diff --git a/.gitignore b/.gitignore
index 83f2aaf1..9a0559ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,31 @@
-cache
-artifacts
-node_modules
-.env
-coverage
+# Compiler and build files
+cache/
+artifacts/
+out/
+compiler_config.json
+
+# Node modules
+node_modules/
+
+# Coverage files
+coverage/
coverage.json
+
+# Environment files
+.env
+.env*
+
+# MacOS file system
.DS_Store
-compiler_config.json
-out
-lib
-.deps
+
+# Development broadcast logs
broadcast/
+!/broadcast
+/broadcast/*/31337/
+/broadcast/**/dry-run/
+broadcast/*
+
+# Documentation
+docs/
+.vscode/
+lcov.info
diff --git a/.gitmodules b/.gitmodules
index 267e9cf6..a7843928 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,31 +1,27 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
- branch = chore/v1.5.6
-
-[submodule "lib/account-abstraction"]
- path = lib/account-abstraction
- url = https://github.com/SoulWallet/account-abstraction
- branch = v0.6.0-with-openzeppelin-v5
-
-[submodule "lib/openzeppelin-contracts"]
- path = lib/openzeppelin-contracts
- url = https://github.com/Openzeppelin/openzeppelin-contracts
- branch = release-v5.0
-
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
branch = release-v5.0
-
-[submodule "lib/solmate"]
- path = lib/solmate
- url = https://github.com/transmissions11/solmate
-
[submodule "lib/nitro-contracts"]
path = lib/nitro-contracts
url = https://github.com/OffchainLabs/nitro-contracts
-
+[submodule "lib/solenv"]
+ path = lib/solenv
+ url = https://github.com/memester-xyz/solenv
+[submodule "lib/SoulWalletCore"]
+ path = lib/SoulWalletCore
+ url = https://github.com/SoulWallet/SoulWalletCore
[submodule "lib/solady"]
path = lib/solady
url = https://github.com/vectorized/solady
+[submodule "lib/openzeppelin-contracts"]
+ path = lib/openzeppelin-contracts
+ url = https://github.com/Openzeppelin/openzeppelin-contracts
+ branch = release-v5.0
+[submodule "lib/account-abstraction"]
+ path = lib/account-abstraction
+ url = https://github.com/SoulWallet/account-abstraction
+ branch = v0.6.0-with-openzeppelin-v5
diff --git a/contracts/SoulWallet.sol b/contracts/SoulWallet.sol
index 1115cf92..2a7789b3 100644
--- a/contracts/SoulWallet.sol
+++ b/contracts/SoulWallet.sol
@@ -1,118 +1,142 @@
-// SPDX-License-Identifier: GPL-3.0
+// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
-import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
-import "@account-abstraction/contracts/core/BaseAccount.sol";
-import "./interfaces/ISoulWallet.sol";
-import "./base/EntryPointManager.sol";
-import "./base/ExecutionManager.sol";
-import "./base/PluginManager.sol";
-import "./base/ModuleManager.sol";
-import "./base/OwnerManager.sol";
-import "./helper/SignatureValidator.sol";
-import "./handler/ERC1271Handler.sol";
-import "./base/FallbackManager.sol";
-import "./base/UpgradeManager.sol";
-import "./base/ValidatorManager.sol";
-
-/// @title SoulWallet
-/// @author SoulWallet team
-/// @notice logic contract of SoulWallet
-/// @dev Draft contract - may be subject to changes
+import {IAccount, UserOperation} from "@soulwallet-core/contracts/interface/IAccount.sol";
+import {EntryPointManager} from "@soulwallet-core/contracts/base/EntryPointManager.sol";
+import {FallbackManager} from "@soulwallet-core/contracts/base/FallbackManager.sol";
+import {StandardExecutor} from "@soulwallet-core/contracts/base/StandardExecutor.sol";
+import {ValidatorManager} from "@soulwallet-core/contracts/base/ValidatorManager.sol";
+import {SignatureDecoder} from "@soulwallet-core/contracts/utils/SignatureDecoder.sol";
+import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";
+import {Errors} from "./libraries/Errors.sol";
+import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
+import "./abstract/ERC1271Handler.sol";
+import {SoulWalletOwnerManager} from "./abstract/SoulWalletOwnerManager.sol";
+import {SoulWalletModuleManager} from "./abstract/SoulWalletModuleManager.sol";
+import {SoulWalletHookManager} from "./abstract/SoulWalletHookManager.sol";
+import {SoulWalletUpgradeManager} from "./abstract/SoulWalletUpgradeManager.sol";
+
contract SoulWallet is
Initializable,
- ISoulWallet,
- BaseAccount,
+ IAccount,
+ IERC1271,
EntryPointManager,
- OwnerManager,
- SignatureValidator,
- PluginManager,
- ModuleManager,
- UpgradeManager,
- ExecutionManager,
+ SoulWalletOwnerManager,
+ SoulWalletModuleManager,
+ SoulWalletHookManager,
+ StandardExecutor,
+ ValidatorManager,
FallbackManager,
- ERC1271Handler,
- ValidatorManager
+ SoulWalletUpgradeManager,
+ ERC1271Handler
{
- /// @notice Creates a new SoulWallet instance
- /// @param _EntryPoint Address of the entry point
- /// @param _validator Address of the validator
- constructor(IEntryPoint _EntryPoint, IValidator _validator)
- EntryPointManager(_EntryPoint)
- ValidatorManager(_validator)
- {
+ address internal immutable _DEFAULT_VALIDATOR;
+
+ constructor(address _entryPoint, address defaultValidator) EntryPointManager(_entryPoint) {
+ _DEFAULT_VALIDATOR = defaultValidator;
_disableInitializers();
}
- /// @notice Initializes the SoulWallet with given parameters
- /// @param owners List of owner addresses (passkey public key hash or eoa address)
- /// @param defalutCallbackHandler Default callback handler address
- /// @param modules List of module data
- /// @param plugins List of plugin data
function initialize(
bytes32[] calldata owners,
address defalutCallbackHandler,
bytes[] calldata modules,
- bytes[] calldata plugins
+ bytes[] calldata hooks
) external initializer {
_addOwners(owners);
_setFallbackHandler(defalutCallbackHandler);
+ _installValidator(_DEFAULT_VALIDATOR, hex"");
for (uint256 i = 0; i < modules.length;) {
_addModule(modules[i]);
unchecked {
i++;
}
}
- for (uint256 i = 0; i < plugins.length;) {
- _addPlugin(plugins[i]);
+ for (uint256 i = 0; i < hooks.length;) {
+ _installHook(hooks[i]);
unchecked {
i++;
}
}
}
- /// @notice Gets the address of the entry point
- /// @return IEntryPoint Address of the entry point
- function entryPoint() public view override(BaseAccount) returns (IEntryPoint) {
- return EntryPointManager._entryPoint();
+ function _uninstallValidator(address validator) internal override {
+ require(validator != _DEFAULT_VALIDATOR, "can't uninstall default validator");
+ super._uninstallValidator(validator);
+ }
+
+ function isValidSignature(bytes32 _hash, bytes calldata signature)
+ public
+ view
+ override
+ returns (bytes4 magicValue)
+ {
+ bytes32 datahash = _encodeRawHash(_hash);
+
+ (address validator, bytes calldata validatorSignature, bytes calldata hookSignature) =
+ SignatureDecoder.signatureSplit(signature);
+ _preIsValidSignatureHook(datahash, hookSignature);
+ return _isValidSignature(datahash, validator, validatorSignature);
}
- /// @notice Validates the user's signature
- /// @param userOp User operation details
- /// @param userOpHash Hash of the user operation
- /// @return validationData Data related to validation process
- function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)
+ function _decodeSignature(bytes calldata signature)
internal
+ pure
+ virtual
+ returns (address validator, bytes calldata validatorSignature, bytes calldata hookSignature)
+ {
+ return SignatureDecoder.signatureSplit(signature);
+ }
+
+ function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)
+ public
+ payable
virtual
override
returns (uint256 validationData)
{
- bool sigValid;
- bytes calldata guardHookInputData;
- (validationData, sigValid, guardHookInputData) = _isValidUserOp(userOpHash, userOp.signature);
-
- /*
- Why using the current "non-gas-optimized" approach instead of using
- `sigValid = sigValid && guardHook(userOp, userOpHash, guardHookInputData);` :
-
- When data is executed on the blockchain, if `sigValid = true`, the gas cost remains consistent.
- However, the benefits of using this approach are quite apparent:
- By using "semi-valid" signatures off-chain to estimate gas fee (sigValid will always be false),
- the estimated fee can include a portion of the execution cost of `guardHook`.
+ _onlyEntryPoint();
+
+ assembly ("memory-safe") {
+ if missingAccountFunds {
+ // ignore failure (its EntryPoint's job to verify, not account.)
+ pop(call(gas(), caller(), missingAccountFunds, 0x00, 0x00, 0x00, 0x00))
+ }
+ }
+ (address validator, bytes calldata validatorSignature, bytes calldata hookSignature) =
+ _decodeSignature(userOp.signature);
+
+ /*
+ Warning!!!
+ This function uses `return` to terminate the execution of the entire contract.
+ If any `Hook` fails, this function will stop the contract's execution and
+ return `SIG_VALIDATION_FAILED`, skipping all the subsequent unexecuted code.
+ */
+ _preUserOpValidationHook(userOp, userOpHash, missingAccountFunds, hookSignature);
+
+ /*
+ When any hook execution fails, this line will not be executed.
*/
- bool guardHookResult = guardHook(userOp, userOpHash, guardHookInputData);
+ return _validateUserOp(userOp, userOpHash, validator, validatorSignature);
+ }
+
+ /**
+ * Only authorized modules can manage hooks and modules.
+ */
+ function pluginManagementAccess() internal view override {
+ _onlyModule();
+ }
- // equivalence code: `(sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48))`
- // validUntil and validAfter is already packed in signatureData.validationData,
- // and aggregator is address(0), so we just need to add sigFailed flag.
- validationData = validationData | ((sigValid && guardHookResult) ? 0 : SIG_VALIDATION_FAILED);
+ /**
+ * Only authorized modules can manage validators
+ */
+ function validatorManagementAccess() internal view override {
+ _onlyModule();
}
- /// @notice Upgrades the contract to a new implementation
- /// @param newImplementation Address of the new implementation
- /// @dev Can only be called from an external module for security reasons
- function upgradeTo(address newImplementation) external onlyModule {
- UpgradeManager._upgradeTo(newImplementation);
+ function upgradeTo(address newImplementation) external override {
+ _onlyModule();
+ _upgradeTo(newImplementation);
}
/// @notice Handles the upgrade from an old implementation
diff --git a/contracts/abstract/DefaultCallbackHandler.sol b/contracts/abstract/DefaultCallbackHandler.sol
new file mode 100644
index 00000000..a7102e2b
--- /dev/null
+++ b/contracts/abstract/DefaultCallbackHandler.sol
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
+import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
+import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
+
+contract DefaultCallbackHandler is IERC721Receiver, IERC1155Receiver {
+ bytes4 private constant _ERC721_RECEIVED =
+ IERC721Receiver.onERC721Received.selector;
+ bytes4 private constant _ERC1155_RECEIVED =
+ IERC1155Receiver.onERC1155Received.selector;
+ bytes4 private constant _ERC1155_BATCH_RECEIVED =
+ IERC1155Receiver.onERC1155BatchReceived.selector;
+
+ bytes4 private constant _INTERFACE_ID_ERC721_RECEIVER =
+ type(IERC721Receiver).interfaceId;
+ bytes4 private constant _INTERFACE_ID_ERC1155_RECEIVER =
+ type(IERC1155Receiver).interfaceId;
+ bytes4 private constant _INTERFACE_ID_ERC165 = type(IERC165).interfaceId;
+
+ function onERC721Received(
+ address,
+ address,
+ uint256,
+ bytes calldata
+ ) external pure override returns (bytes4) {
+ return _ERC721_RECEIVED;
+ }
+
+ function onERC1155Received(
+ address,
+ address,
+ uint256,
+ uint256,
+ bytes calldata
+ ) external pure override returns (bytes4) {
+ return _ERC1155_RECEIVED;
+ }
+
+ function onERC1155BatchReceived(
+ address,
+ address,
+ uint256[] calldata,
+ uint256[] calldata,
+ bytes calldata
+ ) external pure override returns (bytes4) {
+ return _ERC1155_BATCH_RECEIVED;
+ }
+
+ function supportsInterface(
+ bytes4 interfaceId
+ ) external view virtual override returns (bool) {
+ return
+ interfaceId == _INTERFACE_ID_ERC721_RECEIVER ||
+ interfaceId == _INTERFACE_ID_ERC1155_RECEIVER ||
+ interfaceId == _INTERFACE_ID_ERC165;
+ }
+
+ receive() external payable {}
+
+ fallback() external payable {}
+}
diff --git a/contracts/abstract/ERC1271Handler.sol b/contracts/abstract/ERC1271Handler.sol
new file mode 100644
index 00000000..52d834eb
--- /dev/null
+++ b/contracts/abstract/ERC1271Handler.sol
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+import {Authority} from "@soulwallet-core/contracts/base/Authority.sol";
+
+abstract contract ERC1271Handler is Authority {
+ // Magic value indicating a valid signature for ERC-1271 contracts
+ // bytes4(keccak256("isValidSignature(bytes32,bytes)")
+ bytes4 internal constant MAGICVALUE = 0x1626ba7e;
+ // Constants indicating different invalid states
+ bytes4 internal constant INVALID_ID = 0xffffffff;
+
+ bytes32 private constant SOUL_WALLET_MSG_TYPEHASH = keccak256("SoulWalletMessage(bytes32 message)");
+
+ bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH =
+ keccak256("EIP712Domain(uint256 chainId,address verifyingContract)");
+
+ function _encodeRawHash(bytes32 rawHash) internal view returns (bytes32) {
+ bytes32 encode1271MessageHash = keccak256(abi.encode(SOUL_WALLET_MSG_TYPEHASH, rawHash));
+ bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), address(msg.sender)));
+ return keccak256(abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator, encode1271MessageHash));
+ }
+
+ function getChainId() public view returns (uint256) {
+ uint256 id;
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ id := chainid()
+ }
+ return id;
+ }
+}
diff --git a/contracts/abstract/SoulWalletHookManager.sol b/contracts/abstract/SoulWalletHookManager.sol
new file mode 100644
index 00000000..23a7cb9b
--- /dev/null
+++ b/contracts/abstract/SoulWalletHookManager.sol
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {HookManager} from "@soulwallet-core/contracts/base/HookManager.sol";
+import {ISoulWalletHookManager} from "../interfaces/ISoulWalletHookManager.sol";
+
+abstract contract SoulWalletHookManager is ISoulWalletHookManager, HookManager {
+ function _installHook(bytes calldata hookAndDataWithFlag) internal virtual {
+ _installHook(
+ address(bytes20(hookAndDataWithFlag[:20])),
+ hookAndDataWithFlag[20:hookAndDataWithFlag.length - 1],
+ uint8(bytes1((hookAndDataWithFlag[hookAndDataWithFlag.length - 1:hookAndDataWithFlag.length])))
+ );
+ }
+
+ function installHook(bytes calldata hookAndData, uint8 capabilityFlags) external virtual override {
+ pluginManagementAccess();
+ _installHook(address(bytes20(hookAndData[:20])), hookAndData[20:], capabilityFlags);
+ }
+}
diff --git a/contracts/abstract/SoulWalletModuleManager.sol b/contracts/abstract/SoulWalletModuleManager.sol
new file mode 100644
index 00000000..845059fb
--- /dev/null
+++ b/contracts/abstract/SoulWalletModuleManager.sol
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {ModuleManager} from "@soulwallet-core/contracts/base/ModuleManager.sol";
+import {ISoulWalletModuleManager} from "../interfaces/ISoulWalletModuleManager.sol";
+import {ISoulWalletModule} from "../modules/interfaces/ISoulWalletModule.sol";
+import {Errors} from "../libraries/Errors.sol";
+
+abstract contract SoulWalletModuleManager is
+ ISoulWalletModuleManager,
+ ModuleManager
+{
+ function installModule(bytes calldata moduleAndData) external override {
+ _onlyModule();
+ _addModule(moduleAndData);
+ }
+
+ function _addModule(bytes calldata moduleAndData) internal {
+ address moduleAddress = address(bytes20(moduleAndData[:20]));
+ ISoulWalletModule aModule = ISoulWalletModule(moduleAddress);
+ if (!aModule.supportsInterface(type(ISoulWalletModule).interfaceId)) {
+ revert Errors.MODULE_NOT_SUPPORT_INTERFACE();
+ }
+ bytes4[] memory requiredFunctions = aModule.requiredFunctions();
+ if (requiredFunctions.length == 0) {
+ revert Errors.MODULE_SELECTORS_EMPTY();
+ }
+ _installModule(
+ address(bytes20(moduleAndData[:20])),
+ moduleAndData[20:],
+ requiredFunctions
+ );
+
+ }
+}
diff --git a/contracts/abstract/SoulWalletOwnerManager.sol b/contracts/abstract/SoulWalletOwnerManager.sol
new file mode 100644
index 00000000..8f998240
--- /dev/null
+++ b/contracts/abstract/SoulWalletOwnerManager.sol
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {OwnerManager} from "@soulwallet-core/contracts/base/OwnerManager.sol";
+import {ISoulWalletOwnerManager} from "../interfaces/ISoulWalletOwnerManager.sol";
+
+abstract contract SoulWalletOwnerManager is
+ ISoulWalletOwnerManager,
+ OwnerManager
+{
+ function _addOwners(bytes32[] calldata owners) internal {
+ for (uint256 i = 0; i < owners.length; ) {
+ _addOwner(owners[i]);
+ unchecked {
+ i++;
+ }
+ }
+ }
+
+ function addOwners(bytes32[] calldata owners) external override {
+ _onlySelfOrModule();
+ _addOwners(owners);
+ }
+
+ function resetOwners(bytes32[] calldata newOwners) external override {
+ _onlySelfOrModule();
+ _clearOwner();
+ _addOwners(newOwners);
+ }
+}
diff --git a/contracts/base/UpgradeManager.sol b/contracts/abstract/SoulWalletUpgradeManager.sol
similarity index 94%
rename from contracts/base/UpgradeManager.sol
rename to contracts/abstract/SoulWalletUpgradeManager.sol
index 11817e8c..10710814 100644
--- a/contracts/base/UpgradeManager.sol
+++ b/contracts/abstract/SoulWalletUpgradeManager.sol
@@ -4,11 +4,11 @@ pragma solidity ^0.8.20;
import "../interfaces/IUpgradable.sol";
import "../libraries/Errors.sol";
/**
- * @title UpgradeManager
+ * @title SoulWalletUpgradeManager
* @dev This contract allows for the logic of a proxy to be upgraded
*/
-abstract contract UpgradeManager is IUpgradable {
+abstract contract SoulWalletUpgradeManager is IUpgradable {
/**
* @dev Storage slot with the address of the current implementation
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1
diff --git a/contracts/abstract/SoulWalletValidatorManager.sol b/contracts/abstract/SoulWalletValidatorManager.sol
new file mode 100644
index 00000000..18424e9e
--- /dev/null
+++ b/contracts/abstract/SoulWalletValidatorManager.sol
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {ValidatorManager} from "@soulwallet-core/contracts/base/ValidatorManager.sol";
+import {ISoulWalletValidatorManager} from "../interfaces/ISoulWalletValidatorManager.sol";
+
+abstract contract SoulWalletValidatorManager is ISoulWalletValidatorManager, ValidatorManager {
+ function installValidator(bytes calldata validatorAndData) external virtual override {
+ validatorManagementAccess();
+ _installValidator(address(bytes20(validatorAndData[:20])), validatorAndData[20:]);
+ }
+}
diff --git a/contracts/authority/Authority.sol b/contracts/authority/Authority.sol
deleted file mode 100644
index ddf70408..00000000
--- a/contracts/authority/Authority.sol
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "./EntryPointAuth.sol";
-import "./OwnerAuth.sol";
-import "../interfaces/IExecutionManager.sol";
-import "../interfaces/IModuleManager.sol";
-import "../libraries/Errors.sol";
-import "./ModuleAuth.sol";
-
-/**
- * @title Authority
- * @notice An abstract contract that provides authorization mechanisms
- * @dev Inherits various authorization patterns including EntryPoint, Owner, and Module-based authentication
- */
-abstract contract Authority is EntryPointAuth, OwnerAuth, ModuleAuth {
- /**
- * @notice Ensures the calling contract is either the Authority contract itself or an authorized module
- * @dev Uses the inherited `_isAuthorizedModule()` from ModuleAuth for module-based authentication
- */
- modifier onlySelfOrModule() {
- if (msg.sender != address(this) && !_isAuthorizedModule()) {
- revert Errors.CALLER_MUST_BE_SELF_OR_MODULE();
- }
- _;
- }
-}
diff --git a/contracts/authority/EntryPointAuth.sol b/contracts/authority/EntryPointAuth.sol
deleted file mode 100644
index d35b2b9b..00000000
--- a/contracts/authority/EntryPointAuth.sol
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "@account-abstraction/contracts/interfaces/IEntryPoint.sol";
-import "../libraries/Errors.sol";
-
-/**
- * @title EntryPointAuth
- * @notice Abstract contract to provide EntryPoint based authentication
- * @dev Requires the inheriting contracts to implement the `_entryPoint` method
- */
-abstract contract EntryPointAuth {
- /**
- * @notice Expected to return the associated entry point for the contract
- * @dev Must be implemented by inheriting contracts
- * @return The EntryPoint associated with the contract
- */
- function _entryPoint() internal view virtual returns (IEntryPoint);
-
- /*
- Data Flow:
-
- A: from entryPoint
- # msg.sender: entryPoint
- # address(this): soulwalletProxy
- ┌────────────┐ ┌────────┐
- │ entryPoint │ ──► │ here │
- └────────────┘ └────────┘
- * @notice Modifier to ensure the caller is the expected entry point
- * @dev If not called from the expected entry point, it will revert
- */
- modifier onlyEntryPoint() {
- if (msg.sender != address(_entryPoint())) {
- revert Errors.CALLER_MUST_BE_ENTRYPOINT();
- }
- _;
- }
-}
diff --git a/contracts/authority/ModuleAuth.sol b/contracts/authority/ModuleAuth.sol
deleted file mode 100644
index c4509fcb..00000000
--- a/contracts/authority/ModuleAuth.sol
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../libraries/Errors.sol";
-
-/**
- * @title ModuleAuth
- * @notice Abstract contract to provide Module-based authentication
- * @dev Requires the inheriting contracts to implement the `_isAuthorizedModule` method
- */
-abstract contract ModuleAuth {
- /**
- * @notice Expected to return whether the current context is authorized as a module
- * @dev Must be implemented by inheriting contracts
- * @return True if the context is an authorized module, otherwise false
- */
- function _isAuthorizedModule() internal view virtual returns (bool);
-
- /**
- * @notice Modifier to ensure the caller is an authorized module
- * @dev If not called from an authorized module, it will revert
- */
- modifier onlyModule() {
- if (!_isAuthorizedModule()) {
- revert Errors.CALLER_MUST_BE_MODULE();
- }
- _;
- }
-}
diff --git a/contracts/authority/OwnerAuth.sol b/contracts/authority/OwnerAuth.sol
deleted file mode 100644
index b762691b..00000000
--- a/contracts/authority/OwnerAuth.sol
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-/**
- * @title OwnerAuth
- * @notice Abstract contract to provide Owner-based authentication
- * @dev Requires the inheriting contracts to implement the `_isOwner` method
- */
-abstract contract OwnerAuth {
- /**
- * @notice Expected to return whether the provided owner identifier matches the owner context
- * @dev Must be implemented by inheriting contracts
- * @param owner The owner identifier to be checked
- * @return True if the provided owner identifier matches the current owner context, otherwise false
- */
- function _isOwner(bytes32 owner) internal view virtual returns (bool);
-}
diff --git a/contracts/base/EntryPointManager.sol b/contracts/base/EntryPointManager.sol
deleted file mode 100644
index 24047e42..00000000
--- a/contracts/base/EntryPointManager.sol
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../authority/EntryPointAuth.sol";
-
-abstract contract EntryPointManager is EntryPointAuth {
- IEntryPoint private immutable _ENTRY_POINT;
-
- constructor(IEntryPoint entryPoint) {
- _ENTRY_POINT = entryPoint;
- }
-
- function _entryPoint() internal view override returns (IEntryPoint) {
- return _ENTRY_POINT;
- }
-}
diff --git a/contracts/base/ExecutionManager.sol b/contracts/base/ExecutionManager.sol
deleted file mode 100644
index 2e2180f8..00000000
--- a/contracts/base/ExecutionManager.sol
+++ /dev/null
@@ -1,73 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../authority/Authority.sol";
-import "./PluginManager.sol";
-import "../interfaces/IExecutionManager.sol";
-
-/**
- * @title ExecutionManager
- * @notice Manages the execution of transactions and batches of transactions
- * @dev Inherits functionality from IExecutionManager, Authority, and PluginManager
- */
-abstract contract ExecutionManager is IExecutionManager, Authority, PluginManager {
- /**
- * @notice Execute a transaction
- * @param dest The destination address for the transaction
- * @param value The amount of ether to be sent with the transaction
- * @param func The calldata for the transaction
- */
- function execute(address dest, uint256 value, bytes calldata func) external override onlyEntryPoint {
- _call(dest, value, func);
- }
-
- /**
- * @notice Execute a sequence of transactions without any associated ether
- * @param dest List of destination addresses for each transaction
- * @param func List of calldata for each transaction
- */
- function executeBatch(address[] calldata dest, bytes[] calldata func) external override onlyEntryPoint {
- for (uint256 i = 0; i < dest.length;) {
- _call(dest[i], 0, func[i]);
- unchecked {
- i++;
- }
- }
- }
-
- /**
- * @notice Execute a sequence of transactions, each potentially having associated ether
- * @param dest List of destination addresses for each transaction
- * @param value List of ether amounts for each transaction
- * @param func List of calldata for each transaction
- */
- function executeBatch(address[] calldata dest, uint256[] calldata value, bytes[] calldata func)
- external
- override
- onlyEntryPoint
- {
- for (uint256 i = 0; i < dest.length;) {
- _call(dest[i], value[i], func[i]);
- unchecked {
- i++;
- }
- }
- }
-
- /**
- * @dev Internal function to handle the call logic
- * @param target Address of the target contract
- * @param value Ether to be sent with the transaction
- * @param data Calldata for the transaction
- */
- function _call(address target, uint256 value, bytes memory data) private executeHook(target, value, data) {
- assembly ("memory-safe") {
- let result := call(gas(), target, value, add(data, 0x20), mload(data), 0, 0)
- if iszero(result) {
- let ptr := mload(0x40)
- returndatacopy(ptr, 0, returndatasize())
- revert(ptr, returndatasize())
- }
- }
- }
-}
diff --git a/contracts/base/FallbackManager.sol b/contracts/base/FallbackManager.sol
deleted file mode 100644
index 55f211ad..00000000
--- a/contracts/base/FallbackManager.sol
+++ /dev/null
@@ -1,51 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../interfaces/IFallbackManager.sol";
-import "../authority/Authority.sol";
-import "../libraries/AccountStorage.sol";
-
-/**
- * @title FallbackManager
- * @notice Manages the fallback behavior for the contract
- * @dev Inherits functionalities from Authority and IFallbackManager
- */
-abstract contract FallbackManager is Authority, IFallbackManager {
- /// @notice A payable function that allows the contract to receive ether
- receive() external payable {}
-
- /**
- * @dev Sets the address of the fallback handler contract
- * @param fallbackContract The address of the new fallback handler contract
- */
- function _setFallbackHandler(address fallbackContract) internal {
- AccountStorage.layout().defaultFallbackContract = fallbackContract;
- }
-
- /**
- * @notice Fallback function that forwards all requests to the fallback handler contract
- * @dev The request is forwarded using a STATICCALL
- * It ensures that the state of the contract doesn't change even if the fallback function has state-changing operations
- */
- fallback() external payable {
- address fallbackContract = AccountStorage.layout().defaultFallbackContract;
- assembly {
- /* not memory-safe */
- calldatacopy(0, 0, calldatasize())
- let result := staticcall(gas(), fallbackContract, 0, calldatasize(), 0, 0)
- returndatacopy(0, 0, returndatasize())
- switch result
- case 0 { revert(0, returndatasize()) }
- default { return(0, returndatasize()) }
- }
- }
-
- /**
- * @notice Sets the address of the fallback handler and emits the FallbackChanged event
- * @param fallbackContract The address of the new fallback handler
- */
- function setFallbackHandler(address fallbackContract) external override onlySelfOrModule {
- _setFallbackHandler(fallbackContract);
- emit FallbackChanged(fallbackContract);
- }
-}
diff --git a/contracts/base/ModuleManager.sol b/contracts/base/ModuleManager.sol
deleted file mode 100644
index 4cd73e7d..00000000
--- a/contracts/base/ModuleManager.sol
+++ /dev/null
@@ -1,162 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../libraries/AccountStorage.sol";
-import "../authority/Authority.sol";
-import "../interfaces/IModuleManager.sol";
-import "../interfaces/IPluginManager.sol";
-import "../libraries/AddressLinkedList.sol";
-import "../libraries/SelectorLinkedList.sol";
-
-/**
- * @title ModuleManager
- * @notice Manages the modules that are added to, or removed from, the wallet
- * @dev Inherits functionalities from IModuleManager and Authority
- */
-abstract contract ModuleManager is IModuleManager, Authority {
- using AddressLinkedList for mapping(address => address);
- using SelectorLinkedList for mapping(bytes4 => bytes4);
-
- /// @dev Returns the mapping of modules
- function _modulesMapping() private view returns (mapping(address => address) storage modules) {
- modules = AccountStorage.layout().modules;
- }
-
- /// @dev Returns the mapping of module selectors
- function _moduleSelectorsMapping()
- private
- view
- returns (mapping(address => mapping(bytes4 => bytes4)) storage moduleSelectors)
- {
- moduleSelectors = AccountStorage.layout().moduleSelectors;
- }
- /// @dev Checks if the sender is an authorized module
-
- function _isAuthorizedModule() internal view override returns (bool) {
- address module = msg.sender;
- if (!_modulesMapping().isExist(module)) {
- return false;
- }
- mapping(address => mapping(bytes4 => bytes4)) storage moduleSelectors = _moduleSelectorsMapping();
- return moduleSelectors[module].isExist(msg.sig);
- }
- /**
- * @notice Check if a module is authorized
- * @param module Address of the module
- * @return A boolean indicating the authorization status
- */
-
- function isAuthorizedModule(address module) external view override returns (bool) {
- return _modulesMapping().isExist(module);
- }
-
- /**
- * @notice Add a new module
- * @param moduleAndData Byte data containing the module address and initialization data
- */
- function addModule(bytes calldata moduleAndData) external override onlyModule {
- _addModule(moduleAndData);
- }
- /// @dev Internal function to add a module
-
- function _addModule(bytes calldata moduleAndData) internal {
- if (moduleAndData.length < 20) {
- revert Errors.MODULE_ADDRESS_EMPTY();
- }
- address moduleAddress = address(bytes20(moduleAndData[:20]));
- bytes calldata initData = moduleAndData[20:];
- IModule aModule = IModule(moduleAddress);
- if (!aModule.supportsInterface(type(IModule).interfaceId)) {
- revert Errors.MODULE_NOT_SUPPORT_INTERFACE();
- }
- bytes4[] memory requiredFunctions = aModule.requiredFunctions();
- if (requiredFunctions.length == 0) {
- revert Errors.MODULE_SELECTORS_EMPTY();
- }
- mapping(address => address) storage modules = _modulesMapping();
- modules.add(moduleAddress);
- mapping(address => mapping(bytes4 => bytes4)) storage moduleSelectors = _moduleSelectorsMapping();
- moduleSelectors[moduleAddress].add(requiredFunctions);
- aModule.walletInit(initData);
- emit ModuleAdded(moduleAddress);
- }
- /**
- * @notice Remove a module
- * @param module Address of the module to be removed
- */
-
- function removeModule(address module) external override onlyModule {
- mapping(address => address) storage modules = _modulesMapping();
- modules.remove(module);
-
- mapping(address => mapping(bytes4 => bytes4)) storage moduleSelectors = _moduleSelectorsMapping();
- moduleSelectors[module].clear();
-
- try IModule(module).walletDeInit() {
- emit ModuleRemoved(module);
- } catch {
- emit ModuleRemovedWithError(module);
- }
- }
- /**
- * @notice List all the modules and their associated selectors
- * @return modules An array of module addresses
- * @return selectors A two-dimensional array of selectors
- */
-
- function listModule() external view override returns (address[] memory modules, bytes4[][] memory selectors) {
- mapping(address => address) storage _modules = _modulesMapping();
- uint256 moduleSize = _modulesMapping().size();
- modules = new address[](moduleSize);
- mapping(address => mapping(bytes4 => bytes4)) storage moduleSelectors = _moduleSelectorsMapping();
- selectors = new bytes4[][](moduleSize);
-
- uint256 i = 0;
- address addr = _modules[AddressLinkedList.SENTINEL_ADDRESS];
- while (uint160(addr) > AddressLinkedList.SENTINEL_UINT) {
- {
- modules[i] = addr;
- mapping(bytes4 => bytes4) storage moduleSelector = moduleSelectors[addr];
-
- {
- uint256 selectorSize = moduleSelector.size();
- bytes4[] memory _selectors = new bytes4[](selectorSize);
- uint256 j = 0;
- bytes4 selector = moduleSelector[SelectorLinkedList.SENTINEL_SELECTOR];
- while (uint32(selector) > SelectorLinkedList.SENTINEL_UINT) {
- _selectors[j] = selector;
-
- selector = moduleSelector[selector];
- unchecked {
- j++;
- }
- }
- selectors[i] = _selectors;
- }
- }
-
- addr = _modules[addr];
- unchecked {
- i++;
- }
- }
- }
- /**
- * @notice Execute a transaction from a module
- * @param to Address to which the transaction should be executed
- * @param value Amount of ETH (in wei) to be sent
- * @param data Transaction data
- */
-
- function executeFromModule(address to, uint256 value, bytes memory data) external override onlyModule {
- if (to == address(this)) revert Errors.MODULE_EXECUTE_FROM_MODULE_RECURSIVE();
- assembly {
- /* not memory-safe */
- let result := call(gas(), to, value, add(data, 0x20), mload(data), 0, 0)
- if iszero(result) {
- returndatacopy(0, 0, returndatasize())
- revert(0, returndatasize())
- }
- }
- }
-}
diff --git a/contracts/base/OwnerManager.sol b/contracts/base/OwnerManager.sol
deleted file mode 100644
index baced5db..00000000
--- a/contracts/base/OwnerManager.sol
+++ /dev/null
@@ -1,129 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../libraries/AccountStorage.sol";
-import "../authority/Authority.sol";
-import "../interfaces/IOwnerManager.sol";
-import "../libraries/Bytes32LinkedList.sol";
-import "../libraries/Errors.sol";
-
-/**
- * @title OwnerManager
- * @notice Manages the owners of the wallet, allowing for addition, removal, and listing of owners
- * The owner should be of bytes32 type. Currently, an owner is an eoa key or the public key of the passkey
- * @dev Inherits functionalities from IOwnerManager and Authority
- */
-abstract contract OwnerManager is IOwnerManager, Authority {
- using Bytes32LinkedList for mapping(bytes32 => bytes32);
-
- /**
- * @notice Helper function to get the owner mapping from account storage
- * @return owners Mapping of current owners
- */
- function _ownerMapping() private view returns (mapping(bytes32 => bytes32) storage owners) {
- owners = AccountStorage.layout().owners;
- }
- /**
- * @notice Checks if the provided owner is a current owner
- * @param owner Address in bytes32 format to check
- * @return true if provided owner is a current owner, false otherwise
- */
-
- function _isOwner(bytes32 owner) internal view override returns (bool) {
- return _ownerMapping().isExist(owner);
- }
- /**
- * @notice External function to check if the provided owner is a current owner
- * @param owner Address in bytes32 format to check
- * @return true if provided owner is a current owner, false otherwise
- */
-
- function isOwner(bytes32 owner) external view override returns (bool) {
- return _isOwner(owner);
- }
- /**
- * @notice Clears all owners
- */
-
- function _clearOwner() private {
- _ownerMapping().clear();
- emit OwnerCleared();
- }
- /**
- * @notice Resets the owner to a new owner
- * @param newOwner The new owner address in bytes32 format
- */
-
- function resetOwner(bytes32 newOwner) external override onlySelfOrModule {
- _clearOwner();
- _addOwner(newOwner);
- }
- /**
- * @notice Resets the owners to a new set of owners
- * @param newOwners An array of new owner addresses in bytes32 format
- */
-
- function resetOwners(bytes32[] calldata newOwners) external override onlySelfOrModule {
- _clearOwner();
- _addOwners(newOwners);
- }
- /**
- * @notice Adds multiple owners
- * @param owners An array of owner addresses in bytes32 format to add
- */
-
- function _addOwners(bytes32[] calldata owners) internal {
- for (uint256 i = 0; i < owners.length;) {
- _addOwner(owners[i]);
- unchecked {
- i++;
- }
- }
- }
- /**
- * @notice Adds a single owner
- * @param owner The owner address in bytes32 format to add
- */
-
- function addOwner(bytes32 owner) external override onlySelfOrModule {
- _addOwner(owner);
- }
- /**
- * @notice Adds multiple owners
- * @param owners An array of owner addresses in bytes32 format to add
- */
-
- function addOwners(bytes32[] calldata owners) external override onlySelfOrModule {
- _addOwners(owners);
- }
- /**
- * @notice Adds a single owner
- * @param owner The owner address in bytes32 format to add
- */
-
- function _addOwner(bytes32 owner) internal {
- _ownerMapping().add(owner);
- emit OwnerAdded(owner);
- }
- /**
- * @notice Removes a single owner
- * @param owner The owner address in bytes32 format to remove
- */
-
- function removeOwner(bytes32 owner) external override onlySelfOrModule {
- _ownerMapping().remove(owner);
- if (_ownerMapping().isEmpty()) {
- revert Errors.NO_OWNER();
- }
- emit OwnerRemoved(owner);
- }
- /**
- * @notice Lists all current owners
- * @return owners An array of current owner addresses in bytes32 format
- */
-
- function listOwner() external view override returns (bytes32[] memory owners) {
- uint256 size = _ownerMapping().size();
- owners = _ownerMapping().list(Bytes32LinkedList.SENTINEL_BYTES32, size);
- }
-}
diff --git a/contracts/base/PluginManager.sol b/contracts/base/PluginManager.sol
deleted file mode 100644
index fed9b293..00000000
--- a/contracts/base/PluginManager.sol
+++ /dev/null
@@ -1,283 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../interfaces/IPluginManager.sol";
-import "../interfaces/IPlugin.sol";
-import "../libraries/AccountStorage.sol";
-import "../authority/Authority.sol";
-import "../libraries/AddressLinkedList.sol";
-import "../interfaces/IPluggable.sol";
-import "../interfaces/IPluginStorage.sol";
-
-/**
- * @title PluginManager
- * @dev This contract manages plugins and provides associated utility functions
- */
-abstract contract PluginManager is IPluginManager, Authority, IPluginStorage {
- uint8 private constant _GUARD_HOOK = 1 << 0;
- uint8 private constant _PRE_HOOK = 1 << 1;
- uint8 private constant _POST_HOOK = 1 << 2;
-
- using AddressLinkedList for mapping(address => address);
- /**
- * @dev Adds a new plugin
- * @param pluginAndData The plugin address and associated data
- */
-
- function addPlugin(bytes calldata pluginAndData) external override onlyModule {
- _addPlugin(pluginAndData);
- }
-
- function _addPlugin(bytes calldata pluginAndData) internal {
- if (pluginAndData.length < 20) {
- revert Errors.PLUGIN_ADDRESS_EMPTY();
- }
- address pluginAddress = address(bytes20(pluginAndData[:20]));
- bytes calldata initData = pluginAndData[20:];
- IPlugin aPlugin = IPlugin(pluginAddress);
- if (!aPlugin.supportsInterface(type(IPlugin).interfaceId)) {
- revert Errors.PLUGIN_NOT_SUPPORT_INTERFACE();
- }
- AccountStorage.Layout storage l = AccountStorage.layout();
- uint8 hookType = aPlugin.supportsHook();
-
- if (hookType & 7 /* _GUARD_HOOK | _PRE_HOOK | _POST_HOOK */ == 0) {
- revert Errors.PLUGIN_HOOK_TYPE_ERROR();
- }
-
- if (hookType & _GUARD_HOOK == _GUARD_HOOK) {
- l.guardHookPlugins.add(pluginAddress);
- }
- if (hookType & _PRE_HOOK == _PRE_HOOK) {
- l.preHookPlugins.add(pluginAddress);
- }
- if (hookType & _POST_HOOK == _POST_HOOK) {
- l.postHookPlugins.add(pluginAddress);
- }
- l.plugins.add(pluginAddress);
- if (!call(pluginAddress, abi.encodeWithSelector(IPluggable.walletInit.selector, initData))) {
- revert Errors.PLUGIN_INIT_FAILED();
- }
- emit PluginAdded(pluginAddress);
- }
- /**
- * @dev Removes a plugin
- * @param plugin Address of the plugin to be removed
- */
-
- function removePlugin(address plugin) external override onlyModule {
- AccountStorage.Layout storage l = AccountStorage.layout();
- l.plugins.remove(plugin);
- bool success = call(plugin, abi.encodeWithSelector(IPluggable.walletDeInit.selector));
- if (success) {
- emit PluginRemoved(plugin);
- } else {
- emit PluginRemovedWithError(plugin);
- }
- l.guardHookPlugins.tryRemove(plugin);
- l.preHookPlugins.tryRemove(plugin);
- l.postHookPlugins.tryRemove(plugin);
- }
- /**
- * @dev Checks if a plugin is authorized
- * @param plugin Address of the plugin
- * @return Returns true if the plugin is authorized, false otherwise
- */
-
- function isAuthorizedPlugin(address plugin) external view override returns (bool) {
- return AccountStorage.layout().plugins.isExist(plugin);
- }
- /**
- * @dev Lists plugins based on the hook type
- * @param hookType Type of the hook
- * @return plugins An array of plugin addresses
- */
-
- function listPlugin(uint8 hookType) external view override returns (address[] memory plugins) {
- if (hookType == 0) {
- mapping(address => address) storage _plugins = AccountStorage.layout().plugins;
- plugins = _plugins.list(AddressLinkedList.SENTINEL_ADDRESS, _plugins.size());
- } else if (hookType == _GUARD_HOOK) {
- mapping(address => address) storage _plugins = AccountStorage.layout().guardHookPlugins;
- plugins = _plugins.list(AddressLinkedList.SENTINEL_ADDRESS, _plugins.size());
- } else if (hookType == _PRE_HOOK) {
- mapping(address => address) storage _plugins = AccountStorage.layout().preHookPlugins;
- plugins = _plugins.list(AddressLinkedList.SENTINEL_ADDRESS, _plugins.size());
- } else if (hookType == _POST_HOOK) {
- mapping(address => address) storage _plugins = AccountStorage.layout().postHookPlugins;
- plugins = _plugins.list(AddressLinkedList.SENTINEL_ADDRESS, _plugins.size());
- } else {
- revert Errors.PLUGIN_HOOK_TYPE_ERROR();
- }
- }
-
- function _nextGuardHookData(bytes calldata guardHookData, uint256 cursor)
- private
- pure
- returns (address _guardAddr, uint256 _cursorFrom, uint256 _cursorEnd)
- {
- uint256 dataLen = guardHookData.length;
- uint48 guardSigLen;
- if (dataLen > cursor) {
- unchecked {
- _cursorEnd = cursor + 20;
- }
- bytes calldata _guardAddrBytes = guardHookData[cursor:_cursorEnd];
- assembly ("memory-safe") {
- _guardAddr := shr(0x60, calldataload(_guardAddrBytes.offset))
- }
- require(_guardAddr != address(0));
- unchecked {
- cursor = _cursorEnd;
- _cursorEnd = cursor + 6;
- }
- bytes calldata _guardSigLen = guardHookData[cursor:_cursorEnd];
- assembly ("memory-safe") {
- guardSigLen := shr(0xd0, calldataload(_guardSigLen.offset))
- }
- unchecked {
- cursor = _cursorEnd;
- _cursorEnd = cursor + guardSigLen;
- }
- _cursorFrom = cursor;
- }
- }
- /**
- * @dev Hooks a user operation with associated data
- * @param userOp User operation details
- * @param userOpHash Hash of the user operation
- * @param guardHookData Data for the guard hook
- * @return Returns true if the hook was successful, false otherwise
- */
-
- function guardHook(UserOperation calldata userOp, bytes32 userOpHash, bytes calldata guardHookData)
- internal
- returns (bool)
- {
- AccountStorage.Layout storage l = AccountStorage.layout();
- mapping(address => address) storage _plugins = l.guardHookPlugins;
-
- /*
- +--------------------------------------------------------------------------------+
- | multi-guardHookInputData |
- +--------------------------------------------------------------------------------+
- | guardHookInputData | guardHookInputData | ... | guardHookInputData |
- +-----------------------+--------------------------------------------------------+
- | dynamic data | dynamic data | ... | dynamic data |
- +--------------------------------------------------------------------------------+
-
- +----------------------------------------------------------------------+
- | guardHookInputData |
- +----------------------------------------------------------------------+
- | guardHook address | input data length | input data |
- +----------------------+-----------------------------------------------+
- | 20bytes | 6bytes(uint48) | bytes |
- +----------------------------------------------------------------------+
- */
- address _guardAddr;
- uint256 _cursorFrom;
- uint256 _cursorEnd;
- (_guardAddr, _cursorFrom, _cursorEnd) = _nextGuardHookData(guardHookData, _cursorEnd);
-
- address addr = _plugins[AddressLinkedList.SENTINEL_ADDRESS];
- while (uint160(addr) > AddressLinkedList.SENTINEL_UINT) {
- {
- bytes calldata currentGuardHookData;
- address plugin = addr;
- if (plugin == _guardAddr) {
- currentGuardHookData = guardHookData[_cursorFrom:_cursorEnd];
- // next
- _guardAddr = address(0);
- if (_cursorEnd > 0) {
- (_guardAddr, _cursorFrom, _cursorEnd) = _nextGuardHookData(guardHookData, _cursorEnd);
- }
- } else {
- currentGuardHookData = guardHookData[0:0];
- }
- bool success =
- call(plugin, abi.encodeCall(IPlugin.guardHook, (userOp, userOpHash, currentGuardHookData)));
- if (!success) {
- return false;
- }
- }
- addr = _plugins[addr];
- }
- if (_guardAddr != address(0)) {
- revert Errors.INVALID_GUARD_HOOK_DATA();
- }
- return true;
- }
- /**
- * @dev Executes hooks around a transaction
- * @param target Address of the transaction target
- * @param value Amount of ether to send with the transaction
- * @param data Data of the transaction
- */
-
- modifier executeHook(address target, uint256 value, bytes memory data) {
- AccountStorage.Layout storage l = AccountStorage.layout();
- {
- mapping(address => address) storage _preHookPlugins = l.preHookPlugins;
- address addr = _preHookPlugins[AddressLinkedList.SENTINEL_ADDRESS];
- while (uint160(addr) > AddressLinkedList.SENTINEL_UINT) {
- {
- address plugin = addr;
- if (!call(plugin, abi.encodeCall(IPlugin.preHook, (target, value, data)))) {
- revert Errors.PLUGIN_PRE_HOOK_FAILED();
- }
- }
- addr = _preHookPlugins[addr];
- }
- }
- _;
- {
- mapping(address => address) storage _postHookPlugins = l.postHookPlugins;
-
- address addr = _postHookPlugins[AddressLinkedList.SENTINEL_ADDRESS];
- while (uint160(addr) > AddressLinkedList.SENTINEL_UINT) {
- {
- address plugin = addr;
- if (!call(plugin, abi.encodeCall(IPlugin.postHook, (target, value, data)))) {
- revert Errors.PLUGIN_POST_HOOK_FAILED();
- }
- }
- addr = _postHookPlugins[addr];
- }
- }
- }
-
- function call(address target, bytes memory data) private returns (bool success) {
- assembly ("memory-safe") {
- success := call(gas(), target, 0, add(data, 0x20), mload(data), 0, 0)
- }
- }
- /**
- * @dev Ensures that the function is only called by an authorized plugin
- */
-
- modifier onlyPlugin() {
- if (AccountStorage.layout().plugins[msg.sender] == address(0)) {
- revert Errors.PLUGIN_NOT_REGISTERED();
- }
- _;
- }
- /**
- * @dev Stores data for a plugin
- * @param key Key to store the data against
- * @param value Data to be stored
- */
-
- function pluginDataStore(bytes32 key, bytes calldata value) external override onlyPlugin {
- AccountStorage.layout().pluginDataBytes[msg.sender][key] = value;
- }
- /**
- * @dev Loads data of a plugin
- * @param plugin Address of the plugin
- * @param key Key for which data needs to be loaded
- * @return Returns the loaded data
- */
-
- function pluginDataLoad(address plugin, bytes32 key) external view override returns (bytes memory) {
- return AccountStorage.layout().pluginDataBytes[plugin][key];
- }
-}
diff --git a/contracts/base/Validator.sol b/contracts/base/Validator.sol
deleted file mode 100644
index 191ff4c0..00000000
--- a/contracts/base/Validator.sol
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../interfaces/IValidator.sol";
-/**
- * @title Validator
- * @dev This abstract contract provides a method to retrieve an IValidator interface
- */
-
-abstract contract Validator {
- /**
- * @dev Gets the IValidator interface
- * @return An instance of the IValidator interface
- */
- function validator() public view virtual returns (IValidator);
-}
diff --git a/contracts/base/ValidatorManager.sol b/contracts/base/ValidatorManager.sol
deleted file mode 100644
index 61865d02..00000000
--- a/contracts/base/ValidatorManager.sol
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../interfaces/IValidator.sol";
-import "./Validator.sol";
-
-/**
- * @title ValidatorManager
- * @dev This abstract contract extends the Validator contract and manages a single instance of IValidator
- */
-abstract contract ValidatorManager is Validator {
- /// @dev The IValidator interface instance
- IValidator private immutable _VALIDATOR;
- /**
- * @dev Constructs the ValidatorManager contracs
- * @param aValidator The IValidator interface instance
- */
-
- constructor(IValidator aValidator) {
- _VALIDATOR = aValidator;
- }
- /**
- * @dev Gets the IValidator interface instance
- * @return The IValidator interface instance
- */
-
- function validator() public view override returns (IValidator) {
- return _VALIDATOR;
- }
-}
diff --git a/contracts/dev/Base64UrlTest.sol b/contracts/dev/Base64UrlTest.sol
deleted file mode 100644
index 0d759c3e..00000000
--- a/contracts/dev/Base64UrlTest.sol
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.20;
-
-import {Base64Url} from "../libraries/Base64Url.sol";
-import {Base64} from "@openzeppelin/contracts/utils/Base64.sol";
-
-contract Base64UrlTest {
- function encodeBase64UrlTest() external pure returns (bool) {
- bytes32 challenge = 0x83714056da6e6910b51595330c2c2cdfbf718f2deff5bdd84b95df7a7f36f6dd;
- string memory encoded = Base64Url.encode(bytes.concat(challenge));
- require(
- keccak256(bytes(encoded)) == keccak256("g3FAVtpuaRC1FZUzDCws379xjy3v9b3YS5Xfen829t0"),
- "Base64Url encode failed"
- );
- return true;
- }
-
- function encodeBase64UrlTest(string memory data) external pure returns (string memory encoded) {
- bytes memory dataBytes = bytes(data);
- encoded = Base64Url.encode(dataBytes);
- }
-
- function encodeBase64Test(string memory data) external pure returns (string memory encoded) {
- bytes memory dataBytes = bytes(data);
- encoded = Base64.encode(dataBytes);
- }
-}
diff --git a/contracts/dev/CallHelperTarget.sol b/contracts/dev/CallHelperTarget.sol
deleted file mode 100644
index 497123e5..00000000
--- a/contracts/dev/CallHelperTarget.sol
+++ /dev/null
@@ -1,81 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.20;
-
-contract CallHelperTarget {
- address private immutable DEPLOY_ADDRESS;
- bytes32 private constant VALUE_SLOT = keccak256("CallHelperTarget");
-
- constructor() {
- DEPLOY_ADDRESS = address(this);
- }
-
- function read() private view returns (uint256 v) {
- bytes32 slot = VALUE_SLOT;
- assembly {
- v := sload(slot)
- }
- }
-
- function save(uint256 v) private {
- bytes32 slot = VALUE_SLOT;
- assembly {
- sstore(slot, v)
- }
- }
-
- modifier onlyCall() {
- require(address(this) == DEPLOY_ADDRESS);
- _;
- }
-
- modifier onlyDelegateCall() {
- require(address(this) != DEPLOY_ADDRESS);
- _;
- }
-
- function _call1() external onlyCall {
- save(0);
- save(0x11111);
- }
-
- function _call2() external onlyCall returns (uint256) {
- save(0);
- save(0x11111);
- return read();
- }
-
- function _call3(uint256 i) external onlyCall returns (uint256) {
- save(i);
- uint256 _value = read();
- save(0x11111);
- return _value;
- }
-
- function _staticCall1() external view onlyCall {}
-
- function _staticCall2() external view onlyCall returns (uint256) {
- return read();
- }
-
- function _staticCall3(uint256 i) external view onlyCall returns (uint256) {
- return i;
- }
-
- function _delegateCall1() external onlyDelegateCall {
- save(0);
- save(0x11111);
- }
-
- function _delegateCall2() external onlyDelegateCall returns (uint256) {
- save(0);
- save(0x11111);
- return read();
- }
-
- function _delegateCall3(uint256 i) external onlyDelegateCall returns (uint256) {
- save(i);
- uint256 _value = read();
- save(0x11111);
- return _value;
- }
-}
diff --git a/contracts/dev/DemoModule.sol b/contracts/dev/DemoModule.sol
deleted file mode 100644
index e817087c..00000000
--- a/contracts/dev/DemoModule.sol
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../modules/BaseModule.sol";
-
-contract DemoModule is BaseModule {
- mapping(address => bool) public isInit;
-
- event initEvent(address wallet);
- event deInitEvent(address wallet);
-
- bytes4 constant _function = bytes4(keccak256("addOwner(bytes32)"));
-
- function requiredFunctions() external pure override returns (bytes4[] memory) {
- // addOwner(address owner)
- bytes4[] memory _requiredFunctions = new bytes4[](1);
- _requiredFunctions[0] = _function;
- return _requiredFunctions;
- }
-
- function inited(address wallet) internal view override returns (bool) {
- return isInit[wallet];
- }
-
- function _init(bytes calldata data) internal override {
- (data);
- isInit[sender()] = true;
- emit initEvent(sender());
- }
-
- function _deInit() internal override {
- isInit[sender()] = false;
- emit deInitEvent(sender());
- }
-
- function addOwner(address target, bytes32 newOwner) external {
- require(inited(target));
- (bool ok, bytes memory res) = target.call{value: 0}(abi.encodeWithSelector(_function, newOwner));
- require(ok, string(res));
- }
-}
diff --git a/contracts/dev/DemoPlugin.sol b/contracts/dev/DemoPlugin.sol
deleted file mode 100644
index e67e6cf6..00000000
--- a/contracts/dev/DemoPlugin.sol
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../plugin/BasePlugin.sol";
-
-contract DemoPlugin is BasePlugin {
- mapping(address => bool) registry;
-
- event OnGuardHook();
- event OnPreHook();
- event OnPostHook();
-
- function _supportsHook() internal pure override returns (uint8 hookType) {
- hookType = GUARD_HOOK | PRE_HOOK | POST_HOOK;
- }
-
- function guardHook(UserOperation calldata userOp, bytes32 userOpHash, bytes calldata guardData) external override {
- (userOp, userOpHash, guardData);
- emit OnGuardHook();
- }
-
- function preHook(address target, uint256 value, bytes calldata data) external override {
- (target, value, data);
- emit OnPreHook();
- }
-
- function postHook(address target, uint256 value, bytes calldata data) external override {
- (target, value, data);
- emit OnPostHook();
- }
-
- function inited(address wallet) internal view virtual override returns (bool) {
- return registry[wallet];
- }
-
- function _init(bytes calldata data) internal virtual override {
- (data);
- registry[_wallet()] = true;
- }
-
- function _deInit() internal virtual override {
- delete registry[_wallet()];
- }
-}
diff --git a/contracts/dev/HelloWorld.sol b/contracts/dev/HelloWorld.sol
index fc8b2bd2..35e921c2 100644
--- a/contracts/dev/HelloWorld.sol
+++ b/contracts/dev/HelloWorld.sol
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.17;
contract HelloWorld {
function output() external pure returns (string memory) {
diff --git a/contracts/dev/NewImplementation.sol b/contracts/dev/NewImplementation.sol
index 6281e964..ebb78d41 100644
--- a/contracts/dev/NewImplementation.sol
+++ b/contracts/dev/NewImplementation.sol
@@ -2,10 +2,10 @@
pragma solidity ^0.8.20;
-import "../base/UpgradeManager.sol";
+import "../abstract/SoulWalletUpgradeManager.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
-contract NewImplementation is Initializable, UpgradeManager {
+contract NewImplementation is Initializable, SoulWalletUpgradeManager {
address public immutable WALLETIMPL;
bytes32 public constant CURRENT_UPGRADE_SLOT = keccak256("soul.wallet.upgradeTo_NewImplementation");
@@ -18,7 +18,7 @@ contract NewImplementation is Initializable, UpgradeManager {
bytes32[] calldata owners,
address defalutCallbackHandler,
bytes[] calldata modules,
- bytes[] calldata plugins
+ bytes[] calldata hooks
) external initializer {}
function hello() external pure returns (string memory) {
@@ -26,7 +26,7 @@ contract NewImplementation is Initializable, UpgradeManager {
}
function upgradeTo(address newImplementation) external override {
- UpgradeManager._upgradeTo(newImplementation);
+ _upgradeTo(newImplementation);
}
function upgradeFrom(address oldImplementation) external override {
diff --git a/contracts/miscellaneous/ReceivePayment.sol b/contracts/dev/ReceivePayment.sol
similarity index 77%
rename from contracts/miscellaneous/ReceivePayment.sol
rename to contracts/dev/ReceivePayment.sol
index 5a858832..01dfa06e 100644
--- a/contracts/miscellaneous/ReceivePayment.sol
+++ b/contracts/dev/ReceivePayment.sol
@@ -15,8 +15,6 @@ contract ReceivePayment is Ownable {
function pay(bytes32 _paymentId) external payable {
emit PaymentReceived(_paymentId, msg.sender, msg.value);
}
- // Transfer() and send() is hardcode 2300 gas, and can be out of gas when sending to smart contract
- // using call instead. more deital: https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/
function withdraw(address _to) external onlyOwner {
(bool success,) = payable(_to).call{value: address(this).balance}("");
diff --git a/contracts/dev/SafeLockHelper.sol b/contracts/dev/SafeLockHelper.sol
deleted file mode 100644
index 67629663..00000000
--- a/contracts/dev/SafeLockHelper.sol
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../safeLock/SafeLock.sol";
-
-contract SafeLockHelper is SafeLock {
- constructor(uint64 safeLockPeriod) SafeLock("SafeLockHelper", safeLockPeriod) {}
-
- function start(bytes32 _id) external {
- _lock(_id);
- }
-
- function cancel(bytes32 _id) external {
- _cancelLock(_id);
- }
-
- function end(bytes32 _id) external {
- _unlock(_id);
- }
-}
diff --git a/contracts/dev/SingletonFactory.sol b/contracts/dev/SingletonFactory.sol
deleted file mode 100644
index 6b8fd5c4..00000000
--- a/contracts/dev/SingletonFactory.sol
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Submitted for verification at Etherscan.io on 2020-03-30
- */
-
-pragma solidity ^0.8.20;
-
-/**
- * @title Singleton Factory (EIP-2470)
- * @notice Exposes CREATE2 (EIP-1014) to deploy bytecode on deterministic addresses based on initialization code and salt.
- * @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
- */
-contract SingletonFactory {
- /**
- * @notice Deploys `_initCode` using `_salt` for defining the deterministic address.
- * @param _initCode Initialization code.
- * @param _salt Arbitrary value to modify resulting address.
- * @return createdContract Created contract address.
- */
- function deploy(bytes memory _initCode, bytes32 _salt) public returns (address payable createdContract) {
- assembly {
- createdContract := create2(0, add(_initCode, 0x20), mload(_initCode), _salt)
- }
- }
-}
-// IV is a value changed to generate the vanity address.
-// IV: 6583047
diff --git a/contracts/dev/StorageWriter.sol b/contracts/dev/StorageWriter.sol
deleted file mode 100644
index 3040db6d..00000000
--- a/contracts/dev/StorageWriter.sol
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-
-pragma solidity ^0.8.20;
-
-contract StorageWriter {
- // Event to log the storage write operation
- event StorageUpdated(bytes32 indexed slot, bytes32 value);
-
- /**
- * @dev Writes a bytes32 value to a specific storage slot using inline assembly.
- * @param slot The storage slot to write to.
- * @param key The bytes32 value to write.
- */
- function writeToSlot(bytes32 slot, bytes32 key) external {
- assembly {
- sstore(slot, key)
- }
- emit StorageUpdated(slot, key);
- }
-}
diff --git a/contracts/dev/TestWebAuthn.sol b/contracts/dev/TestWebAuthn.sol
deleted file mode 100644
index 4cb0ca99..00000000
--- a/contracts/dev/TestWebAuthn.sol
+++ /dev/null
@@ -1,144 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-
-pragma solidity ^0.8.20;
-
-import "../libraries/WebAuthn.sol";
-import "../libraries/RS256Verify.sol";
-
-contract TestWebAuthn {
- function signatureP256Test() external view {
- /*
- register:
- {
- "username": "MyUsername",
- "credential": {
- "id": "Z5v4MnDJUhMpVBgphmNb7FQ9ylbDXnPXcde_i9QdEsM",
- "publicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6J6LS-lD-ttNxZn-Lor4enm0OK3eMoo7ctQzJFBs1bZPv-Si-ZNHg8Oxr3Eu6Hq8CPV255NG78O4NV2TG9e5dg==",
- "algorithm": "ES256"
- },
- "authenticatorData": "SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NFAAAAAK3OAAI1vMYKZIsLJfHwVQMAIGeb-DJwyVITKVQYKYZjW-xUPcpWw15z13HXv4vUHRLDpQECAyYgASFYIOiei0vpQ_rbTcWZ_i6K-Hp5tDit3jKKO3LUMyRQbNW2IlggT7_kovmTR4PDsa9xLuh6vAj1dueTRu_DuDVdkxvXuXY=",
- "clientData": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiZzNGQVZ0cHVhUkMxRlpVekRDd3MzNzl4ankzdjliM1lTNVhmZW44Mjl0MCIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTUwMCIsImNyb3NzT3JpZ2luIjpmYWxzZX0="
- }
-
- publicKey -> Qx, Qy
- Qx: 0xe89e8b4be943fadb4dc599fe2e8af87a79b438adde328a3b72d43324506cd5b6
- Qy: 0x4fbfe4a2f9934783c3b1af712ee87abc08f576e79346efc3b8355d931bd7b976
-
- userOpHash: 0x83714056da6e6910b51595330c2c2cdfbf718f2deff5bdd84b95df7a7f36f6dd
-
- sign:
- {
- "credentialId": "Z5v4MnDJUhMpVBgphmNb7FQ9ylbDXnPXcde_i9QdEsM",
- "authenticatorData": "SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MFAAAAAA==",
- "clientData": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiZzNGQVZ0cHVhUkMxRlpVekRDd3MzNzl4ankzdjliM1lTNVhmZW44Mjl0MCIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTUwMCIsImNyb3NzT3JpZ2luIjpmYWxzZX0=",
- "signature": "MEUCICrj3f5MxBTcD61_86XJYNHO4SEXItMJmt525awYJnMaAiEAh-XWVPNX5M1stSUSstpNkergrkjp2JLOUyuTUvY6VdY="
- }
- authenticatorData: SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MFAAAAAA==
- authenticatorData decode to hex: 0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000
-
- decode clientData: {"type":"webauthn.get","challenge":"g3FAVtpuaRC1FZUzDCws379xjy3v9b3YS5Xfen829t0","origin":"http://localhost:5500","crossOrigin":false}
- decode DER signature to r,s:
- r 0x2ae3ddfe4cc414dc0fad7ff3a5c960d1cee1211722d3099ade76e5ac1826731a
- s 0x87e5d654f357e4cd6cb52512b2da4d91eae0ae48e9d892ce532b9352f63a55d6
-
- */
-
- uint256 Qx = uint256(0xe89e8b4be943fadb4dc599fe2e8af87a79b438adde328a3b72d43324506cd5b6);
- uint256 Qy = uint256(0x4fbfe4a2f9934783c3b1af712ee87abc08f576e79346efc3b8355d931bd7b976);
- uint256 r = uint256(0x2ae3ddfe4cc414dc0fad7ff3a5c960d1cee1211722d3099ade76e5ac1826731a);
- uint256 s = uint256(0x87e5d654f357e4cd6cb52512b2da4d91eae0ae48e9d892ce532b9352f63a55d6);
- bytes32 userOpHash = 0x83714056da6e6910b51595330c2c2cdfbf718f2deff5bdd84b95df7a7f36f6dd;
- bytes memory authenticatorData = hex"49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000000";
- string memory clientDataSuffix = "\",\"origin\":\"http://localhost:5500\",\"crossOrigin\":false}";
- bool succ = WebAuthn.verifyP256Signature(Qx, Qy, r, s, userOpHash, authenticatorData, clientDataSuffix);
- require(succ, "WebAuthn-P256 verifySignature failed");
- }
-
- function signatureRS256Test() external view {
- bytes memory e = hex"0000000000000000000000000000000000000000000000000000000000010001";
-
- bytes memory Msg =
- hex"49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d976305000000013cdb7da78783855f4167a4a0d6fdccaeff7a8596ce7ca47c7a4dbfe6b8d6b43a";
-
- bytes memory S = hex"add8085f6dc3657e1cb034b945e4fa57df40b7eac0382281a1b225a41dc4bba8"
- hex"9230f0c3c14f8c2a979636710a646fe7d400a9ddfc545f0ac245dee9f678bf63"
- hex"85429f5c1719b7a2822e242eaf6edc52de17abd071f69ead3d8e76c2f33424f8"
- hex"247dfd1dcea9fbbe5723e3931b48388343afe7770e82b0a7c66592c90e32a15a"
- hex"6dda5850ce6efa4dc86f513ce68aa764eba9875c6a43a0c73d83bebffabd19bb"
- hex"791811779070f9a1c6072be5046c81dbc2a576beba964620258c2a1d6795956e"
- hex"17a7619beb26cbb500af65554fa84beef8608a6e2d3849f8893c50d7b450cabf"
- hex"d53be339061dd8691e73445c3c9290425e98132afe876cfddd240e5fe90f73f8";
-
- bytes memory n = hex"babd47aa475d28fb0bc840be692c3e8fbeb7bbb81e303d3ba262c3aa83fd5832"
- hex"91f60a1b17c168ed75ac28f6e084e69a5296a807c667acdbab6794424e474e6f"
- hex"13d6544c139bb39133300145abcf2cb542e5bdc99bfa0e1ce637631667db5bbd"
- hex"c65f11d0a8abb5d2cbc0ae618a7ba975fe4121f95b7762c08e912e6d9415bf4f"
- hex"f1ef75f0deab9833e37f0ae2273a421520ed64bb06246463698aba3ee2e70567"
- hex"0899da6899b0d1151f261fa1c5b5ca269a805fc12cb6f10e87b3a80536d63e5e"
- hex"e52108fd1bfc745ab0de326205d7e16f6fbdac6c65d0b91f46a74f6772faeffa"
- hex"82be6f9069d6bd1790e7261f85ca32b1934dc1c82345af729c4023401d1e2949";
-
- bytes32 message = sha256(Msg);
- bool succ = RS256Verify.RSASSA_PSS_VERIFY(n, e, message, S);
- require(succ, "WebAuthn-RS256 verifySignature failed");
- }
-
- function signatureRS256Test2() external view {
- /*
- register:
- {
- "credential": {
- "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxoB0Eu2NYWVlUIyHkpJoa7HbbwVhtix7ZqLTgG0WHAzO-IjSwe_PBh4mihXmHn0CNkYBTDOx6tMb7w5TeVWOb_cSSbFDwDq-wzorBV_I4KlHOTUS5-Jq0z8K1Kq_4y0GQpZYVtjiAgSkTXjjbMkNsqEs-8N_qXNg79OnNcYlq4FNb2u3xjq-Jhu9nFJoHGIh-TbWF9yE3mFVYHT2wdc7P_0kLSlA08AsWiaeOQvY5rYwGloKM5kQ9kgEA9J9MsL_K5vzO65Fw29CMCXKQfBcl75RSLLLJ2sxRBJ0EAvzygtQ2h7gRRG-m9u08St1eas9p4C8LGFeKkn14fdQsDTQrwIDAQAB",
- "algorithm": "RS256"
- }
- }
-
- publicKey -> e,n
- e: 0x010001
- n: 0xc6807412ed8d616565508c879292686bb1db6f0561b62c7b66a2d3806d161c0ccef888d2c1efcf061e268a15e61e7d023646014c33b1ead31bef0e5379558e6ff71249b143c03abec33a2b055fc8e0a947393512e7e26ad33f0ad4aabfe32d0642965856d8e20204a44d78e36cc90db2a12cfbc37fa97360efd3a735c625ab814d6f6bb7c63abe261bbd9c52681c6221f936d617dc84de61556074f6c1d73b3ffd242d2940d3c02c5a269e390bd8e6b6301a5a0a339910f6480403d27d32c2ff2b9bf33bae45c36f423025ca41f05c97be5148b2cb276b31441274100bf3ca0b50da1ee04511be9bdbb4f12b7579ab3da780bc2c615e2a49f5e1f750b034d0af
-
-
- userOpHash: 0x83714056da6e6910b51595330c2c2cdfbf718f2deff5bdd84b95df7a7f36f6dd
-
- sign:
- // {"type":"webauthn.get","challenge":"g3FAVtpuaRC1FZUzDCws379xjy3v9b3YS5Xfen829t0","origin":"http://localhost:5500","crossOrigin":false}
- {
- "credentialId": "7tHBySevVSHJIYJJWSNS_f3UDx9WgBQ1UbLq60E2ehs",
- "authenticatorData": "SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MFAAAAAQ==",
- "clientData": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiZzNGQVZ0cHVhUkMxRlpVekRDd3MzNzl4ankzdjliM1lTNVhmZW44Mjl0MCIsIm9yaWdpbiI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTUwMCIsImNyb3NzT3JpZ2luIjpmYWxzZX0=",
- "signature": "NXpRsm4i3PuHNGu2k4z7KwZtSNTDbK_TCsEF_jRRmZZvJMh_pmeR1MI0G5f6B0Ie9BFamSPmJJxTiHtvIxPfYGVAg3WP5xBChkkOGjdIEkY5XcsJeoZkXcMlGvpch-S8jylgz-Pvo0xEu-4P49YChmyBpfxDJwlEPGI1lVVmcKQnUCxjweaoZ2HIsya19QO9z9zx8Ahx8zCp_d9q4Rrc_0pfQR7ewwAZyGk2-AZLcPiM21a6ZjUXX371x09S3p21SY5MTUt1yKMhDlsaYxryccS2E6h1Kyoc6kmb2BEV2e00MF2atK91Pcm5YwR4_bB4fl9eDvt2UE0V7_X9AqOL8Q=="
- }
- authenticatorData: SZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2MFAAAAAQ==
- authenticatorData decode to hex: 0x49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000001
-
- decode clientData: {"type":"webauthn.get","challenge":"g3FAVtpuaRC1FZUzDCws379xjy3v9b3YS5Xfen829t0","origin":"http://localhost:5500","crossOrigin":false}
- signature to hex:
- 0x357a51b26e22dcfb87346bb6938cfb2b066d48d4c36cafd30ac105fe345199966f24c87fa66791d4c2341b97fa07421ef4115a9923e6249c53887b6f2313df60654083758fe7104286490e1a37481246395dcb097a86645dc3251afa5c87e4bc8f2960cfe3efa34c44bbee0fe3d602866c81a5fc432709443c623595556670a427502c63c1e6a86761c8b326b5f503bdcfdcf1f00871f330a9fddf6ae11adcff4a5f411edec30019c86936f8064b70f88cdb56ba6635175f7ef5c74f52de9db5498e4c4d4b75c8a3210e5b1a631af271c4b613a8752b2a1cea499bd81115d9ed34305d9ab4af753dc9b9630478fdb0787e5f5e0efb76504d15eff5fd02a38bf1
-
-
- */
- bytes32 userOpHash = 0x83714056da6e6910b51595330c2c2cdfbf718f2deff5bdd84b95df7a7f36f6dd;
- bytes memory challengeBase64 = bytes(Base64Url.encode(bytes.concat(userOpHash)));
- string memory clientDataPrefix = "{\"type\":\"webauthn.get\",\"challenge\":\"";
- string memory clientDataSuffix = "\",\"origin\":\"http://localhost:5500\",\"crossOrigin\":false}";
- bytes memory clientDataJSON = bytes.concat(bytes(clientDataPrefix), challengeBase64, bytes(clientDataSuffix));
- bytes32 clientHash = sha256(clientDataJSON);
- bytes memory authenticatorData = hex"49960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d97630500000001";
- bytes32 message = sha256(bytes.concat(authenticatorData, clientHash));
- bytes memory e = hex"0000000000000000000000000000000000000000000000000000000000010001";
- bytes memory n =
- hex"c6807412ed8d616565508c879292686bb1db6f0561b62c7b66a2d3806d161c0ccef888d2c1efcf061e268a15e61e7d023646014c33b1ead31bef0e5379558e6ff71249b143c03abec33a2b055fc8e0a947393512e7e26ad33f0ad4aabfe32d0642965856d8e20204a44d78e36cc90db2a12cfbc37fa97360efd3a735c625ab814d6f6bb7c63abe261bbd9c52681c6221f936d617dc84de61556074f6c1d73b3ffd242d2940d3c02c5a269e390bd8e6b6301a5a0a339910f6480403d27d32c2ff2b9bf33bae45c36f423025ca41f05c97be5148b2cb276b31441274100bf3ca0b50da1ee04511be9bdbb4f12b7579ab3da780bc2c615e2a49f5e1f750b034d0af";
- bytes memory signature =
- hex"357a51b26e22dcfb87346bb6938cfb2b066d48d4c36cafd30ac105fe345199966f24c87fa66791d4c2341b97fa07421ef4115a9923e6249c53887b6f2313df60654083758fe7104286490e1a37481246395dcb097a86645dc3251afa5c87e4bc8f2960cfe3efa34c44bbee0fe3d602866c81a5fc432709443c623595556670a427502c63c1e6a86761c8b326b5f503bdcfdcf1f00871f330a9fddf6ae11adcff4a5f411edec30019c86936f8064b70f88cdb56ba6635175f7ef5c74f52de9db5498e4c4d4b75c8a3210e5b1a631af271c4b613a8752b2a1cea499bd81115d9ed34305d9ab4af753dc9b9630478fdb0787e5f5e0efb76504d15eff5fd02a38bf1";
- bool success = RS256Verify.RSASSA_PSS_VERIFY(n, e, message, signature);
- require(success, "WebAuthn-RS256 verifySignature failed");
- }
-
- function recoverTest(bytes32 userOpHash, bytes calldata packedSignature) public view returns (bytes32) {
- bytes32 publicKey = WebAuthn.recover(userOpHash, packedSignature);
- if (publicKey == 0) {
- revert("WebAuthn-p256 recover failed");
- }
- return publicKey;
- }
-}
diff --git a/contracts/dev/TimeLockEmailGuardian.sol b/contracts/dev/TimeLockEmailGuardian.sol
new file mode 100644
index 00000000..5f000572
--- /dev/null
+++ b/contracts/dev/TimeLockEmailGuardian.sol
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+import "@openzeppelin/contracts/access/Ownable.sol";
+import "@openzeppelin/contracts/access/AccessControl.sol";
+import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
+import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
+
+contract TimeLockEmailGuardian is Ownable, AccessControl {
+ using ECDSA for bytes32;
+ using MessageHashUtils for bytes32;
+
+ bytes32 public constant APPROVER_ROLE = keccak256("APPROVER_ROLE");
+ mapping(bytes32 => uint256) private approveTime;
+ uint256 constant VALID_PERIOD_START = 2 days;
+ uint256 constant VALID_PERIOD_END = 7 days;
+ bytes4 internal constant MAGICVALUE = 0x1626ba7e;
+ bytes4 internal constant INVALID_ID = 0xffffffff;
+ bytes32 private constant TYPE_HASH =
+ keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
+ bytes32 private constant _TYPE_HASH_SOCIAL_RECOVERY =
+ keccak256("SocialRecovery(bytes32 keyStoreSlot,uint256 nonce,bytes32 newSigner)");
+ bytes32 private constant _TYPE_HASH_CANCEL_SOCIAL_RECOVERY =
+ keccak256("CancelSocialRecovery(bytes32 keyStoreSlot,uint256 nonce,bytes32 newSigner)");
+ bytes32 private immutable hashedName;
+ bytes32 private immutable hashedVersion;
+ address private immutable keystoreAddr;
+
+ event RecoveryApproved(bytes32 indexed slot, uint256 slotNonce, bytes32 newKey, uint256 timestamp);
+ event RecoveryCancelled(bytes32 indexed slot, uint256 slotNonce, bytes32 newKey, uint256 timestamp);
+
+ constructor(address _keystoreAddr, address _owner) Ownable(_owner) {
+ hashedName = keccak256(bytes("KeyStore"));
+ hashedVersion = keccak256(bytes("1"));
+ keystoreAddr = _keystoreAddr;
+ _grantRole(DEFAULT_ADMIN_ROLE, _owner);
+ }
+
+ function _domainSeparatorV4() internal view returns (bytes32) {
+ return _buildDomainSeparator();
+ }
+
+ function _buildDomainSeparator() private view returns (bytes32) {
+ return keccak256(abi.encode(TYPE_HASH, hashedName, hashedVersion, block.chainid, address(keystoreAddr)));
+ }
+
+ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
+ return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);
+ }
+
+ function approveRecovery(bytes32 slot, uint256 slotNonce, bytes32 newKey, bytes calldata signatureData) public {
+ bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(_TYPE_HASH_SOCIAL_RECOVERY, slot, slotNonce, newKey)));
+ require(approveTime[digest] == 0, "already approved");
+ (uint256 validUntil, bytes memory signatures) = abi.decode(signatureData, (uint256, bytes));
+ require(signatures.length == 65, "invalid signature length");
+ require(block.timestamp <= validUntil, "signature expired");
+ bytes32 verifyHash = keccak256(abi.encode(digest, validUntil));
+ address recoveredAddress = verifyHash.recover(signatures);
+ require(hasRole(APPROVER_ROLE, recoveredAddress), "invalid signature");
+ approveTime[digest] = block.timestamp;
+ emit RecoveryApproved(slot, slotNonce, newKey, block.timestamp);
+ }
+
+ function cancleRecovery(bytes32 slot, uint256 slotNonce, bytes32 newKey, bytes calldata signatureData) public {
+ bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(_TYPE_HASH_SOCIAL_RECOVERY, slot, slotNonce, newKey)));
+ require(approveTime[digest] != 0, "not approved");
+ bytes32 cancelDigest =
+ _hashTypedDataV4(keccak256(abi.encode(_TYPE_HASH_CANCEL_SOCIAL_RECOVERY, slot, slotNonce, newKey)));
+ (uint256 validUntil, bytes memory signatures) = abi.decode(signatureData, (uint256, bytes));
+ require(signatures.length == 65, "invalid signature length");
+ require(block.timestamp <= validUntil, "signature expired");
+ bytes32 verifyHash = keccak256(abi.encode(cancelDigest, validUntil));
+ address recoveredAddress = verifyHash.recover(signatures);
+ require(hasRole(APPROVER_ROLE, recoveredAddress), "invalid signature");
+ approveTime[digest] = 0;
+ emit RecoveryCancelled(slot, slotNonce, newKey, block.timestamp);
+ }
+
+ function isValidSignature(bytes32 _hash, bytes memory _signature) public view returns (bytes4) {
+ require(_signature.length == 0, "invalid signature length");
+ uint256 storedTime = approveTime[_hash];
+ if (storedTime == 0) {
+ return INVALID_ID;
+ }
+ uint256 currentTime = block.timestamp;
+ if (currentTime >= storedTime + VALID_PERIOD_START && currentTime <= storedTime + VALID_PERIOD_END) {
+ return MAGICVALUE;
+ }
+ return INVALID_ID;
+ }
+}
diff --git a/contracts/dev/Tokens/TokenERC721.sol b/contracts/dev/Tokens/TokenERC721.sol
deleted file mode 100644
index f815a908..00000000
--- a/contracts/dev/Tokens/TokenERC721.sol
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.20;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-
-contract TokenERC721 is ERC721 {
- constructor() ERC721("MyToken", "MTK") {}
-
- function _baseURI() internal pure override returns (string memory) {
- return "http://soulwallet";
- }
-
- function safeMint(address to, uint256 tokenId) external {
- _safeMint(to, tokenId);
- }
-}
diff --git a/contracts/factory/SoulWalletFactory.sol b/contracts/factory/SoulWalletFactory.sol
new file mode 100644
index 00000000..a2d4c7e5
--- /dev/null
+++ b/contracts/factory/SoulWalletFactory.sol
@@ -0,0 +1,136 @@
+
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+/* solhint-disable avoid-low-level-calls */
+/* solhint-disable no-inline-assembly */
+/* solhint-disable reason-string */
+
+import "../SoulWallet.sol";
+import "@openzeppelin/contracts/utils/Create2.sol";
+import {IEntryPoint} from "@account-abstraction/contracts/interfaces/IEntryPoint.sol";
+import "@openzeppelin/contracts/access/Ownable.sol";
+
+/**
+ * @title SoulWalletFactory
+ * @author soulwallet team
+ * @notice A factory contract to create soul wallets
+ * @dev This contract is called by the entrypoint which uses the "initCode" to create and return the sender's wallet address
+ */
+contract SoulWalletFactory is Ownable {
+ address immutable public _WALLETIMPL;
+ IEntryPoint public immutable entryPoint;
+ string public constant VERSION = "0.0.1";
+
+ event SoulWalletCreation(address indexed proxy);
+
+ /**
+ * @dev Initializes the factory with the wallet implementation and entry point addresses
+ * @param _walletImpl Address of the SoulWallet implementation
+ * @param _entryPoint Address of the EntryPoint contract
+ * @param _owner Address of the contract owner
+ */
+ constructor(address _walletImpl, address _entryPoint, address _owner) Ownable(_owner) {
+ require(_walletImpl != address(0), "Invalid wallet implementation address");
+ _WALLETIMPL = _walletImpl;
+ require(_entryPoint != address(0), "Invalid entry point address");
+ entryPoint = IEntryPoint(_entryPoint);
+ }
+
+
+ function _calcSalt(bytes memory _initializer, bytes32 _salt) private pure returns (bytes32 salt) {
+ return keccak256(abi.encodePacked(keccak256(_initializer), _salt));
+ }
+
+ /**
+ * @dev Deploys the SoulWallet using a proxy and returns the proxy's address
+ * @param _initializer Initialization data
+ * @param _salt Salt for the create2 deployment
+ * @return proxy Address of the deployed proxy
+ */
+ function createWallet(bytes memory _initializer, bytes32 _salt) external returns (address proxy) {
+ bytes memory deploymentData = _proxyCode(_WALLETIMPL);
+ bytes32 salt = _calcSalt(_initializer, _salt);
+ assembly ("memory-safe") {
+ proxy := create2(0x0, add(deploymentData, 0x20), mload(deploymentData), salt)
+ }
+ if (proxy == address(0)) {
+ revert();
+ }
+ assembly ("memory-safe") {
+ let succ := call(gas(), proxy, 0, add(_initializer, 0x20), mload(_initializer), 0, 0)
+ if eq(succ, 0) { revert(0, 0) }
+ }
+ emit SoulWalletCreation(proxy);
+ }
+
+ /**
+ * @notice Returns the proxy's creation code
+ * @dev Used by soulwalletlib to calculate the SoulWallet address
+ * @return Byte array representing the proxy's creation code
+ */
+ function proxyCode() external view returns (bytes memory) {
+ return _proxyCode(_WALLETIMPL);
+ }
+ /**
+ * @notice using solay ERC1967 https://github.com/Vectorized/solady/blob/5eff720c27746987dc95e5e2b720615d3d96f7ee/src/utils/LibClone.sol#L774C18-L774C18
+ */
+ function _proxyCode(address implementation) private pure returns (bytes memory deploymentData) {
+ deploymentData = abi.encodePacked(
+ hex"603d3d8160223d3973",
+ implementation,
+ hex"60095155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3"
+ );
+ }
+
+ /**
+ * @notice Calculates the counterfactual address of the SoulWallet as it would be returned by `createWallet`
+ * @param _initializer Initialization data
+ * @param _salt Salt for the create2 deployment
+ * @return proxy Counterfactual address of the SoulWallet
+ */
+ function getWalletAddress(bytes memory _initializer, bytes32 _salt) external view returns (address proxy) {
+ bytes memory deploymentData = _proxyCode(_WALLETIMPL);
+ bytes32 salt = _calcSalt(_initializer, _salt);
+ proxy = Create2.computeAddress(salt, keccak256(deploymentData));
+ }
+
+ /**
+ * @notice Deposits ETH to the entry point on behalf of the contract
+ */
+ function deposit() public payable {
+ entryPoint.depositTo{value: msg.value}(address(this));
+ }
+
+ /**
+ * @notice Allows the owner to withdraw ETH from entrypoint contract
+ * @param withdrawAddress Address to receive the withdrawn ETH
+ * @param amount Amount of ETH to withdraw
+ */
+ function withdrawTo(address payable withdrawAddress, uint256 amount) public onlyOwner {
+ entryPoint.withdrawTo(withdrawAddress, amount);
+ }
+
+ /**
+ * @notice Allows the owner to add stake to the entry point
+ * @param unstakeDelaySec Duration (in seconds) after which the stake can be unlocked
+ */
+ function addStake(uint32 unstakeDelaySec) external payable onlyOwner {
+ entryPoint.addStake{value: msg.value}(unstakeDelaySec);
+ }
+
+ /**
+ * @notice Allows the owner to unlock their stake from the entry point
+ */
+ function unlockStake() external onlyOwner {
+ entryPoint.unlockStake();
+ }
+
+ /**
+ * @notice Allows the owner to withdraw their stake from the entry point
+ * @param withdrawAddress Address to receive the withdrawn stake
+ */
+ function withdrawStake(address payable withdrawAddress) external onlyOwner {
+ entryPoint.withdrawStake(withdrawAddress);
+ }
+}
diff --git a/contracts/handler/DefaultCallbackHandler.sol b/contracts/handler/DefaultCallbackHandler.sol
deleted file mode 100644
index 069cfe17..00000000
--- a/contracts/handler/DefaultCallbackHandler.sol
+++ /dev/null
@@ -1,6 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "@account-abstraction/contracts/samples/callback/TokenCallbackHandler.sol";
-
-contract DefaultCallbackHandler is TokenCallbackHandler {}
diff --git a/contracts/handler/ERC1271Handler.sol b/contracts/handler/ERC1271Handler.sol
deleted file mode 100644
index 90cd3a7b..00000000
--- a/contracts/handler/ERC1271Handler.sol
+++ /dev/null
@@ -1,94 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../helper/SignatureValidator.sol";
-import "@account-abstraction/contracts/core/Helpers.sol";
-import "../interfaces/IERC1271Handler.sol";
-import "../authority/Authority.sol";
-import "../libraries/AccountStorage.sol";
-
-/**
- * @title ERC1271Handler
- * @dev This contract provides functionality to handle ERC1271 signature validations
- */
-abstract contract ERC1271Handler is Authority, IERC1271Handler, SignatureValidator {
- // Magic value indicating a valid signature for ERC-1271 contracts
- // bytes4(keccak256("isValidSignature(bytes32,bytes)")
- bytes4 internal constant MAGICVALUE = 0x1626ba7e;
- // Constants indicating different invalid states
- bytes4 internal constant INVALID_ID = 0xffffffff;
- bytes4 internal constant INVALID_TIME_RANGE = 0xfffffffe;
- /**
- * @dev Provides access to the mapping of approved hashes from the AccountStorage
- * @return The mapping of approved hashes
- */
-
- function _approvedHashes() private view returns (mapping(bytes32 => uint256) storage) {
- return AccountStorage.layout().approvedHashes;
- }
- /**
- * @dev Checks if a given signature is valid for the provided hash
- * @param rawHash The raw hash to check the signature against
- * @param signature The provided signature
- * @return magicValue A bytes4 magic value indicating the result of the signature check
- */
-
- function isValidSignature(bytes32 rawHash, bytes calldata signature)
- external
- view
- override
- returns (bytes4 magicValue)
- {
- bytes32 datahash = _encodeRawHash(rawHash);
- if (signature.length > 0) {
- (uint256 _validationData, bool sigValid) = _isValidate1271Signature(datahash, signature);
- if (!sigValid) {
- return INVALID_ID;
- }
- if (_validationData > 0) {
- ValidationData memory validationData = _parseValidationData(_validationData);
- bool outOfTimeRange =
- (block.timestamp > validationData.validUntil) || (block.timestamp < validationData.validAfter);
- if (outOfTimeRange) {
- return INVALID_TIME_RANGE;
- }
- }
- return MAGICVALUE;
- }
-
- mapping(bytes32 => uint256) storage approvedHashes = _approvedHashes();
- uint256 status = approvedHashes[datahash];
- if (status == 1) {
- // approved
- return MAGICVALUE;
- } else {
- return INVALID_ID;
- }
- }
- /**
- * @dev Approves a given hash
- * @param hash The hash to be approved
- */
-
- function approveHash(bytes32 hash) external override onlySelfOrModule {
- mapping(bytes32 => uint256) storage approvedHashes = _approvedHashes();
- if (approvedHashes[hash] == 1) {
- revert Errors.HASH_ALREADY_APPROVED();
- }
- approvedHashes[hash] = 1;
- emit ApproveHash(hash);
- }
- /**
- * @dev Rejects a given hash
- * @param hash The hash to be rejected
- */
-
- function rejectHash(bytes32 hash) external override onlySelfOrModule {
- mapping(bytes32 => uint256) storage approvedHashes = _approvedHashes();
- if (approvedHashes[hash] == 0) {
- revert Errors.HASH_ALREADY_REJECTED();
- }
- approvedHashes[hash] = 0;
- emit RejectHash(hash);
- }
-}
diff --git a/contracts/helper/SignatureValidator.sol b/contracts/helper/SignatureValidator.sol
deleted file mode 100644
index c8037e2a..00000000
--- a/contracts/helper/SignatureValidator.sol
+++ /dev/null
@@ -1,87 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
-import "../authority/OwnerAuth.sol";
-import "../base/Validator.sol";
-import "../libraries/Errors.sol";
-import "../libraries/TypeConversion.sol";
-import "../libraries/SignatureDecoder.sol";
-
-/**
- * @title SignatureValidator
- * @dev This contract provides functionality for validating cryptographic signatures
- */
-abstract contract SignatureValidator is OwnerAuth, Validator {
- using ECDSA for bytes32;
- using TypeConversion for address;
- /**
- * @dev Encodes the raw hash using a validator to prevent replay attacks
- * If the same owner signs the message for different smart contract accounts,
- * this function uses EIP-712-like encoding to encode the raw hash
- * @param rawHash The raw hash to encode
- * @return encodeRawHash The encoded hash
- */
-
- function _encodeRawHash(bytes32 rawHash) internal view returns (bytes32 encodeRawHash) {
- return validator().encodeRawHash(rawHash);
- }
- /**
- * @dev Validates an EIP1271 signature
- * @param rawHash The raw hash against which the signature is to be checked
- * @param rawSignature The signature to validate
- * @return validationData The data used for validation
- * @return sigValid A boolean indicating if the signature is valid or not
- */
-
- function _isValidate1271Signature(bytes32 rawHash, bytes calldata rawSignature)
- internal
- view
- returns (uint256 validationData, bool sigValid)
- {
- bytes32 recovered;
- bool success;
- bytes calldata guardHookInputData;
- bytes calldata validatorSignature;
-
- (guardHookInputData, validatorSignature) = SignatureDecoder.decodeSignature(rawSignature);
-
- // To prevent potential attacks, prohibit the use of guardHookInputData with EIP1271 signatures.
- require(guardHookInputData.length == 0);
-
- (validationData, recovered, success) = validator().recover1271Signature(rawHash, validatorSignature);
-
- if (!success) {
- sigValid = false;
- } else {
- sigValid = _isOwner(recovered);
- }
- }
- /**
- * @dev Validates a user operation signature
- * @param userOpHash The hash of the user operation
- * @param userOpSignature The signature of the user operation
- * @return validationData same as defined in EIP4337
- * @return sigValid A boolean indicating if the signature is valid or not
- * @return guardHookInputData Input data for the guard hook
- */
-
- function _isValidUserOp(bytes32 userOpHash, bytes calldata userOpSignature)
- internal
- view
- returns (uint256 validationData, bool sigValid, bytes calldata guardHookInputData)
- {
- bytes32 recovered;
- bool success;
- bytes calldata validatorSignature;
-
- (guardHookInputData, validatorSignature) = SignatureDecoder.decodeSignature(userOpSignature);
-
- (validationData, recovered, success) = validator().recoverSignature(userOpHash, validatorSignature);
- if (!success) {
- sigValid = false;
- } else {
- sigValid = _isOwner(recovered);
- }
- }
-}
diff --git a/contracts/hooks/2fa/Crypto2FAHook.sol b/contracts/hooks/2fa/Crypto2FAHook.sol
new file mode 100644
index 00000000..7916e7f5
--- /dev/null
+++ b/contracts/hooks/2fa/Crypto2FAHook.sol
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IHook, UserOperation} from "@soulwallet-core/contracts/interface/IHook.sol";
+import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
+import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
+import "forge-std/console.sol";
+
+contract Crypto2FAHook is IHook {
+ using ECDSA for bytes32;
+ using MessageHashUtils for bytes32;
+
+ uint256 public constant TIME_LOCK_DURATION = 1 days;
+
+ struct User2FA {
+ bool initialized;
+ address wallet2FAAddr;
+ address pending2FAAddr;
+ uint256 effectiveTime;
+ }
+
+ mapping(address => User2FA) public user2FA;
+
+ function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
+ return interfaceId == type(IHook).interfaceId;
+ }
+
+ function Init(bytes calldata data) external override {
+ console.logBytes(data);
+ User2FA storage _user2fa = user2FA[msg.sender];
+ require(_user2fa.initialized == false, "already initialized");
+ address wallet2FAAddr = address(bytes20(data[:20]));
+ _user2fa.initialized = true;
+ _user2fa.wallet2FAAddr = wallet2FAAddr;
+ }
+
+ function DeInit() external override {
+ User2FA storage _user2fa = user2FA[msg.sender];
+ require(_user2fa.initialized == true, "cannot deinit");
+ delete user2FA[msg.sender];
+ }
+
+ function preIsValidSignatureHook(bytes32 hash, bytes calldata hookSignature) external view override {
+ address recoveredAddress = hash.toEthSignedMessageHash().recover(hookSignature);
+ require(recoveredAddress == user2FA[msg.sender].wallet2FAAddr, "Crypto2FAHook: invalid signature");
+ }
+
+ function preUserOpValidationHook(
+ UserOperation calldata userOp,
+ bytes32 userOpHash,
+ uint256 missingAccountFunds,
+ bytes calldata hookSignature
+ ) external view override {
+ console.log("hookSignature");
+ console.logBytes(hookSignature);
+ (userOp, userOpHash, missingAccountFunds, hookSignature);
+ address recoveredAddress = userOpHash.toEthSignedMessageHash().recover(hookSignature);
+ require(recoveredAddress == user2FA[msg.sender].wallet2FAAddr, "Crypto2FAHook: invalid signature");
+ }
+
+ function initiateChange2FA(address new2FA) external {
+ User2FA storage _user2fa = user2FA[msg.sender];
+ require(_user2fa.initialized, "User not initialized");
+ _user2fa.pending2FAAddr = new2FA;
+ _user2fa.effectiveTime = block.timestamp + TIME_LOCK_DURATION;
+ }
+
+ function applyChange2FA() external {
+ User2FA storage _user2fa = user2FA[msg.sender];
+ require(block.timestamp >= _user2fa.effectiveTime, "Time lock not expired");
+ _user2fa.wallet2FAAddr = _user2fa.pending2FAAddr;
+ _user2fa.pending2FAAddr = address(0);
+ _user2fa.effectiveTime = 0;
+ }
+
+ function cancelChange2FA() external {
+ User2FA storage _user2fa = user2FA[msg.sender];
+ require(block.timestamp < _user2fa.effectiveTime, "Change already effective");
+ _user2fa.pending2FAAddr = address(0);
+ _user2fa.effectiveTime = 0;
+ }
+}
diff --git a/contracts/interfaces/IERC1271Handler.sol b/contracts/interfaces/IERC1271Handler.sol
deleted file mode 100644
index 5a19ec0f..00000000
--- a/contracts/interfaces/IERC1271Handler.sol
+++ /dev/null
@@ -1,33 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "@openzeppelin/contracts/interfaces/IERC1271.sol";
-
-/**
- * @title IERC1271Handler
- * @dev This interface extends the IERC1271 interface by adding functionality to approve and reject hashes
- * The main intention is to manage the approval status of specific signed hashes
- */
-interface IERC1271Handler is IERC1271 {
- /**
- * @dev Emitted when a hash has been approved.
- * @param hash The approved hash.
- */
- event ApproveHash(bytes32 indexed hash);
- /**
- * @dev Emitted when a hash has been rejected
- * @param hash The rejected hash
- */
- event RejectHash(bytes32 indexed hash);
- /**
- * @notice Approves the given hash
- * @param hash The hash to approve
- */
-
- function approveHash(bytes32 hash) external;
- /**
- * @notice Rejects the given hash
- * @param hash The hash to reject
- */
- function rejectHash(bytes32 hash) external;
-}
diff --git a/contracts/interfaces/IExecutionManager.sol b/contracts/interfaces/IExecutionManager.sol
deleted file mode 100644
index 76695eaf..00000000
--- a/contracts/interfaces/IExecutionManager.sol
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-/**
- * @title IExecutionManager
- * @dev Interface for executing transactions or batch of transactions
- * The execution can be a single transaction or multiple transactions in sequence
- */
-interface IExecutionManager {
- /**
- * @notice Executes a single transaction
- * @dev This can be invoked directly by the owner or by an entry point
- *
- * @param dest The destination address for the transaction
- * @param value The amount of Ether (in wei) to transfer along with the transaction. Can be 0 for non-ETH transfers
- * @param func The function call data to be executed
- */
- function execute(address dest, uint256 value, bytes calldata func) external;
-
- /**
- * @notice Executes a sequence of transactions with the same Ether value for each
- * @dev All transactions in the batch will carry 0 Ether value
- * @param dest An array of destination addresses for each transaction in the batch
- * @param func An array of function call data for each transaction in the batch
- */
- function executeBatch(address[] calldata dest, bytes[] calldata func) external;
-
- /**
- * @notice Executes a sequence of transactions with specified Ether values for each
- * @dev The values for Ether transfer are specified for each transaction
- * @param dest An array of destination addresses for each transaction in the batch
- * @param value An array of amounts of Ether (in wei) to transfer for each transaction in the batch
- * @param func An array of function call data for each transaction in the batch
- */
- function executeBatch(address[] calldata dest, uint256[] calldata value, bytes[] calldata func) external;
-}
diff --git a/contracts/interfaces/IModule.sol b/contracts/interfaces/IModule.sol
deleted file mode 100644
index 530329eb..00000000
--- a/contracts/interfaces/IModule.sol
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "./IPluggable.sol";
-
-/**
- * @title Module Interface
- * @dev This interface defines the funcations that a module needed access in the smart contract wallet
- * Modules are key components that can be plugged into the main contract to enhance its functionalities
- * For security reasons, a module can only call functions in the smart contract that it has explicitly
- * listed via the `requiredFunctions` method
- */
-interface IModule is IPluggable {
- /**
- * @notice Provides a list of function selectors that the module is allowed to call
- * within the smart contract. When a module is added to the smart contract, it's restricted
- * to only call these functions. This ensures that modules have explicit and limited permissions,
- * enhancing the security of the smart contract (e.g., a "Daily Limit" module shouldn't be able to
- * change the owner)
- *
- * @return An array of function selectors that this module is permitted to call
- */
- function requiredFunctions() external pure returns (bytes4[] memory);
-}
diff --git a/contracts/interfaces/IModuleManager.sol b/contracts/interfaces/IModuleManager.sol
deleted file mode 100644
index f8a95eab..00000000
--- a/contracts/interfaces/IModuleManager.sol
+++ /dev/null
@@ -1,62 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "./IModule.sol";
-
-/**
- * @title Module Manager Interface
- * @dev This interface defines the management functionalities for handling modules
- * within the system. Modules are components that can be added to or removed from the
- * smart contract to extend its functionalities. The manager ensures that only authorized
- * modules can execute certain functionalities
- */
-interface IModuleManager {
- /**
- * @notice Emitted when a new module is successfully added
- * @param module The address of the newly added module
- */
- event ModuleAdded(address indexed module);
- /**
- * @notice Emitted when a module is successfully removed
- * @param module The address of the removed module
- */
- event ModuleRemoved(address indexed module);
- /**
- * @notice Emitted when there's an error while removing a module
- * @param module The address of the module that was attempted to be removed
- */
- event ModuleRemovedWithError(address indexed module);
-
- /**
- * @notice Adds a new module to the system
- * @param moduleAndData The module to be added and its associated initialization data
- */
- function addModule(bytes calldata moduleAndData) external;
- /**
- * @notice Removes a module from the system
- * @param module The address of the module to be removed
- */
- function removeModule(address module) external;
-
- /**
- * @notice Checks if a module is authorized within the system
- * @param module The address of the module to check
- * @return True if the module is authorized, false otherwise
- */
- function isAuthorizedModule(address module) external returns (bool);
- /**
- * @notice Provides a list of all added modules and their respective authorized function selectors
- * @return modules An array of the addresses of all added modules
- * @return selectors A 2D array where each inner array represents the function selectors
- * that the corresponding module in the 'modules' array is allowed to call
- */
- function listModule() external view returns (address[] memory modules, bytes4[][] memory selectors);
- /**
- * @notice Allows a module to execute a function within the system. This ensures that the
- * module can only call functions it is permitted to, based on its declared `requiredFunctions`
- * @param dest The address of the destination contract where the function will be executed
- * @param value The amount of ether (in wei) to be sent with the function call
- * @param func The function data to be executed
- */
- function executeFromModule(address dest, uint256 value, bytes calldata func) external;
-}
diff --git a/contracts/interfaces/IOwnerManager.sol b/contracts/interfaces/IOwnerManager.sol
deleted file mode 100644
index 9271f9fc..00000000
--- a/contracts/interfaces/IOwnerManager.sol
+++ /dev/null
@@ -1,71 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-/**
- * @title Owner Manager Interface
- * @dev This interface defines the management functionalities for handling owners within the system.
- * Owners are identified by a unique bytes32 ID. This design allows for a flexible representation
- * of ownership – whether it be an Ethereum address, a hash of an off-chain public key, or any other
- * unique identifier.
- */
-interface IOwnerManager {
- /**
- * @notice Emitted when a new owner is successfully added
- * @param owner The bytes32 ID of the newly added owner
- */
- event OwnerAdded(bytes32 indexed owner);
-
- /**
- * @notice Emitted when an owner is successfully removed
- * @param owner The bytes32 ID of the removed owner
- */
- event OwnerRemoved(bytes32 indexed owner);
-
- /**
- * @notice Emitted when all owners are cleared from the system
- */
- event OwnerCleared();
-
- /**
- * @notice Checks if a given bytes32 ID corresponds to an owner within the system
- * @param owner The bytes32 ID to check
- * @return True if the ID corresponds to an owner, false otherwise
- */
- function isOwner(bytes32 owner) external view returns (bool);
-
- /**
- * @notice Adds a new owner to the system
- * @param owner The bytes32 ID of the owner to be added
- */
- function addOwner(bytes32 owner) external;
-
- /**
- * @notice Removes an existing owner from the system
- * @param owner The bytes32 ID of the owner to be removed
- */
- function removeOwner(bytes32 owner) external;
-
- /**
- * @notice Resets the entire owner set, replacing it with a single new owner
- * @param newOwner The bytes32 ID of the new owner
- */
- function resetOwner(bytes32 newOwner) external;
-
- /**
- * @notice Adds multiple new owners to the system
- * @param owners An array of bytes32 IDs representing the owners to be added
- */
- function addOwners(bytes32[] calldata owners) external;
-
- /**
- * @notice Resets the entire owner set, replacing it with a new set of owners
- * @param newOwners An array of bytes32 IDs representing the new set of owners
- */
- function resetOwners(bytes32[] calldata newOwners) external;
-
- /**
- * @notice Provides a list of all added owners
- * @return owners An array of bytes32 IDs representing the owners
- */
- function listOwner() external view returns (bytes32[] memory owners);
-}
diff --git a/contracts/interfaces/IPlugin.sol b/contracts/interfaces/IPlugin.sol
deleted file mode 100644
index 8a14d49a..00000000
--- a/contracts/interfaces/IPlugin.sol
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "@account-abstraction/contracts/interfaces/UserOperation.sol";
-import "./IPluggable.sol";
-
-/**
- * @title Plugin Interface
- * @dev This interface provides functionalities for hooks and interactions of plugins within a wallet or contract
- */
-interface IPlugin is IPluggable {
- /**
- * @notice Specifies the types of hooks a plugin supports
- * @return hookType An 8-bit value where:
- * - GuardHook is represented by 1<<0
- * - PreHook is represented by 1<<1
- * - PostHook is represented by 1<<2
- */
- function supportsHook() external pure returns (uint8 hookType);
-
- /**
- * @notice A hook that guards the user operation
- * @dev For security, plugins should revert when they do not need guardData but guardData.length > 0
- * @param userOp The user operation being performed
- * @param userOpHash The hash of the user operation
- * @param guardData Additional data for the guard
- */
- function guardHook(UserOperation calldata userOp, bytes32 userOpHash, bytes calldata guardData) external;
-
- /**
- * @notice A hook that's executed before the actual operation
- * @param target The target address of the operation
- * @param value The amount of ether (in wei) involved in the operation
- * @param data The calldata for the operation
- */
- function preHook(address target, uint256 value, bytes calldata data) external;
-
- /**
- * @notice A hook that's executed after the actual operation
- * @param target The target address of the operation
- * @param value The amount of ether (in wei) involved in the operation
- * @param data The calldata for the operation
- */
- function postHook(address target, uint256 value, bytes calldata data) external;
-}
diff --git a/contracts/interfaces/IPluginManager.sol b/contracts/interfaces/IPluginManager.sol
deleted file mode 100644
index a67c0cc2..00000000
--- a/contracts/interfaces/IPluginManager.sol
+++ /dev/null
@@ -1,40 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "./IPlugin.sol";
-
-/**
- * @title Plugin Manager Interface
- * @dev This interface provides functionalities for adding, removing, and querying plugins
- */
-interface IPluginManager {
- event PluginAdded(address indexed plugin);
- event PluginRemoved(address indexed plugin);
- event PluginRemovedWithError(address indexed plugin);
-
- /**
- * @notice Add a new plugin along with its initialization data
- * @param pluginAndData The plugin address concatenated with its initialization data
- */
- function addPlugin(bytes calldata pluginAndData) external;
-
- /**
- * @notice Remove a plugin from the system
- * @param plugin The address of the plugin to be removed
- */
- function removePlugin(address plugin) external;
-
- /**
- * @notice Checks if a plugin is authorized
- * @param plugin The address of the plugin to check
- * @return True if the plugin is authorized, otherwise false
- */
- function isAuthorizedPlugin(address plugin) external returns (bool);
-
- /**
- * @notice List all plugins of a specific hook type
- * @param hookType The type of the hook for which to list plugins
- * @return plugins An array of plugin addresses corresponding to the hookType
- */
- function listPlugin(uint8 hookType) external view returns (address[] memory plugins);
-}
diff --git a/contracts/interfaces/IPluginStorage.sol b/contracts/interfaces/IPluginStorage.sol
deleted file mode 100644
index da94f01b..00000000
--- a/contracts/interfaces/IPluginStorage.sol
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-/**
- * @title Plugin Storage Interface
- * @dev This interface defines the functionalities to store and load data for plugins
- */
-interface IPluginStorage {
- /**
- * @notice Store data for a plugin
- * @param key The key under which the value should be stored
- * @param value The value to be stored
- */
- function pluginDataStore(bytes32 key, bytes calldata value) external;
-
- /**
- * @notice Load data for a specific plugin using a key
- * @param plugin The address of the plugin for which data should be loaded
- * @param key The key under which the data is stored
- * @return The data stored under the given key for the specified plugin
- */
- function pluginDataLoad(address plugin, bytes32 key) external view returns (bytes memory);
-}
diff --git a/contracts/interfaces/ISoulWallet.sol b/contracts/interfaces/ISoulWallet.sol
index 28696a65..885e97cd 100644
--- a/contracts/interfaces/ISoulWallet.sol
+++ b/contracts/interfaces/ISoulWallet.sol
@@ -1,26 +1,24 @@
-// SPDX-License-Identifier: GPL-3.0
+// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
-import "./IExecutionManager.sol";
-import "./IModuleManager.sol";
-import "./IOwnerManager.sol";
-import "./IPluginManager.sol";
-import "./IFallbackManager.sol";
-import "@account-abstraction/contracts/interfaces/IAccount.sol";
-import "./IUpgradable.sol";
+import {ISoulWalletHookManager} from "../interfaces/ISoulWalletHookManager.sol";
+import {ISoulWalletModuleManager} from "../interfaces/ISoulWalletModuleManager.sol";
+import {ISoulWalletOwnerManager} from "../interfaces/ISoulWalletOwnerManager.sol";
+import {ISoulWalletOwnerManager} from "../interfaces/ISoulWalletOwnerManager.sol";
+import {IUpgradable} from "../interfaces/IUpgradable.sol";
+import {IStandardExecutor} from "@soulwallet-core/contracts/interface/IStandardExecutor.sol";
-/**
- * @title SoulWallet Interface
- * @dev This interface aggregates multiple sub-interfaces to represent the functionalities of the SoulWallet
- * It encompasses account management, execution management, module management, owner management, plugin management,
- * fallback management, and upgradeability
- */
interface ISoulWallet is
- IAccount,
- IExecutionManager,
- IModuleManager,
- IOwnerManager,
- IPluginManager,
- IFallbackManager,
+ ISoulWalletHookManager,
+ ISoulWalletModuleManager,
+ ISoulWalletOwnerManager,
+ IStandardExecutor,
IUpgradable
-{}
+{
+ function initialize(
+ bytes32[] calldata owners,
+ address defalutCallbackHandler,
+ bytes[] calldata modules,
+ bytes[] calldata hooks
+ ) external;
+}
diff --git a/contracts/interfaces/ISoulWalletHookManager.sol b/contracts/interfaces/ISoulWalletHookManager.sol
new file mode 100644
index 00000000..dbef479e
--- /dev/null
+++ b/contracts/interfaces/ISoulWalletHookManager.sol
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IHookManager} from "@soulwallet-core/contracts/interface/IHookManager.sol";
+
+interface ISoulWalletHookManager is IHookManager {
+ function installHook(bytes calldata hookAndData, uint8 capabilityFlags) external;
+}
diff --git a/contracts/interfaces/ISoulWalletModuleManager.sol b/contracts/interfaces/ISoulWalletModuleManager.sol
new file mode 100644
index 00000000..80cc1124
--- /dev/null
+++ b/contracts/interfaces/ISoulWalletModuleManager.sol
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IModuleManager} from "@soulwallet-core/contracts/interface/IModuleManager.sol";
+
+interface ISoulWalletModuleManager is IModuleManager {
+ function installModule(bytes calldata moduleAndData) external;
+}
diff --git a/contracts/interfaces/ISoulWalletOwnerManager.sol b/contracts/interfaces/ISoulWalletOwnerManager.sol
new file mode 100644
index 00000000..c391cbab
--- /dev/null
+++ b/contracts/interfaces/ISoulWalletOwnerManager.sol
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+import {IOwnerManager} from "@soulwallet-core/contracts/interface/IOwnerManager.sol";
+interface ISoulWalletOwnerManager is IOwnerManager {
+ function addOwners(bytes32[] calldata owners) external;
+ function resetOwners(bytes32[] calldata newOwners) external;
+}
diff --git a/contracts/interfaces/ISoulWalletValidatorManager.sol b/contracts/interfaces/ISoulWalletValidatorManager.sol
new file mode 100644
index 00000000..606160e6
--- /dev/null
+++ b/contracts/interfaces/ISoulWalletValidatorManager.sol
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IValidatorManager} from "@soulwallet-core/contracts/interface/IValidatorManager.sol";
+
+interface ISoulWalletValidatorManager is IValidatorManager {
+ function installValidator(bytes calldata validatorAndData) external;
+}
diff --git a/contracts/interfaces/IValidator.sol b/contracts/interfaces/IValidator.sol
deleted file mode 100644
index 5bb35675..00000000
--- a/contracts/interfaces/IValidator.sol
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-/**
- * @title Validator Interface
- * @dev This interface defines the functionalities for signature validation and hash encoding
- */
-interface IValidator {
- /**
- * @dev Recover the signer of a given raw hash using the provided raw signature
- * @param rawHash The raw hash that was signed
- * @param rawSignature The signature data
- * @return validationData same as defined in EIP4337
- * @return recovered The recovered signer's signing key from the signature
- * @return success A boolean indicating the success of the recovery
- */
- function recoverSignature(bytes32 rawHash, bytes calldata rawSignature)
- external
- view
- returns (uint256 validationData, bytes32 recovered, bool success);
-
- /**
- * @dev Recover the signer of a given raw hash using the provided raw signature according to EIP-1271 standards
- * @param rawHash The raw hash that was signed
- * @param rawSignature The signature data
- * @return validationData same as defined in EIP4337
- * @return recovered The recovered signer's signing key from the signature
- * @return success A boolean indicating the success of the recovery
- */
- function recover1271Signature(bytes32 rawHash, bytes calldata rawSignature)
- external
- view
- returns (uint256 validationData, bytes32 recovered, bool success);
-
- /**
- * @dev Encode a raw hash to prevent replay attacks
- * @param rawHash The raw hash to encode
- * @return The encoded hash
- */
- function encodeRawHash(bytes32 rawHash) external view returns (bytes32);
-}
diff --git a/contracts/interfaces/IValidatorManager.sol b/contracts/interfaces/IValidatorManager.sol
deleted file mode 100644
index 48cd1da6..00000000
--- a/contracts/interfaces/IValidatorManager.sol
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "./IValidator.sol";
-
-/**
- * @title Validator Manager Interface
- * @dev This interface provides a method to retrieve the active validator instance
- */
-interface IValidatorManager {
- /**
- * @dev Returns the current active validator instance
- * @return The active validator instance
- */
- function validator() external view returns (IValidator);
-}
diff --git a/contracts/keystore/L1/KeyStore.sol b/contracts/keystore/L1/KeyStore.sol
index ba7ef075..51e0bc13 100644
--- a/contracts/keystore/L1/KeyStore.sol
+++ b/contracts/keystore/L1/KeyStore.sol
@@ -1,15 +1,15 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;
-import "./BaseKeyStore.sol";
-import "../interfaces/IKeyStoreProof.sol";
+import "./base/BaseKeyStore.sol";
+import {IKeyStoreProof} from "../interfaces/IKeyStoreProof.sol";
import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/interfaces/IERC1271.sol";
-import "../../base/ValidatorManager.sol";
+import "./base/BaseKeyStoreValidatorManager.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
-contract KeyStore is IKeyStoreProof, EIP712, BaseKeyStore, ValidatorManager, Ownable {
+contract KeyStore is IKeyStoreProof, EIP712, BaseKeyStore, BaseKeyStoreValidatorManager, Ownable {
using ECDSA for bytes32;
IKeyStoreStorage private immutable _KEYSTORE_STORAGE;
@@ -36,9 +36,9 @@ contract KeyStore is IKeyStoreProof, EIP712, BaseKeyStore, ValidatorManager, Own
bytes32 private constant _TYPE_HASH_UPGRADE_KEYSTORE_LOGIC =
keccak256("KeyStoreUpgrade(bytes32 keyStoreSlot,uint256 nonce,address newLogic)");
- constructor(IValidator _validator, IKeyStoreStorage _keystorStorage, address _owner)
+ constructor(IKeyStoreValidator _validator, IKeyStoreStorage _keystorStorage, address _owner)
EIP712("KeyStore", "1")
- ValidatorManager(_validator)
+ BaseKeyStoreValidatorManager(_validator)
Ownable(_owner)
{
_KEYSTORE_STORAGE = _keystorStorage;
@@ -115,7 +115,7 @@ contract KeyStore is IKeyStoreProof, EIP712, BaseKeyStore, ValidatorManager, Own
bytes32 digest = _verifyStructHash(slot, slotNonce, action, data);
- (, bytes32 recovered, bool success) = validator().recoverSignature(digest, keySignature);
+ (bytes32 recovered, bool success) = validator().recoverSignature(digest, keySignature);
if (!success) {
revert Errors.INVALID_SIGNATURE();
}
@@ -132,7 +132,7 @@ contract KeyStore is IKeyStoreProof, EIP712, BaseKeyStore, ValidatorManager, Own
}
}
- function keystoreBySlot(bytes32 l1Slot) external view override returns (bytes32 signingKeyHash) {
+ function keyStoreBySlot(bytes32 l1Slot) external view override returns (bytes32 signingKeyHash) {
return _getKey(l1Slot);
}
@@ -242,97 +242,95 @@ contract KeyStore is IKeyStoreProof, EIP712, BaseKeyStore, ValidatorManager, Own
If, in certain cases, 's' is defined as bytes4 (up to 4GB), there is no need to perform overflow prevention under the current known block gas limit.
Overall, it is more suitable for both Layer1 and Layer2.
*/
- {
- uint8 v;
- uint256 cursor = 0;
-
- uint256 skipCount = 0;
- uint256 guardianSignatureLen = guardianSignature.length;
- for (uint256 i = 0; i < guardiansLen;) {
- if (cursor >= guardianSignatureLen) break;
- bytes calldata signatures = guardianSignature[cursor:];
- assembly ("memory-safe") {
- v := byte(0, calldataload(signatures.offset))
- }
+ uint8 v;
+ uint256 cursor = 0;
+
+ uint256 skipCount = 0;
+ uint256 guardianSignatureLen = guardianSignature.length;
+ for (uint256 i = 0; i < guardiansLen;) {
+ if (cursor >= guardianSignatureLen) break;
+ bytes calldata signatures = guardianSignature[cursor:];
+ assembly ("memory-safe") {
+ v := byte(0, calldataload(signatures.offset))
+ }
- if (v == 0) {
- /*
+ if (v == 0) {
+ /*
v = 0
EIP-1271 signature
s: bytes4 Length of signature data
r: no set
dynamic data: signature data
*/
- uint256 cursorEnd;
- assembly ("memory-safe") {
- // read 's' as bytes4
- let sigLen := shr(224, calldataload(add(signatures.offset, 1)))
-
- cursorEnd := add(5, sigLen) // see Note line 223
- cursor := add(cursor, cursorEnd)
- }
-
- bytes calldata dynamicData = signatures[5:cursorEnd];
- {
- (bool success, bytes memory result) = guardianData.guardians[i].staticcall(
- abi.encodeWithSelector(IERC1271.isValidSignature.selector, digest, dynamicData)
- );
- require(
- success && result.length == 32
- && abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector),
- "contract signature invalid"
- );
- }
- } else if (v == 1) {
- /*
+ uint256 cursorEnd;
+ assembly ("memory-safe") {
+ // read 's' as bytes4
+ let sigLen := shr(224, calldataload(add(signatures.offset, 1)))
+
+ cursorEnd := add(5, sigLen) // see Note line 223
+ cursor := add(cursor, cursorEnd)
+ }
+
+ bytes calldata dynamicData = signatures[5:cursorEnd];
+ {
+ (bool success, bytes memory result) = guardianData.guardians[i].staticcall(
+ abi.encodeWithSelector(IERC1271.isValidSignature.selector, digest, dynamicData)
+ );
+ require(
+ success && result.length == 32
+ && abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector),
+ "contract signature invalid"
+ );
+ }
+ } else if (v == 1) {
+ /*
v = 1
approved hash
r: no set
s: no set
*/
- bytes32 key = _approveKey(guardianData.guardians[i], digest);
- require(approvedHashes[key] == 1, "hash not approved");
- unchecked {
- cursor += 1; // see Note line 223
- }
- } else if (v == 2) {
- /*
+ bytes32 key = _approveKey(guardianData.guardians[i], digest);
+ require(approvedHashes[key] == 1, "hash not approved");
+ unchecked {
+ cursor += 1; // see Note line 223
+ }
+ } else if (v == 2) {
+ /*
v = 2
skip
s: bytes4 skip times
r: no set
*/
- assembly ("memory-safe") {
- // read 's' as bytes4
- let skipTimes := shr(224, calldataload(add(signatures.offset, 1)))
-
- i := add(i, skipTimes) // see Note line 223
- skipCount := add(skipCount, add(skipTimes, 1))
- cursor := add(cursor, 5)
- }
- } else {
- /*
+ assembly ("memory-safe") {
+ // read 's' as bytes4
+ let skipTimes := shr(224, calldataload(add(signatures.offset, 1)))
+
+ i := add(i, skipTimes) // see Note line 223
+ skipCount := add(skipCount, add(skipTimes, 1))
+ cursor := add(cursor, 5)
+ }
+ } else {
+ /*
v > 2
EOA signature
*/
- bytes32 s;
- bytes32 r;
- assembly ("memory-safe") {
- s := calldataload(add(signatures.offset, 1))
- r := calldataload(add(signatures.offset, 33))
-
- cursor := add(cursor, 65) // see Note line 223
- }
- require(guardianData.guardians[i] == ECDSA.recover(digest, v, r, s), "guardian signature invalid");
- }
- unchecked {
- i++; // see Note line 223
+ bytes32 s;
+ bytes32 r;
+ assembly ("memory-safe") {
+ s := calldataload(add(signatures.offset, 1))
+ r := calldataload(add(signatures.offset, 33))
+
+ cursor := add(cursor, 65) // see Note line 223
}
+ require(guardianData.guardians[i] == ECDSA.recover(digest, v, r, s), "guardian signature invalid");
}
- if (guardiansLen - skipCount < guardianData.threshold) {
- revert Errors.GUARDIAN_SIGNATURE_INVALID();
+ unchecked {
+ i++; // see Note line 223
}
}
+ if (guardiansLen - skipCount < guardianData.threshold) {
+ revert Errors.GUARDIAN_SIGNATURE_INVALID();
+ }
}
function keyStoreStorage() public view virtual override returns (IKeyStoreStorage) {
diff --git a/contracts/keystore/L1/KeyStoreStorage.sol b/contracts/keystore/L1/KeyStoreStorage.sol
index c894c328..15ac795a 100644
--- a/contracts/keystore/L1/KeyStoreStorage.sol
+++ b/contracts/keystore/L1/KeyStoreStorage.sol
@@ -2,8 +2,7 @@
pragma solidity ^0.8.20;
import "./interfaces/IKeyStoreStorage.sol";
-import "./interfaces/IMerkelTree.sol";
-import "./BaseMerkelTree.sol";
+import "./base/BaseMerkleTree.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
@@ -11,7 +10,7 @@ import "@openzeppelin/contracts/access/Ownable.sol";
* @dev Implements the eternal storage pattern. Provides generic storage capabilities
* and integrates with a Merkle Tree structure.
*/
-contract KeyStoreStorage is IKeyStoreStorage, IMerkleTree, Ownable, BaseMerkleTree {
+contract KeyStoreStorage is IKeyStoreStorage, Ownable, BaseMerkleTree {
// Mapping structure for various data types
// slot ->key-> value
mapping(bytes32 => mapping(bytes32 => string)) private stringStorage;
diff --git a/contracts/keystore/L1/BaseKeyStore.sol b/contracts/keystore/L1/base/BaseKeyStore.sol
similarity index 98%
rename from contracts/keystore/L1/BaseKeyStore.sol
rename to contracts/keystore/L1/base/BaseKeyStore.sol
index acd81467..eca6cd99 100644
--- a/contracts/keystore/L1/BaseKeyStore.sol
+++ b/contracts/keystore/L1/base/BaseKeyStore.sol
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;
-import "./KeyStoreAdapter.sol";
-import "../../libraries/KeyStoreSlotLib.sol";
+import "./BaseKeyStoreAdapter.sol";
+import "../../../libraries/KeyStoreSlotLib.sol";
-abstract contract BaseKeyStore is IKeyStore, KeyStoreAdapter {
+abstract contract BaseKeyStore is IKeyStore, BaseKeyStoreAdapter {
/**
* @notice Verify the signature of the `signKey`
* @dev Implementers must revert if the signature is invalid
@@ -176,6 +176,7 @@ abstract contract BaseKeyStore is IKeyStore, KeyStoreAdapter {
_verifySignature(slot, signKey, Action.SET_KEY, newKey, currentRawOwners, keySignature);
_saveKey(slot, newKey);
_storeRawOwnerBytes(slot, newRawOwners);
+ _insertLeaf(slot, newKey);
}
/**
@@ -239,6 +240,7 @@ abstract contract BaseKeyStore is IKeyStore, KeyStoreAdapter {
_verifyGuardianSignature(slot, rawGuardian, newKey, guardianSignature);
_saveKey(slot, newKey);
_storeRawOwnerBytes(slot, newRawOwners);
+ _insertLeaf(slot, newKey);
}
/**
@@ -260,6 +262,7 @@ abstract contract BaseKeyStore is IKeyStore, KeyStoreAdapter {
_verifyGuardianSignature(slot, rawGuardian, newKey, guardianSignature);
_saveKey(slot, newKey);
_storeRawOwnerBytes(slot, newRawOwners);
+ _insertLeaf(slot, newKey);
}
/**
diff --git a/contracts/keystore/L1/KeyStoreAdapter.sol b/contracts/keystore/L1/base/BaseKeyStoreAdapter.sol
similarity index 96%
rename from contracts/keystore/L1/KeyStoreAdapter.sol
rename to contracts/keystore/L1/base/BaseKeyStoreAdapter.sol
index 1590ab08..e00fc101 100644
--- a/contracts/keystore/L1/KeyStoreAdapter.sol
+++ b/contracts/keystore/L1/base/BaseKeyStoreAdapter.sol
@@ -1,16 +1,16 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;
-import "./interfaces/IKeyStoreStorage.sol";
-import "./interfaces/IKeyStore.sol";
-import "../../libraries/Errors.sol";
+import "../interfaces/IKeyStoreStorage.sol";
+import "../interfaces/IKeyStore.sol";
+import "../../../libraries/Errors.sol";
/**
- * @title KeyStoreAdapter
+ * @title BaseKeyStoreAdapter
* @dev A contract that provides a set of utility functions to interact with a keystore
*/
-abstract contract KeyStoreAdapter is IKeyStore {
- uint256 internal constant _GUARDIAN_PERIOD_MIN = 2 days;
+abstract contract BaseKeyStoreAdapter is IKeyStore {
+ uint256 internal constant _GUARDIAN_PERIOD_MIN = 1 seconds;
uint256 internal constant _GUARDIAN_PERIOD_MAX = 30 days;
/**
* @dev Returns the current instance of the KeyStoreStorage
@@ -58,6 +58,11 @@ abstract contract KeyStoreAdapter is IKeyStore {
emit KeyChanged(slot, key);
}
+ function _insertLeaf(bytes32 slot, bytes32 key) internal {
+ _keyGuard(key);
+ keyStoreStorage().insertLeaf(slot, key);
+ }
+
/**
* @dev Fetches the signing key hash stored in a given slot
* @param slot The slot from which to fetch the signing key hash
diff --git a/contracts/keystore/L1/base/BaseKeyStoreValidatorManager.sol b/contracts/keystore/L1/base/BaseKeyStoreValidatorManager.sol
new file mode 100644
index 00000000..145212f4
--- /dev/null
+++ b/contracts/keystore/L1/base/BaseKeyStoreValidatorManager.sol
@@ -0,0 +1,16 @@
+
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+import "../interfaces/IKeyStoreValidatorManager.sol";
+
+
+abstract contract BaseKeyStoreValidatorManager is IKeyStoreValidatorManager {
+ IKeyStoreValidator private immutable _VALIDATOR;
+ constructor(IKeyStoreValidator aValidator) {
+ _VALIDATOR = aValidator;
+ }
+ function validator() public view override returns (IKeyStoreValidator) {
+ return _VALIDATOR;
+ }
+}
diff --git a/contracts/keystore/L1/BaseMerkelTree.sol b/contracts/keystore/L1/base/BaseMerkleTree.sol
similarity index 83%
rename from contracts/keystore/L1/BaseMerkelTree.sol
rename to contracts/keystore/L1/base/BaseMerkleTree.sol
index 639ab41c..3be93bb4 100644
--- a/contracts/keystore/L1/BaseMerkelTree.sol
+++ b/contracts/keystore/L1/base/BaseMerkleTree.sol
@@ -3,7 +3,7 @@ pragma solidity ^0.8.20;
/**
* @title Interface for KeyStore Merkle Proof
*/
-interface IKeyStoreMerkelProof {
+interface IKeyStoreMerkleProof {
/**
* @notice Gets the merkle root of the tree
* @return The merkle root
@@ -20,7 +20,7 @@ interface IKeyStoreMerkelProof {
* @title Implementation of a Merkle Tree structure
* @dev This contract allows for the construction of a merkle tree based on the Ethereum 2.0 deposit contract
*/
-abstract contract BaseMerkleTree is IKeyStoreMerkelProof {
+abstract contract BaseMerkleTree is IKeyStoreMerkleProof {
uint256 constant CONTRACT_TREE_DEPTH = 32;
uint256 constant MAX_COUNT = 2 ** CONTRACT_TREE_DEPTH - 1;
@@ -36,7 +36,7 @@ abstract contract BaseMerkleTree is IKeyStoreMerkelProof {
*/
constructor() {
for (uint256 height = 0; height < CONTRACT_TREE_DEPTH - 1; height++) {
- zero_hashes[height + 1] = sha256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));
+ zero_hashes[height + 1] = keccak256(abi.encodePacked(zero_hashes[height], zero_hashes[height]));
}
}
/**
@@ -49,9 +49,9 @@ abstract contract BaseMerkleTree is IKeyStoreMerkelProof {
uint256 size = leaf_count;
for (uint256 height = 0; height < CONTRACT_TREE_DEPTH; height++) {
if ((size & 1) == 1) {
- node = sha256(abi.encodePacked(branch[height], node));
+ node = keccak256(abi.encodePacked(branch[height], node));
} else {
- node = sha256(abi.encodePacked(node, zero_hashes[height]));
+ node = keccak256(abi.encodePacked(node, zero_hashes[height]));
}
size /= 2;
}
@@ -81,7 +81,7 @@ abstract contract BaseMerkleTree is IKeyStoreMerkelProof {
function _insertLeaf(bytes32 slot, bytes32 signingKeyHash) internal {
require(leaf_count < MAX_COUNT, "merkle tree full");
- bytes32 node = sha256(abi.encodePacked(slot, signingKeyHash, block.number));
+ bytes32 node = keccak256(abi.encodePacked(slot, signingKeyHash, block.number));
emit newLeaf(slot, signingKeyHash, block.number, node, leaf_count);
leaf_count += 1;
@@ -91,7 +91,7 @@ abstract contract BaseMerkleTree is IKeyStoreMerkelProof {
branch[height] = node;
return;
}
- node = sha256(abi.encodePacked(branch[height], node));
+ node = keccak256(abi.encodePacked(branch[height], node));
size /= 2;
}
}
diff --git a/contracts/keystore/L1/interfaces/IKeyStoreStorage.sol b/contracts/keystore/L1/interfaces/IKeyStoreStorage.sol
index fb60ae8c..c9280562 100644
--- a/contracts/keystore/L1/interfaces/IKeyStoreStorage.sol
+++ b/contracts/keystore/L1/interfaces/IKeyStoreStorage.sol
@@ -21,4 +21,5 @@ interface IKeyStoreStorage {
function setBytes32(bytes32 _slot, bytes32 _key, bytes32 _value) external;
function setSlotValue(bytes32 _slot, bytes32 _value) external;
function setKeystoreLogic(bytes32 _slot, address _logicAddress) external;
+ function insertLeaf(bytes32 _slot, bytes32 _signingKey) external;
}
diff --git a/contracts/keystore/L1/interfaces/IKeyStoreValidator.sol b/contracts/keystore/L1/interfaces/IKeyStoreValidator.sol
new file mode 100644
index 00000000..a9a29ffb
--- /dev/null
+++ b/contracts/keystore/L1/interfaces/IKeyStoreValidator.sol
@@ -0,0 +1,21 @@
+
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+/**
+ * @title Validator Interface
+ * @dev This interface defines the functionalities for signature validation and hash encoding
+ */
+interface IKeyStoreValidator {
+ /**
+ * @dev Recover the signer of a given raw hash using the provided raw signature
+ * @param rawHash The raw hash that was signed
+ * @param rawSignature The signature data
+ * @return recovered The recovered signer's signing key from the signature
+ * @return success A boolean indicating the success of the recovery
+ */
+ function recoverSignature(bytes32 rawHash, bytes calldata rawSignature)
+ external
+ view
+ returns (bytes32 recovered, bool success);
+}
diff --git a/contracts/keystore/L1/interfaces/IKeyStoreValidatorManager.sol b/contracts/keystore/L1/interfaces/IKeyStoreValidatorManager.sol
new file mode 100644
index 00000000..8bfe2cf1
--- /dev/null
+++ b/contracts/keystore/L1/interfaces/IKeyStoreValidatorManager.sol
@@ -0,0 +1,8 @@
+
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+import "./IKeyStoreValidator.sol";
+
+interface IKeyStoreValidatorManager {
+ function validator() external view returns (IKeyStoreValidator);
+}
diff --git a/contracts/keystore/L1/interfaces/IMerkelTree.sol b/contracts/keystore/L1/interfaces/IMerkleTree.sol
similarity index 100%
rename from contracts/keystore/L1/interfaces/IMerkelTree.sol
rename to contracts/keystore/L1/interfaces/IMerkleTree.sol
diff --git a/contracts/keystore/interfaces/IKeyStoreProof.sol b/contracts/keystore/interfaces/IKeyStoreProof.sol
index ecf580dd..43b10fa9 100644
--- a/contracts/keystore/interfaces/IKeyStoreProof.sol
+++ b/contracts/keystore/interfaces/IKeyStoreProof.sol
@@ -11,7 +11,7 @@ interface IKeyStoreProof {
* @param l1Slot The L1 slot
* @return signingKeyHash The hash of the signing key associated with the L1 slot
*/
- function keystoreBySlot(bytes32 l1Slot) external view returns (bytes32 signingKeyHash);
+ function keyStoreBySlot(bytes32 l1Slot) external view returns (bytes32 signingKeyHash);
/**
* @dev Returns the raw owners associated with a given L1 slot.
diff --git a/contracts/libraries/AccountStorage.sol b/contracts/libraries/AccountStorage.sol
deleted file mode 100644
index c003a0ce..00000000
--- a/contracts/libraries/AccountStorage.sol
+++ /dev/null
@@ -1,55 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "@account-abstraction/contracts/interfaces/IEntryPoint.sol";
-
-/**
- * @title AccountStorage
- * @notice A library that defines the storage layout for the SoulWallet account or contract.
- */
-library AccountStorage {
- bytes32 private constant _ACCOUNT_SLOT = keccak256("soulwallet.contracts.AccountStorage");
-
- struct Layout {
- // ┌───────────────────┐
- // │ base data │
- mapping(bytes32 => bytes32) owners;
- address defaultFallbackContract;
- uint256[50] __gap_0;
- // └───────────────────┘
-
- // ┌───────────────────┐
- // │ EIP1271 │
- mapping(bytes32 => uint256) approvedHashes;
- uint256[50] __gap_1;
- // └───────────────────┘
-
- // ┌───────────────────┐
- // │ Module │
- mapping(address => address) modules;
- mapping(address => mapping(bytes4 => bytes4)) moduleSelectors;
- uint256[50] __gap_2;
- // └───────────────────┘
-
- // ┌───────────────────┐
- // │ Plugin │
- mapping(address => address) plugins;
- mapping(address => address) guardHookPlugins;
- mapping(address => address) preHookPlugins;
- mapping(address => address) postHookPlugins;
- mapping(address => mapping(bytes32 => bytes)) pluginDataBytes;
- uint256[50] __gap_3;
- }
- // └───────────────────┘
-
- /**
- * @notice Returns the layout of the storage for the account or contract.
- * @return l The layout of the storage.
- */
- function layout() internal pure returns (Layout storage l) {
- bytes32 slot = _ACCOUNT_SLOT;
- assembly ("memory-safe") {
- l.slot := slot
- }
- }
-}
diff --git a/contracts/libraries/Errors.sol b/contracts/libraries/Errors.sol
index d42533ac..e926df79 100644
--- a/contracts/libraries/Errors.sol
+++ b/contracts/libraries/Errors.sol
@@ -21,13 +21,6 @@ library Errors {
error MODULE_SELECTORS_EMPTY();
error MODULE_EXECUTE_FROM_MODULE_RECURSIVE();
error NO_OWNER();
- error PLUGIN_ADDRESS_EMPTY();
- error PLUGIN_HOOK_TYPE_ERROR();
- error PLUGIN_INIT_FAILED();
- error PLUGIN_NOT_SUPPORT_INTERFACE();
- error PLUGIN_POST_HOOK_FAILED();
- error PLUGIN_PRE_HOOK_FAILED();
- error PLUGIN_NOT_REGISTERED();
error SELECTOR_ALREADY_EXISTS();
error SELECTOR_NOT_EXISTS();
error UNSUPPORTED_SIGNTYPE();
diff --git a/contracts/libraries/SignatureDecoder.sol b/contracts/libraries/SignatureDecoder.sol
deleted file mode 100644
index 23c0a4e3..00000000
--- a/contracts/libraries/SignatureDecoder.sol
+++ /dev/null
@@ -1,111 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../libraries/Errors.sol";
-
-library SignatureDecoder {
- /*
- signature format
-
- +-----------------------------------------------------------------------------------------------------+
- | | |
- | | validator signature |
- | | |
- +---------------+---------------------------+--------------------------+-----------------------------+
- | data type | data type dynamic data | signature type | signature data |
- +---------------+---------------------------+--------------------------+-----------------------------+
- | | | | |
- | 1 byte | .......... | 1 byte | ...... |
- | | | | |
- +-----------------------------------------------------------------------------------------------------+
-
-
- A: data type 0: no plugin data
- +-----------------------------------------------------------------------------------------------------+
- | | |
- | | validator signature |
- | | |
- +---------------+---------------------------+--------------------------+-----------------------------+
- | data type | data type dynamic data | signature type | signature data |
- +---------------+---------------------------+--------------------------+-----------------------------+
- | | | | |
- | 0x00 | empty bytes | 1 byte | ...... |
- | | | | |
- +-----------------------------------------------------------------------------------------------------+
-
-
-
-
- B: data type 1: plugin data
-
- +-----------------------------------------------------------------------------------------------------+
- | | |
- | | validator signature |
- | | |
- +---------------+---------------------------+--------------------------+-----------------------------+
- | data type | data type dynamic data | signature type | signature data |
- +---------------+---------------------------+--------------------------+-----------------------------+
- | | | | |
- | 0x01 | ............. | 1 byte | ...... |
- | | | | |
- +-----------------------------------------------------------------------------------------------------+
-
-
-
- +-------------------------+-------------------------------------+
- | |
- | data type dynamic data |
- | |
- +-------------------------+-------------------------------------+
- | dynamic data length | multi-guardHookInputData |
- +-------------------------+-------------------------------------+
- | uint256 32 bytes | dynamic data without length header |
- +-------------------------+-------------------------------------+
-
-
- +--------------------------------------------------------------------------------+
- | multi-guardHookInputData |
- +--------------------------------------------------------------------------------+
- | guardHookInputData | guardHookInputData | ... | guardHookInputData |
- +-----------------------+-----------------------+--------+-----------------------+
- | dynamic data | dynamic data | ... | dynamic data |
- +--------------------------------------------------------------------------------+
-
- +----------------------------------------------------------------------+
- | guardHookInputData |
- +----------------------------------------------------------------------+
- | guardHook address | input data length | input data |
- +----------------------+-----------------------+-----------------------+
- | 20bytes | 6bytes(uint48) | bytes |
- +----------------------------------------------------------------------+
-
- Note: The order of guardHookInputData must be the same as the order in PluginManager.guardHook()!
-
- */
-
- function decodeSignature(bytes calldata userOpsignature)
- internal
- pure
- returns (bytes calldata guardHookInputData, bytes calldata validatorSignature)
- {
- /*
- When the calldata slice doesn't match the actual length at the index,
- it will revert, so we don't need additional checks.
- */
-
- uint8 dataType = uint8(bytes1(userOpsignature[0:1]));
-
- if (dataType == 0x0) {
- // empty guardHookInputData
- guardHookInputData = userOpsignature[0:0];
- validatorSignature = userOpsignature[1:];
- } else if (dataType == 0x01) {
- uint256 dynamicDataLength = uint256(bytes32(userOpsignature[1:33]));
- uint256 validatorSignatureOffset = 33 + dynamicDataLength;
- guardHookInputData = userOpsignature[33:validatorSignatureOffset];
- validatorSignature = userOpsignature[validatorSignatureOffset:];
- } else {
- revert("Unsupported data type");
- }
- }
-}
diff --git a/contracts/libraries/WebAuthn.sol b/contracts/libraries/WebAuthn.sol
index 347bbe76..ed352150 100644
--- a/contracts/libraries/WebAuthn.sol
+++ b/contracts/libraries/WebAuthn.sol
@@ -1,3 +1,4 @@
+
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
diff --git a/contracts/modules/BaseModule.sol b/contracts/modules/BaseModule.sol
index 33d6e821..97e97056 100644
--- a/contracts/modules/BaseModule.sol
+++ b/contracts/modules/BaseModule.sol
@@ -1,16 +1,15 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;
-import "../interfaces/IModule.sol";
-import "../interfaces/ISoulWallet.sol";
-import "../interfaces/IModuleManager.sol";
+import "./interfaces/ISoulWalletModule.sol";
+import "./../interfaces/ISoulWallet.sol";
/**
* @title BaseModule
* @notice An abstract base contract that provides a foundation for other modules.
* It ensures the initialization, de-initialization, and proper authorization of modules.
*/
-abstract contract BaseModule is IModule {
+abstract contract BaseModule is ISoulWalletModule {
event ModuleInit(address indexed wallet);
event ModuleDeInit(address indexed wallet);
/**
@@ -42,10 +41,10 @@ abstract contract BaseModule is IModule {
* @param data Initialization data for the module.
*/
- function walletInit(bytes calldata data) external {
+ function Init(bytes calldata data) external {
address _sender = sender();
if (!inited(_sender)) {
- if (!ISoulWallet(_sender).isAuthorizedModule(address(this))) {
+ if (!ISoulWallet(_sender).isInstalledModule(address(this))) {
revert("not authorized module");
}
_init(data);
@@ -56,10 +55,10 @@ abstract contract BaseModule is IModule {
* @notice De-initializes the module for a wallet.
*/
- function walletDeInit() external {
+ function DeInit() external {
address _sender = sender();
if (inited(_sender)) {
- if (ISoulWallet(_sender).isAuthorizedModule(address(this))) {
+ if (ISoulWallet(_sender).isInstalledModule(address(this))) {
revert("authorized module");
}
_deInit();
@@ -73,6 +72,6 @@ abstract contract BaseModule is IModule {
*/
function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
- return interfaceId == type(IModule).interfaceId;
+ return interfaceId == type(ISoulWalletModule).interfaceId || interfaceId == type(IModule).interfaceId;
}
}
diff --git a/contracts/modules/SecurityControlModule/BaseSecurityControlModule.sol b/contracts/modules/SecurityControlModule/BaseSecurityControlModule.sol
index fa382b79..1eb72a95 100644
--- a/contracts/modules/SecurityControlModule/BaseSecurityControlModule.sol
+++ b/contracts/modules/SecurityControlModule/BaseSecurityControlModule.sol
@@ -1,15 +1,15 @@
+
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;
import "../BaseModule.sol";
import "./IBaseSecurityControlModule.sol";
-import "../../trustedContractManager/ITrustedContractManager.sol";
import "../../libraries/TypeConversion.sol";
// refer to: https://solidity-by-example.org/app/time-lock/
abstract contract BaseSecurityControlModule is IBaseSecurityControlModule, BaseModule {
- uint256 public constant MIN_DELAY = 1 days;
+ uint256 public constant MIN_DELAY = 1 seconds;
uint256 public constant MAX_DELAY = 14 days;
using TypeConversion for address;
diff --git a/contracts/modules/SecurityControlModule/SecurityControlModule.sol b/contracts/modules/SecurityControlModule/SecurityControlModule.sol
index 1739d28a..ac999b38 100644
--- a/contracts/modules/SecurityControlModule/SecurityControlModule.sol
+++ b/contracts/modules/SecurityControlModule/SecurityControlModule.sol
@@ -2,41 +2,58 @@
pragma solidity ^0.8.20;
import "./BaseSecurityControlModule.sol";
-import "../../trustedContractManager/ITrustedContractManager.sol";
-import "../../interfaces/IModuleManager.sol";
-import "../../interfaces/IPluginManager.sol";
+import "./trustedContractManager/ITrustedContractManager.sol";
+import {ISoulWalletHookManager} from "../../interfaces/ISoulWalletHookManager.sol";
+import {ISoulWalletModuleManager} from "../../interfaces/ISoulWalletModuleManager.sol";
+import {ISoulWalletValidatorManager} from "../../interfaces/ISoulWalletValidatorManager.sol";
+import {IHookManager} from "@soulwallet-core/contracts/interface/IHookManager.sol";
+import {IModuleManager} from "@soulwallet-core/contracts/interface/IModuleManager.sol";
+import {IValidatorManager} from "@soulwallet-core/contracts/interface/IValidatorManager.sol";
contract SecurityControlModule is BaseSecurityControlModule {
error UnsupportedSelectorError(bytes4 selector);
error RemoveSelfError();
ITrustedContractManager public immutable trustedModuleManager;
- ITrustedContractManager public immutable trustedPluginManager;
+ ITrustedContractManager public immutable trustedHookManager;
+ ITrustedContractManager public immutable trustedValidatorManager;
- constructor(ITrustedContractManager _trustedModuleManager, ITrustedContractManager _trustedPluginManager) {
+ constructor(
+ ITrustedContractManager _trustedModuleManager,
+ ITrustedContractManager _trustedHookManager,
+ ITrustedContractManager _trustedValidatorManager
+ ) {
trustedModuleManager = _trustedModuleManager;
- trustedPluginManager = _trustedPluginManager;
+ trustedHookManager = _trustedHookManager;
+ trustedValidatorManager = _trustedValidatorManager;
}
function _preExecute(address _target, bytes calldata _data, bytes32 _txId) internal override {
bytes4 _func = bytes4(_data[0:4]);
- if (_func == IModuleManager.addModule.selector) {
+ if (_func == ISoulWalletModuleManager.installModule.selector) {
address _module = address(bytes20(_data[68:88])); // 4 sig + 32 bytes + 32 bytes
if (!trustedModuleManager.isTrustedContract(_module)) {
super._preExecute(_target, _data, _txId);
}
- } else if (_func == IPluginManager.addPlugin.selector) {
- address _plugin = address(bytes20(_data[68:88])); // 4 sig + 32 bytes + 32 bytes
- if (!trustedPluginManager.isTrustedContract(_plugin)) {
+ } else if (_func == ISoulWalletHookManager.installHook.selector) {
+ address _hook = address(bytes20(_data[68:88])); // 4 sig + 32 bytes + 32 bytes
+ if (!trustedHookManager.isTrustedContract(_hook)) {
super._preExecute(_target, _data, _txId);
}
- } else if (_func == IModuleManager.removeModule.selector) {
+ } else if (_func == ISoulWalletValidatorManager.installValidator.selector) {
+ address _validator = address(bytes20(_data[68:88])); // 4 sig + 32 bytes + 32 bytes
+ if (!trustedValidatorManager.isTrustedContract(_validator)) {
+ super._preExecute(_target, _data, _txId);
+ }
+ } else if (_func == IModuleManager.uninstallModule.selector) {
(address _module) = abi.decode(_data[4:], (address));
if (_module == address(this)) {
revert RemoveSelfError();
}
super._preExecute(_target, _data, _txId);
- } else if (_func == IPluginManager.removePlugin.selector) {
+ } else if (_func == IHookManager.uninstallHook.selector) {
+ super._preExecute(_target, _data, _txId);
+ } else if (_func == IValidatorManager.uninstallValidator.selector) {
super._preExecute(_target, _data, _txId);
} else {
revert UnsupportedSelectorError(_func);
@@ -44,11 +61,13 @@ contract SecurityControlModule is BaseSecurityControlModule {
}
function requiredFunctions() external pure override returns (bytes4[] memory) {
- bytes4[] memory _funcs = new bytes4[](4);
- _funcs[0] = IModuleManager.addModule.selector;
- _funcs[1] = IPluginManager.addPlugin.selector;
- _funcs[2] = IModuleManager.removeModule.selector;
- _funcs[3] = IPluginManager.removePlugin.selector;
+ bytes4[] memory _funcs = new bytes4[](6);
+ _funcs[0] = ISoulWalletModuleManager.installModule.selector;
+ _funcs[1] = IModuleManager.uninstallModule.selector;
+ _funcs[2] = ISoulWalletHookManager.installHook.selector;
+ _funcs[3] = IHookManager.uninstallHook.selector;
+ _funcs[4] = ISoulWalletValidatorManager.installValidator.selector;
+ _funcs[5] = IValidatorManager.uninstallValidator.selector;
return _funcs;
}
}
diff --git a/contracts/trustedContractManager/ITrustedContractManager.sol b/contracts/modules/SecurityControlModule/trustedContractManager/ITrustedContractManager.sol
similarity index 100%
rename from contracts/trustedContractManager/ITrustedContractManager.sol
rename to contracts/modules/SecurityControlModule/trustedContractManager/ITrustedContractManager.sol
diff --git a/contracts/trustedContractManager/TrustedContractManager.sol b/contracts/modules/SecurityControlModule/trustedContractManager/TrustedContractManager.sol
similarity index 99%
rename from contracts/trustedContractManager/TrustedContractManager.sol
rename to contracts/modules/SecurityControlModule/trustedContractManager/TrustedContractManager.sol
index bbe33c00..66c78344 100644
--- a/contracts/trustedContractManager/TrustedContractManager.sol
+++ b/contracts/modules/SecurityControlModule/trustedContractManager/TrustedContractManager.sol
@@ -1,3 +1,4 @@
+
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;
diff --git a/contracts/trustedContractManager/trustedPluginManager/TrustedPluginManager.sol b/contracts/modules/SecurityControlModule/trustedContractManager/trustedHookManager/TrustedHookManager.sol
similarity index 74%
rename from contracts/trustedContractManager/trustedPluginManager/TrustedPluginManager.sol
rename to contracts/modules/SecurityControlModule/trustedContractManager/trustedHookManager/TrustedHookManager.sol
index e2673075..b4db588a 100644
--- a/contracts/trustedContractManager/trustedPluginManager/TrustedPluginManager.sol
+++ b/contracts/modules/SecurityControlModule/trustedContractManager/trustedHookManager/TrustedHookManager.sol
@@ -3,6 +3,6 @@ pragma solidity ^0.8.20;
import "../TrustedContractManager.sol";
-contract TrustedPluginManager is TrustedContractManager {
+contract TrustedHookManager is TrustedContractManager {
constructor(address _owner) TrustedContractManager(_owner) {}
}
diff --git a/contracts/trustedContractManager/trustedModuleManager/TrustedModuleManager.sol b/contracts/modules/SecurityControlModule/trustedContractManager/trustedModuleManager/TrustedModuleManager.sol
similarity index 100%
rename from contracts/trustedContractManager/trustedModuleManager/TrustedModuleManager.sol
rename to contracts/modules/SecurityControlModule/trustedContractManager/trustedModuleManager/TrustedModuleManager.sol
diff --git a/contracts/modules/SecurityControlModule/trustedContractManager/trustedValidatorManager/TrustedValidatorManager.sol b/contracts/modules/SecurityControlModule/trustedContractManager/trustedValidatorManager/TrustedValidatorManager.sol
new file mode 100644
index 00000000..1ac23c58
--- /dev/null
+++ b/contracts/modules/SecurityControlModule/trustedContractManager/trustedValidatorManager/TrustedValidatorManager.sol
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+import "../TrustedContractManager.sol";
+
+contract TrustedValidatorManager is TrustedContractManager {
+ constructor(address _owner) TrustedContractManager(_owner) {}
+}
diff --git a/contracts/modules/SocialRecoveryModule/ISocialRecoveryModule.sol b/contracts/modules/SocialRecoveryModule/ISocialRecoveryModule.sol
deleted file mode 100644
index 5cdf7b9a..00000000
--- a/contracts/modules/SocialRecoveryModule/ISocialRecoveryModule.sol
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-struct GuardianInfo {
- mapping(address => address) guardians;
- uint256 threshold;
- bytes32 guardianHash;
-}
-
-struct PendingGuardianEntry {
- uint256 pendingUntil;
- uint256 threshold;
- bytes32 guardianHash;
- address[] guardians;
-}
-
-struct RecoveryEntry {
- address[] newOwners;
- uint256 executeAfter;
- uint256 nonce;
-}
-
-// 1. changing guardians while already in recovery?
-// not allowed. recovery will block wallet
-// 2. recovery while already in chainging guardian?
-// will cancel the changing guardian
-
-interface ISocialRecoveryModule {
- event AnonymousGuardianRevealed(address indexed wallet, address[] indexed guardians, bytes32 guardianHash);
- event ApproveRecovery(address indexed wallet, address indexed guardian, bytes32 indexed recoveryHash);
- event PendingRecovery(address indexed _wallet, address[] indexed _newOwners, uint256 _nonce, uint256 executeAfter);
- event SocialRecovery(address indexed _wallet, address[] indexed _newOwners);
- event SocialRecoveryCanceled(address indexed _wallet, uint256 _nonce);
- // change guardians --> wait 2 day --> guardian changed
-
- function updateGuardians(address[] calldata _guardians, uint256 _threshold, bytes32 _guardianHash) external;
-
- function cancelSetGuardians(address _wallet) external; // owner or guardian
-
- function getGuardians(address _wallet) external returns (address[] memory);
-
- // init recovery --> over half guardian confirm recovery --> wait 2 day --> execute recovery
- // |
- // --> all guardian confim recovery --> execute recovery
- function batchApproveRecovery(
- address _wallet,
- address[] calldata _newOwners,
- uint256 signatureCount,
- bytes memory signatures
- ) external;
-
- function approveRecovery(address _wallet, address[] calldata _newOwners) external;
-
- function executeRecovery(address _wallet) external;
-
- function cancelRecovery(address _wallet) external;
-}
diff --git a/contracts/modules/SocialRecoveryModule/SocialRecoveryModule.sol b/contracts/modules/SocialRecoveryModule/SocialRecoveryModule.sol
deleted file mode 100644
index 8d180664..00000000
--- a/contracts/modules/SocialRecoveryModule/SocialRecoveryModule.sol
+++ /dev/null
@@ -1,420 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "./ISocialRecoveryModule.sol";
-import "../BaseModule.sol";
-import "../../libraries/AddressLinkedList.sol";
-import "../../libraries/TypeConversion.sol";
-import "@openzeppelin/contracts/interfaces/IERC1271.sol";
-import "../../interfaces/ISoulWallet.sol";
-
-contract SocialRecoveryModule is ISocialRecoveryModule, BaseModule {
- using AddressLinkedList for mapping(address => address);
- using TypeConversion for address;
-
- string public constant NAME = "Soulwallet Social Recovery Module";
- string public constant VERSION = "0.0.1";
-
- bytes32 private constant _DOMAIN_SEPARATOR_TYPEHASH =
- keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
-
- bytes32 private constant _SOCIAL_RECOVERY_TYPEHASH =
- keccak256("SocialRecovery(address wallet,address[] newOwners,uint256 nonce)");
-
- bytes4 private constant _FUNC_RESET_OWNER = bytes4(keccak256("resetOwner(bytes32)"));
- bytes4 private constant _FUNC_RESET_OWNERS = bytes4(keccak256("resetOwners(bytes32[])"));
-
- mapping(address => uint256) walletRecoveryNonce;
- mapping(address => uint256) walletInitSeed;
-
- mapping(address => GuardianInfo) internal walletGuardian;
- mapping(address => PendingGuardianEntry) internal walletPendingGuardian;
-
- mapping(address => mapping(bytes32 => uint256)) approvedRecords;
- mapping(address => RecoveryEntry) recoveryEntries;
-
- uint128 private __seed = 0;
-
- modifier authorized(address _wallet) {
- require(ISoulWallet(_wallet).isAuthorizedModule(address(this)), "unauthorized");
- _;
- }
-
- modifier whenRecovery(address _wallet) {
- require(recoveryEntries[_wallet].executeAfter > 0, "no ongoing recovery");
- _;
- }
-
- modifier whenNotRecovery(address _wallet) {
- require(recoveryEntries[_wallet].executeAfter == 0, "ongoing recovery");
- _;
- }
-
- function getChainId() public view returns (uint256) {
- uint256 id;
- assembly {
- id := chainid()
- }
- return id;
- }
-
- function domainSeparator() public view returns (bytes32) {
- return keccak256(
- abi.encode(
- _DOMAIN_SEPARATOR_TYPEHASH,
- keccak256(abi.encodePacked(NAME)),
- keccak256(abi.encodePacked(VERSION)),
- getChainId(),
- this
- )
- );
- }
-
- function encodeSocialRecoveryData(address _wallet, address[] calldata _newOwners, uint256 _nonce)
- public
- view
- returns (bytes memory)
- {
- bytes32 recoveryHash =
- keccak256(abi.encode(_SOCIAL_RECOVERY_TYPEHASH, _wallet, keccak256(abi.encodePacked(_newOwners)), _nonce));
- return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), recoveryHash);
- }
-
- function getSocialRecoveryHash(address _wallet, address[] calldata _newOwners, uint256 _nonce)
- public
- view
- returns (bytes32)
- {
- return keccak256(encodeSocialRecoveryData(_wallet, _newOwners, _nonce));
- }
-
- function _newSeed() private returns (uint128) {
- __seed++;
- return __seed;
- }
-
- function inited(address wallet) internal view override returns (bool) {
- return walletInitSeed[wallet] != 0;
- }
-
- function _init(bytes calldata data) internal override {
- (address[] memory _guardians, uint256 _threshold, bytes32 _guardianHash) =
- abi.decode(data, (address[], uint256, bytes32));
- address _sender = sender();
- require(_threshold > 0 && _threshold <= _guardians.length, "threshold error");
- if (_guardians.length > 0) {
- require(_guardianHash == bytes32(0), "cannot set anonomous guardian with onchain guardian");
- }
- if (_guardians.length == 0) {
- require(_guardianHash != bytes32(0), "guardian config error");
- }
- for (uint256 i = 0; i < _guardians.length; i++) {
- walletGuardian[_sender].guardians.add(_guardians[i]);
- }
- walletGuardian[_sender].guardianHash = _guardianHash;
- walletGuardian[_sender].threshold = _threshold;
- walletInitSeed[_sender] = _newSeed();
- }
-
- function _deInit() internal override {
- address _sender = sender();
- walletInitSeed[_sender] = 0;
- delete walletGuardian[_sender];
- delete walletPendingGuardian[_sender];
- delete recoveryEntries[_sender];
- }
-
- function _checkLatestGuardian(address wallet) private {
- if (
- walletPendingGuardian[wallet].pendingUntil > 0
- && walletPendingGuardian[wallet].pendingUntil > block.timestamp
- ) {
- if (walletPendingGuardian[wallet].guardianHash != bytes32(0)) {
- // if set anonomous guardian, clear onchain guardian
- walletGuardian[wallet].guardians.clear();
- walletGuardian[wallet].guardianHash = walletPendingGuardian[wallet].guardianHash;
- } else if (walletPendingGuardian[wallet].guardians.length > 0) {
- //if set onchain guardian, clear anonomous guardian
- walletGuardian[wallet].guardianHash = bytes32(0);
- walletGuardian[wallet].guardians.clear();
- for (uint256 i = 0; i < walletPendingGuardian[wallet].guardians.length; i++) {
- walletGuardian[wallet].guardians.add(walletPendingGuardian[wallet].guardians[i]);
- }
- }
-
- delete walletPendingGuardian[wallet];
- }
- }
-
- modifier checkLatestGuardian(address wallet) {
- _checkLatestGuardian(wallet);
- _;
- }
-
- function guardiansCount(address wallet) public view returns (uint256) {
- return walletGuardian[wallet].guardians.size();
- }
-
- function getGuardians(address wallet) public view returns (address[] memory) {
- return walletGuardian[wallet].guardians.list(AddressLinkedList.SENTINEL_ADDRESS, type(uint8).max);
- }
-
- function updateGuardians(address[] calldata _guardians, uint256 _threshold, bytes32 _guardianHash)
- external
- authorized(sender())
- whenNotRecovery(sender())
- checkLatestGuardian(sender())
- {
- address wallet = sender();
- if (_guardians.length > 0) {
- require(_guardianHash == bytes32(0), "cannot set anonomous guardian with onchain guardian");
- }
- if (_guardians.length == 0) {
- require(_guardianHash != bytes32(0), "guardian config error");
- }
- require(_threshold > 0 && _threshold <= _guardians.length, "threshold error");
- PendingGuardianEntry memory pendingEntry;
- pendingEntry.pendingUntil = block.timestamp + 2 days;
- pendingEntry.guardians = _guardians;
-
- pendingEntry.guardianHash = _guardianHash;
- walletPendingGuardian[wallet] = pendingEntry;
- }
-
- // owner or guardian
- function cancelSetGuardians(address wallet) external authorized(wallet) checkLatestGuardian(wallet) {
- require(walletPendingGuardian[wallet].pendingUntil > 0, "no pending guardian");
- if (wallet != sender()) {
- if (!isGuardian(wallet, sender())) {
- revert("not authorized");
- }
- }
- delete walletPendingGuardian[wallet];
- }
-
- function revealAnomousGuardians(address wallet, address[] calldata guardians, uint256 salt)
- public
- authorized(wallet)
- checkLatestGuardian(wallet)
- {
- if (wallet != sender()) {
- if (!isGuardian(wallet, sender())) {
- revert("not authorized");
- }
- }
- address lastGuardian = address(0);
- address currenGuardian;
- for (uint256 i = 0; i < guardians.length; i++) {
- currenGuardian = guardians[i];
- require(currenGuardian > lastGuardian, "guardian list error");
- lastGuardian = currenGuardian;
- }
- // 1. check hash
- bytes32 guardianHash = getAnomousGuardianHash(guardians, salt);
- if (guardianHash != walletGuardian[wallet].guardianHash) {
- revert("guardian hash error");
- }
- // 2. update guardian list in storage
- for (uint256 i = 0; i < guardians.length; i++) {
- walletGuardian[wallet].guardians.add(guardians[i]);
- }
- // 3. clear anonomous guardian hash
- walletGuardian[wallet].guardianHash = bytes32(0);
- emit AnonymousGuardianRevealed(wallet, guardians, guardianHash);
- }
-
- function getAnomousGuardianHash(address[] calldata guardians, uint256 salt) public pure returns (bytes32) {
- return keccak256(abi.encodePacked(guardians, salt));
- }
-
- function batchApproveRecovery(
- address _wallet,
- address[] calldata _newOwners,
- uint256 signatureCount,
- bytes memory signatures
- ) external authorized(_wallet) {
- // TODO . clear pending guardian setting
- require(_newOwners.length > 0, "owners cannot be empty");
- uint256 _nonce = nonce(_wallet);
- // get recoverHash = hash(recoveryRecord) with EIP712
- bytes32 recoveryHash = getSocialRecoveryHash(_wallet, _newOwners, _nonce);
- // verify signatures, verify is guardian
- checkNSignatures(_wallet, recoveryHash, signatureCount, signatures);
- // if (numConfirmed == numGuardian) execute Recovery
- if (signatureCount == walletGuardian[_wallet].guardians.size()) {
- // perform recovery
- _performRecovery(_wallet, _newOwners);
- }
- if (signatureCount > threshold(_wallet)) {
- _pendingRecovery(_wallet, _newOwners, _nonce);
- }
- }
-
- function executeRecovery(address _wallet) external whenRecovery(_wallet) authorized(_wallet) {
- RecoveryEntry memory request = recoveryEntries[_wallet];
- // check RecoveryEntry.executeUntil > block.timestamp
- require(block.timestamp >= request.executeAfter, "recovery period still pending");
- _performRecovery(_wallet, request.newOwners);
- }
-
- function _performRecovery(address _wallet, address[] memory _newOwners) private {
- // check nonce and update nonce
- require(_newOwners.length > 0, "owners cannot be empty");
- if (recoveryEntries[_wallet].nonce == nonce(_wallet)) {
- walletRecoveryNonce[_wallet]++;
- }
- // delete RecoveryEntry
- delete recoveryEntries[_wallet];
-
- ISoulWallet soulwallet = ISoulWallet(payable(_wallet));
- bytes32[] memory convertedOwners = TypeConversion.addressesToBytes32Array(_newOwners);
- // update owners
- soulwallet.resetOwners(convertedOwners);
- // emit RecoverySuccess
- emit SocialRecovery(_wallet, _newOwners);
- }
-
- function cancelRecovery(address _wallet) external authorized(_wallet) whenRecovery(_wallet) {
- require(msg.sender == _wallet, "only wallet owner can cancel recovery");
- emit SocialRecoveryCanceled(_wallet, recoveryEntries[_wallet].nonce);
- delete recoveryEntries[_wallet];
- }
-
- function _pendingRecovery(address _wallet, address[] calldata _newOwners, uint256 _nonce) private {
- // new pending recovery
- uint256 executeAfter = block.timestamp + 2 days;
- recoveryEntries[_wallet] = RecoveryEntry(_newOwners, executeAfter, _nonce);
- walletRecoveryNonce[_wallet]++;
- emit PendingRecovery(_wallet, _newOwners, _nonce, executeAfter);
- }
-
- /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`.
- /// @notice Make sure to perform a bounds check for @param pos, to avoid out of bounds access on @param signatures
- /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access
- /// @param signatures concatenated rsv signatures
- function signatureSplit(bytes memory signatures, uint256 pos)
- internal
- pure
- returns (uint8 v, bytes32 r, bytes32 s)
- {
- // The signature format is a compact form of:
- // {bytes32 r}{bytes32 s}{uint8 v}
- // Compact means, uint8 is not padded to 32 bytes.
- // solhint-disable-next-line no-inline-assembly
- assembly {
- let signaturePos := mul(0x41, pos)
- r := mload(add(signatures, add(signaturePos, 0x20)))
- s := mload(add(signatures, add(signaturePos, 0x40)))
- // Here we are loading the last 32 bytes, including 31 bytes
- // of 's'. There is no 'mload8' to do this.
- //
- // 'byte' is not working due to the Solidity parser, so lets
- // use the second best option, 'and'
- v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)
- }
- }
-
- /**
- * referece from gnosis safe validation
- *
- */
- function checkNSignatures(address _wallet, bytes32 dataHash, uint256 signatureCount, bytes memory signatures)
- public
- view
- {
- // Check that the provided signature data is not too short
- require(signatures.length >= signatureCount * 65, "signatures too short");
- // There cannot be an owner with address 0.
- address lastOwner = address(0);
- address currentOwner;
- uint8 v;
- bytes32 r;
- bytes32 s;
- uint256 i;
- for (i = 0; i < signatureCount; i++) {
- (v, r, s) = signatureSplit(signatures, i);
- if (v == 0) {
- // If v is 0 then it is a contract signature
- // When handling contract signatures the address of the contract is encoded into r
- currentOwner = address(uint160(uint256(r)));
-
- // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes
- // This check is not completely accurate, since it is possible that more signatures than the threshold are send.
- // Here we only check that the pointer is not pointing inside the part that is being processed
- require(uint256(s) >= signatureCount * 65, "contract signatures too short");
-
- // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes)
- require(uint256(s) + (32) <= signatures.length, "contract signatures out of bounds");
-
- // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length
- uint256 contractSignatureLen;
- // solhint-disable-next-line no-inline-assembly
- assembly {
- contractSignatureLen := mload(add(add(signatures, s), 0x20))
- }
- require(uint256(s) + 32 + contractSignatureLen <= signatures.length, "contract signature wrong offset");
-
- // Check signature
- bytes memory contractSignature;
- // solhint-disable-next-line no-inline-assembly
- assembly {
- // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s
- contractSignature := add(add(signatures, s), 0x20)
- }
- (bool success, bytes memory result) = currentOwner.staticcall(
- abi.encodeWithSelector(IERC1271.isValidSignature.selector, dataHash, contractSignature)
- );
- require(
- success && result.length == 32
- && abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector),
- "contract signature invalid"
- );
- } else if (v == 1) {
- // If v is 1 then it is an approved hash
- // When handling approved hashes the address of the approver is encoded into r
- currentOwner = address(uint160(uint256(r)));
- // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction
- require(
- msg.sender == currentOwner || approvedRecords[currentOwner][dataHash] != 0,
- "approve hash verify failed"
- );
- } else {
- // eip712 verify
- currentOwner = ecrecover(dataHash, v, r, s);
- }
- require(currentOwner > lastOwner && isGuardian(_wallet, currentOwner), "verify failed");
- lastOwner = currentOwner;
- }
- }
-
- function isGuardian(address _wallet, address _guardian) public view returns (bool) {
- return walletGuardian[_wallet].guardians.isExist(_guardian);
- }
-
- function approveRecovery(address _wallet, address[] calldata _newOwners) external authorized(_wallet) {
- require(_newOwners.length > 0, "owners cannot be empty");
- if (!isGuardian(_wallet, sender())) {
- revert("not authorized");
- }
- //
- uint256 _nonce = nonce(_wallet);
- bytes32 recoveryHash = getSocialRecoveryHash(_wallet, _newOwners, _nonce);
- approvedRecords[sender()][recoveryHash] = 1;
- emit ApproveRecovery(_wallet, sender(), recoveryHash);
- }
-
- function nonce(address _wallet) public view returns (uint256 _nonce) {
- return walletRecoveryNonce[_wallet];
- }
-
- function threshold(address _wallet) public view returns (uint256 _threshold) {
- return walletGuardian[_wallet].threshold;
- }
-
- function requiredFunctions() external pure override returns (bytes4[] memory) {
- bytes4[] memory functions = new bytes4[](2);
- functions[0] = _FUNC_RESET_OWNER;
- functions[1] = _FUNC_RESET_OWNERS;
- return functions;
- }
-}
diff --git a/contracts/modules/Upgrade/Upgrade.sol b/contracts/modules/Upgrade/UpgradeModule.sol
similarity index 75%
rename from contracts/modules/Upgrade/Upgrade.sol
rename to contracts/modules/Upgrade/UpgradeModule.sol
index 840f1919..7a6c9cfc 100644
--- a/contracts/modules/Upgrade/Upgrade.sol
+++ b/contracts/modules/Upgrade/UpgradeModule.sol
@@ -5,16 +5,17 @@ import "../BaseModule.sol";
import "./IUpgrade.sol";
import "../../interfaces/IUpgradable.sol";
-contract Upgrade is BaseModule, IUpgrade {
+contract UpgradeModule is BaseModule, IUpgrade {
address public newImplementation;
mapping(address => uint256) private _inited;
+ mapping(address => bool) private _upgraded;
constructor(address _newImplementation) {
newImplementation = _newImplementation;
}
- function inited(address _target) internal view override returns (bool) {
- return _inited[_target] != 0;
+ function inited(address wallet) internal view override returns (bool) {
+ return _inited[wallet] != 0;
}
function _init(bytes calldata data) internal override {
@@ -26,14 +27,16 @@ contract Upgrade is BaseModule, IUpgrade {
_inited[sender()] = 0;
}
+ function upgrade(address wallet) external override {
+ require(_inited[wallet] != 0, "not inited");
+ require(_upgraded[wallet] == false, "already upgraded");
+ IUpgradable(wallet).upgradeTo(newImplementation);
+ _upgraded[wallet] = true;
+ }
+
function requiredFunctions() external pure override returns (bytes4[] memory) {
bytes4[] memory _funcs = new bytes4[](1);
_funcs[0] = IUpgradable.upgradeTo.selector;
return _funcs;
}
-
- function upgrade(address wallet) external override {
- require(_inited[wallet] != 0, "not inited");
- IUpgradable(wallet).upgradeTo(newImplementation);
- }
}
diff --git a/contracts/modules/interfaces/ISoulWalletModule.sol b/contracts/modules/interfaces/ISoulWalletModule.sol
new file mode 100644
index 00000000..2523af33
--- /dev/null
+++ b/contracts/modules/interfaces/ISoulWalletModule.sol
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+import {IModule} from "@soulwallet-core/contracts/interface/IModule.sol";
+
+interface ISoulWalletModule is IModule {
+ function requiredFunctions() external pure returns (bytes4[] memory);
+}
diff --git a/contracts/modules/keystore/ArbitrumKeyStoreModule/ArbKnownStateRootWithHistory.sol b/contracts/modules/keystore/ArbitrumKeyStoreModule/ArbKnownStateRootWithHistory.sol
deleted file mode 100644
index 8a1ebdb4..00000000
--- a/contracts/modules/keystore/ArbitrumKeyStoreModule/ArbKnownStateRootWithHistory.sol
+++ /dev/null
@@ -1,52 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../KnownStateRootWithHistoryBase.sol";
-import "@arbitrum/nitro-contracts/src/precompiles/ArbSys.sol";
-import "@arbitrum/nitro-contracts/src/libraries/AddressAliasHelper.sol";
-import "@openzeppelin/contracts/access/Ownable.sol";
-/*
- * @title ArbKnownStateRootWithHistory
- * @notice This contract is an extension of `KnownStateRootWithHistoryBase` and keeps a record of block hashes
- * for specific block numbers ensuring they are set by a trusted entity on L1 on Arbitrum network.
- */
-
-contract ArbKnownStateRootWithHistory is KnownStateRootWithHistoryBase, Ownable {
- /* @notice Address of the target contract on Layer 1 (L1). */
- address public l1Target;
- /*
- * @dev Initializes the `l1Target` address and the `owner` of the contract.
- * @param _l1Target Address of the target contract on L1.
- * @param _owner Owner's address.
- */
-
- constructor(address _l1Target, address _owner) Ownable(_owner) {
- l1Target = _l1Target;
- }
- /*
- * @notice Updates the `l1Target` address.
- * @param _l1Target New address of the target contract on L1.
- */
-
- function updateL1Target(address _l1Target) public onlyOwner {
- l1Target = _l1Target;
- }
- /*
- * @notice Sets the hash for a specific block number.
- * @dev This function requires:
- * - Message is coming from the L1 target contract's L2 alias.
- * - Block number is not 0.
- * - Block hash is not the zero hash.
- * @param l1BlockNumber Block number on L1.
- * @param l1BlockHash Block hash corresponding to the block number.
- */
-
- function setBlockHash(uint256 l1BlockNumber, bytes32 l1BlockHash) external {
- // To check that message came from L1, we check that the sender is the L1 contract's L2 alias.
- require(msg.sender == AddressAliasHelper.applyL1ToL2Alias(l1Target), "blockhash only updateable by L1Target");
- require(l1BlockNumber != 0, "l1 block number is 0");
- require(l1BlockHash != bytes32(0), "l1 block hash is 0");
- blockHashs[l1BlockNumber] = l1BlockHash;
- emit L1BlockSyncd(l1BlockNumber, l1BlockHash);
- }
-}
diff --git a/contracts/modules/keystore/ArbitrumKeyStoreModule/L1BlockInfoPassing.sol b/contracts/modules/keystore/ArbitrumKeyStoreModule/L1BlockInfoPassing.sol
deleted file mode 100644
index fd3e1c80..00000000
--- a/contracts/modules/keystore/ArbitrumKeyStoreModule/L1BlockInfoPassing.sol
+++ /dev/null
@@ -1,64 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "@arbitrum/nitro-contracts/src/bridge/IInbox.sol";
-import "@arbitrum/nitro-contracts/src/bridge/Outbox.sol";
-import {ArbKnownStateRootWithHistory} from "./ArbKnownStateRootWithHistory.sol";
-import "@openzeppelin/contracts/access/Ownable.sol";
-/**
- * @title L1BlockInfoPassing
- * @notice This contract facilitates the passing of block information from Layer 1 (L1) to Layer 2 (L2) on the Arbitrum network
- */
-
-contract L1BlockInfoPassing is Ownable {
- address public l2Target;
- IInbox public immutable inbox;
-
- event BlockHashPassingTickedCreated(uint256 ticketId, uint256 blockNumber, bytes32 blockHash);
- /**
- * @dev Initializes the `l2Target` address, `inbox` address and the `owner` of the contract
- * @param _l2Target The address of the target contract on Layer 2 (L2)
- * @param _inbox The address of the inbox contract
- * @param _owner The owner's address
- */
-
- constructor(address _l2Target, address _inbox, address _owner) Ownable(_owner) {
- l2Target = _l2Target;
- inbox = IInbox(_inbox);
- }
- /**
- * @notice Updates the `l2Target` address
- * @param _l2Target New address of the target contract on L2
- */
-
- function updateL2Target(address _l2Target) public onlyOwner {
- l2Target = _l2Target;
- }
- /**
- * @notice Sends the block hash of the previous block to L2 using Arbitrum's retryable ticket mechanism
- * @param _maxSubmissionCost The maximum amount of Eth to be paid for the L2-side message execution
- * @param _maxGas The maximum amount of gas to be used on L2 for executing the L2-side message
- * @param _gasPriceBid The price (in wei) to be paid per unit of gas
- * @return ticketID The ID of the retryable ticket created by this function
- */
-
- function passBlockHashInL2(uint256 _maxSubmissionCost, uint256 _maxGas, uint256 _gasPriceBid)
- public
- payable
- returns (uint256)
- {
- // should not get the current blockhash,
- // block.blockhash(uint blockNumber) returns (bytes32): hash of the given block - only works for 256 most recent, excluding current, blocks
- // check https://github.com/foundry-rs/foundry/pull/1890
- uint256 _blockNumber = block.number - 1;
- bytes32 _blockhash = blockhash(_blockNumber);
-
- bytes memory data = abi.encodeCall(ArbKnownStateRootWithHistory.setBlockHash, (_blockNumber, _blockhash));
- uint256 ticketID = inbox.createRetryableTicket{value: msg.value}(
- l2Target, 0, _maxSubmissionCost, msg.sender, msg.sender, _maxGas, _gasPriceBid, data
- );
-
- emit BlockHashPassingTickedCreated(ticketID, _blockNumber, _blockhash);
- return ticketID;
- }
-}
diff --git a/contracts/modules/keystore/BlockVerifier.sol b/contracts/modules/keystore/BlockVerifier.sol
deleted file mode 100644
index e7863a92..00000000
--- a/contracts/modules/keystore/BlockVerifier.sol
+++ /dev/null
@@ -1,81 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-/*
-This code is based on https://github.com/Keydonix/uniswap-oracle/blob/master/contracts/source/BlockVerifier.sol
-Credit to the original authors and contributors.
-*/
-
-pragma solidity ^0.8.20;
-
-library BlockVerifier {
- function extractStateRootAndTimestamp(bytes memory rlpBytes, bytes32 blockHash)
- internal
- pure
- returns (bytes32 stateRoot, uint256 blockTimestamp, uint256 blockNumber)
- {
- assembly {
- function revertWithReason(message, length) {
- // 4-byte function selector of `Error(string)` which is `0x08c379a0`
- mstore(0, 0x08c379a000000000000000000000000000000000000000000000000000000000)
- // Offset of string return value
- mstore(4, 0x20)
- // Length of string return value (the revert reason)
- mstore(0x24, length)
- // actuall revert message
- mstore(0x44, message)
- revert(0, add(0x44, length))
- }
-
- function readDynamic(prefixPointer) -> dataPointer, dataLength {
- let value := byte(0, mload(prefixPointer))
- switch lt(value, 0x80)
- case 1 {
- dataPointer := prefixPointer
- dataLength := 1
- }
- case 0 {
- dataPointer := add(prefixPointer, 1)
- dataLength := sub(value, 0x80)
- }
- }
-
- // get the length of the data
- let rlpLength := mload(rlpBytes)
- // move pointer forward, ahead of length
- rlpBytes := add(rlpBytes, 0x20)
-
- // we know the length of the block will be between 483 bytes and 709 bytes, which means it will have 2 length bytes after the prefix byte, so we can skip 3 bytes in
- // CONSIDER: we could save a trivial amount of gas by compressing most of this into a single add instruction
- let parentHashPrefixPointer := add(rlpBytes, 3)
- let parentHashPointer := add(parentHashPrefixPointer, 1)
- let uncleHashPrefixPointer := add(parentHashPointer, 32)
- let uncleHashPointer := add(uncleHashPrefixPointer, 1)
- let minerAddressPrefixPointer := add(uncleHashPointer, 32)
- let minerAddressPointer := add(minerAddressPrefixPointer, 1)
- let stateRootPrefixPointer := add(minerAddressPointer, 20)
- let stateRootPointer := add(stateRootPrefixPointer, 1)
- let transactionRootPrefixPointer := add(stateRootPointer, 32)
- let transactionRootPointer := add(transactionRootPrefixPointer, 1)
- let receiptsRootPrefixPointer := add(transactionRootPointer, 32)
- let receiptsRootPointer := add(receiptsRootPrefixPointer, 1)
- let logsBloomPrefixPointer := add(receiptsRootPointer, 32)
- let logsBloomPointer := add(logsBloomPrefixPointer, 3)
- let difficultyPrefixPointer := add(logsBloomPointer, 256)
- let difficultyPointer, difficultyLength := readDynamic(difficultyPrefixPointer)
- let blockNumberPrefixPointer := add(difficultyPointer, difficultyLength)
- let blockNumberPointer, blockNumberLength := readDynamic(blockNumberPrefixPointer)
- let gasLimitPrefixPointer := add(blockNumberPointer, blockNumberLength)
- let gasLimitPointer, gasLimitLength := readDynamic(gasLimitPrefixPointer)
- let gasUsedPrefixPointer := add(gasLimitPointer, gasLimitLength)
- let gasUsedPointer, gasUsedLength := readDynamic(gasUsedPrefixPointer)
- let timestampPrefixPointer := add(gasUsedPointer, gasUsedLength)
- let timestampPointer, timestampLength := readDynamic(timestampPrefixPointer)
-
- blockNumber := shr(sub(256, mul(blockNumberLength, 8)), mload(blockNumberPointer))
- let rlpHash := keccak256(rlpBytes, rlpLength)
- if iszero(eq(blockHash, rlpHash)) { revertWithReason("blockHash != rlpHash", 20) }
-
- stateRoot := mload(stateRootPointer)
- blockTimestamp := shr(sub(256, mul(timestampLength, 8)), mload(timestampPointer))
- }
- }
-}
diff --git a/contracts/modules/keystore/IKeyStoreModule.sol b/contracts/modules/keystore/IKeyStoreModule.sol
deleted file mode 100644
index 81ed86e3..00000000
--- a/contracts/modules/keystore/IKeyStoreModule.sol
+++ /dev/null
@@ -1,31 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-/**
- * @title IKeyStoreModule
- * @notice Interface for the KeyStoreModule, responsible for managing and syncing keystores
- */
-interface IKeyStoreModule {
- /**
- * @notice Emitted when the keystore for a specific wallet has been synchronized
- * @param _wallet The address of the wallet for which the keystore has been synced
- * @param _newOwners The new owners of the keystore represented as a bytes32 value
- */
- event KeyStoreSyncd(address indexed _wallet, bytes32 indexed _newOwners);
- /**
- * @notice Emitted when a keystore is initialized
- * @param _wallet The address of the wallet for which the keystore has been initialized
- * @param _initialKey The initial key set for the keystore represented as a bytes32 value
- * @param initialGuardianHash The initial hash value for the guardians
- * @param guardianSafePeriod The safe period for guardians
- */
- event KeyStoreInited(
- address indexed _wallet, bytes32 _initialKey, bytes32 initialGuardianHash, uint64 guardianSafePeriod
- );
- /**
- * @dev Synchronizes the keystore for a specific wallet
- * @param wallet The address of the wallet to be synchronized
- */
-
- function syncL1Keystore(address wallet) external;
-}
diff --git a/contracts/modules/keystore/IKnownStateRootWithHistory.sol b/contracts/modules/keystore/IKnownStateRootWithHistory.sol
deleted file mode 100644
index c06bab3f..00000000
--- a/contracts/modules/keystore/IKnownStateRootWithHistory.sol
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-/**
- * @title BlockInfo
- * @dev Struct containing information related to a particular block.
- */
-struct BlockInfo {
- bytes32 storageRootHash; /* Storage root hash of the block */
- bytes32 blockHash; /* Hash of the block */
- uint256 blockNumber; /* Number of the block */
- uint256 blockTimestamp; /* Timestamp of the block */
-}
-
-/**
- * @title IKnownStateRootWithHistory
- * @notice Interface for checking and retrieving information about known state roots and associated block info
- */
-interface IKnownStateRootWithHistory {
- /**
- * @notice Checks if a state root is known
- * @param _stateRoot The state root to check
- * @return bool indicating whether the state root is known
- */
- function isKnownStateRoot(bytes32 _stateRoot) external returns (bool);
-
- /**
- * @notice Retrieves information about a state root if it's known
- * @param _stateRoot The state root for which to retrieve information
- * @return result A bool indicating if the state root is known
- * @return info A BlockInfo struct containing associated block information
- */
- function stateRootInfo(bytes32 _stateRoot) external view returns (bool result, BlockInfo memory info);
-}
diff --git a/contracts/modules/keystore/KeyStoreMerkleProof.sol b/contracts/modules/keystore/KeyStoreMerkleProof.sol
new file mode 100644
index 00000000..8e900eaa
--- /dev/null
+++ b/contracts/modules/keystore/KeyStoreMerkleProof.sol
@@ -0,0 +1,64 @@
+pragma solidity ^0.8.17;
+
+import {IMerkleRoot} from "./interfaces/IMerkleRoot.sol";
+import {IKeyStoreProof} from "../../keystore/interfaces/IKeyStoreProof.sol";
+
+contract KeyStoreMerkleProof is IKeyStoreProof {
+ mapping(bytes32 => bytes32) public l1SlotToSigningKey;
+ mapping(bytes32 => bytes) public l1SlotToRawOwners;
+ mapping(bytes32 => uint256) public lastProofBlock;
+
+ address public immutable MERKLE_ROOT_HISTORY;
+
+ event L1KeyStoreProved(bytes32 l1Slot, bytes32 signingKey);
+
+ constructor(address _merkleRootHistory) {
+ MERKLE_ROOT_HISTORY = _merkleRootHistory;
+ }
+
+ function proveKeyStoreData(
+ bytes32 l1Slot,
+ bytes32 merkleRoot,
+ bytes32 newSigningKey,
+ bytes memory rawOwners,
+ uint256 blockNumber,
+ uint256 index,
+ bytes32[] memory proof
+ ) external {
+ require(newSigningKey == keccak256(rawOwners), "invalid raw owner data");
+ require(IMerkleRoot(MERKLE_ROOT_HISTORY).isKnownRoot(merkleRoot), "unkown merkle root");
+ uint256 lastProofBlockNumber = lastProofBlock[l1Slot];
+ require(blockNumber > lastProofBlockNumber, "block too old");
+ require(proof.length == 32, "invalid proof length");
+ bytes32 leaf = keccak256(abi.encodePacked(l1Slot, newSigningKey, blockNumber));
+ require(verify(proof, merkleRoot, leaf, index), "invalid proof");
+ l1SlotToSigningKey[l1Slot] = newSigningKey;
+ lastProofBlock[l1Slot] = blockNumber;
+ l1SlotToRawOwners[l1Slot] = rawOwners;
+ emit L1KeyStoreProved(l1Slot, newSigningKey);
+ }
+
+ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf, uint256 index) public pure returns (bool) {
+ bytes32 hash = leaf;
+ for (uint256 i = 0; i < proof.length; i++) {
+ bytes32 proofElement = proof[i];
+
+ if ((index & 1) == 1) {
+ hash = keccak256(abi.encodePacked(proofElement, hash));
+ } else {
+ hash = keccak256(abi.encodePacked(hash, proofElement));
+ }
+
+ index = index / 2;
+ }
+ return hash == root;
+ }
+
+ function keyStoreBySlot(bytes32 l1Slot) external view returns (bytes32 signingKey) {
+ return (l1SlotToSigningKey[l1Slot]);
+ }
+
+ function rawOwnersBySlot(bytes32 l1Slot) external view override returns (bytes memory owners) {
+ return l1SlotToRawOwners[l1Slot];
+ }
+}
diff --git a/contracts/modules/keystore/KeyStoreModule.sol b/contracts/modules/keystore/KeyStoreModule.sol
index c5bf2c12..034e3cf0 100644
--- a/contracts/modules/keystore/KeyStoreModule.sol
+++ b/contracts/modules/keystore/KeyStoreModule.sol
@@ -1,16 +1,10 @@
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.17;
import "../BaseModule.sol";
-import "./IKeyStoreModule.sol";
-import "./BlockVerifier.sol";
-import "./MerklePatriciaVerifier.sol";
+import "./interfaces/IKeyStoreModule.sol";
import "../../libraries/KeyStoreSlotLib.sol";
-import "../../keystore/interfaces/IKeyStoreProof.sol";
+import {IKeyStoreProof} from "../../keystore/interfaces/IKeyStoreProof.sol";
-/**
- * @title KeyStoreModule
- * @notice module for syncing a L1 keystore
- */
contract KeyStoreModule is IKeyStoreModule, BaseModule {
bytes4 private constant _FUNC_RESET_OWNER = bytes4(keccak256("resetOwner(bytes32)"));
bytes4 private constant _FUNC_RESET_OWNERS = bytes4(keccak256("resetOwners(bytes32[])"));
@@ -21,71 +15,19 @@ contract KeyStoreModule is IKeyStoreModule, BaseModule {
mapping(address => bytes32) public lastKeyStoreSyncSignKey;
mapping(address => bool) walletInited;
- uint128 private __seed = 0;
- /**
- * @notice Internal function to increment and return seed.
- * @return New incremented seed value.
- */
-
- function _newSeed() private returns (uint128) {
- __seed++;
- return __seed;
- }
- /**
- * @param _keyStoreProof Address of the KeyStoreProof contract.
- */
constructor(address _keyStoreProof) {
keyStoreProof = IKeyStoreProof(_keyStoreProof);
}
- /**
- * @notice Synchronize L1 keystore with the wallet.
- * @param wallet Address of the wallet.
- */
- function syncL1Keystore(address wallet) external override {
- bytes32 slotInfo = l1Slot[wallet];
- require(slotInfo != bytes32(0), "wallet slot not set");
- bytes32 keystoreSignKey = keyStoreProof.keystoreBySlot(slotInfo);
- require(keystoreSignKey != bytes32(0), "keystore proof not sync");
- bytes32 lastSyncKeyStore = lastKeyStoreSyncSignKey[wallet];
- if (lastSyncKeyStore != bytes32(0) && lastSyncKeyStore == keystoreSignKey) {
- revert("keystore already synced");
- }
- ISoulWallet soulwallet = ISoulWallet(payable(wallet));
- bytes memory rawOwners = keyStoreProof.rawOwnersBySlot(slotInfo);
- bytes32[] memory owners = abi.decode(rawOwners, (bytes32[]));
- soulwallet.resetOwners(owners);
- lastKeyStoreSyncSignKey[wallet] = keystoreSignKey;
- emit KeyStoreSyncd(wallet, keystoreSignKey);
- }
- /**
- * @notice Retrieve the list of required functions for the keystore module.
- * @return An array of function selectors.
- */
-
- function requiredFunctions() external pure override returns (bytes4[] memory) {
- bytes4[] memory functions = new bytes4[](2);
- functions[0] = _FUNC_RESET_OWNER;
- functions[1] = _FUNC_RESET_OWNERS;
- return functions;
- }
- /**
- * @notice Check if a wallet is initialized.
- * @param wallet Address of the wallet.
- * @return True if the wallet is initialized, false otherwise.
- */
-
- function inited(address wallet) internal view virtual override returns (bool) {
- return walletInited[wallet];
+ function _deInit() internal override {
+ address _sender = sender();
+ delete l1Slot[_sender];
+ delete lastKeyStoreSyncSignKey[_sender];
+ walletInited[_sender] = false;
}
- /**
- * @dev when wallet add keystore module, it will call this function to set the l1keystore slot mapping
- * @notice Internal function to initialize keystore for a wallet.
- * @param _data Initialization data containing initial key hash, guardian hash, and guardian safe period.
- */
- function _init(bytes calldata _data) internal virtual override {
+ function _init(bytes calldata _data) internal override {
address _sender = sender();
(bytes32 initialKeyHash, bytes32 initialGuardianHash, uint64 guardianSafePeriod) =
abi.decode(_data, (bytes32, bytes32, uint64));
@@ -93,7 +35,7 @@ contract KeyStoreModule is IKeyStoreModule, BaseModule {
require(walletKeyStoreSlot != bytes32(0), "wallet slot needs to set");
l1Slot[_sender] = walletKeyStoreSlot;
- bytes32 keystoreSignKey = keyStoreProof.keystoreBySlot(walletKeyStoreSlot);
+ bytes32 keystoreSignKey = keyStoreProof.keyStoreBySlot(walletKeyStoreSlot);
// if keystore already sync, change to keystore signer
if (keystoreSignKey != bytes32(0)) {
bytes memory rawOwners = keyStoreProof.rawOwnersBySlot(walletKeyStoreSlot);
@@ -107,14 +49,32 @@ contract KeyStoreModule is IKeyStoreModule, BaseModule {
walletInited[_sender] = true;
emit KeyStoreInited(_sender, initialKeyHash, initialGuardianHash, guardianSafePeriod);
}
- /**
- * @notice Internal function to deinitialize keystore for a wallet.
- */
- function _deInit() internal virtual override {
- address _sender = sender();
- delete l1Slot[_sender];
- delete lastKeyStoreSyncSignKey[_sender];
- walletInited[_sender] = false;
+ function inited(address wallet) internal view override returns (bool) {
+ return walletInited[wallet];
+ }
+
+ function requiredFunctions() external pure override returns (bytes4[] memory) {
+ bytes4[] memory functions = new bytes4[](2);
+ functions[0] = _FUNC_RESET_OWNER;
+ functions[1] = _FUNC_RESET_OWNERS;
+ return functions;
+ }
+
+ function syncL1Keystore(address wallet) external override {
+ bytes32 slotInfo = l1Slot[wallet];
+ require(slotInfo != bytes32(0), "wallet slot not set");
+ bytes32 keystoreSignKey = keyStoreProof.keyStoreBySlot(slotInfo);
+ require(keystoreSignKey != bytes32(0), "keystore proof not sync");
+ bytes32 lastSyncKeyStore = lastKeyStoreSyncSignKey[wallet];
+ if (lastSyncKeyStore != bytes32(0) && lastSyncKeyStore == keystoreSignKey) {
+ revert("keystore already synced");
+ }
+ ISoulWallet soulwallet = ISoulWallet(payable(wallet));
+ bytes memory rawOwners = keyStoreProof.rawOwnersBySlot(slotInfo);
+ bytes32[] memory owners = abi.decode(rawOwners, (bytes32[]));
+ soulwallet.resetOwners(owners);
+ lastKeyStoreSyncSignKey[wallet] = keystoreSignKey;
+ emit KeyStoreSyncd(wallet, keystoreSignKey);
}
}
diff --git a/contracts/modules/keystore/KeystoreProof.sol b/contracts/modules/keystore/KeystoreProof.sol
deleted file mode 100644
index 23fc71e6..00000000
--- a/contracts/modules/keystore/KeystoreProof.sol
+++ /dev/null
@@ -1,112 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "./IKnownStateRootWithHistory.sol";
-import "./MerklePatriciaVerifier.sol";
-import "../../keystore/interfaces/IKeyStoreProof.sol";
-
-/**
- * @title KeystoreProof
- * @notice Contract for maintaining and proving a L1 keystore and its storage roots
- */
-contract KeystoreProof is IKeyStoreProof {
- mapping(bytes32 => bytes32) public l1SlotToSigningKey;
- mapping(bytes32 => bytes) public l1SlotToRawOwners;
- mapping(bytes32 => uint256) public lastProofBlock;
- mapping(bytes32 => bytes32) public stateRootToKeystoreStorageRoot;
-
- address public immutable STATE_ROOT_HISTORY_ADDESS;
- address public immutable L1_KEYSTORE_ADDRESS;
- // the latest block number in l1 that proved
- uint256 public latestProofL1BlockNumber;
-
- event KeyStoreStorageProved(bytes32 stateRoot, bytes32 storageRoot);
- event L1KeyStoreProved(bytes32 l1Slot, bytes32 signingKeyHash);
- /**
- * @param _l1KeystoreAddress Address of L1 Keystore
- * @param _stateRootHistoryAddress Address of state root history contract
- */
-
- constructor(address _l1KeystoreAddress, address _stateRootHistoryAddress) {
- L1_KEYSTORE_ADDRESS = _l1KeystoreAddress;
- STATE_ROOT_HISTORY_ADDESS = _stateRootHistoryAddress;
- }
- /**
- * @notice Proves the keystore storage root
- * @param stateRoot State root to be proved
- * @param accountProof Proof for the account associated with the state root
- */
-
- function proofKeystoreStorageRoot(bytes32 stateRoot, bytes memory accountProof) external {
- (bool searchResult, BlockInfo memory currentBlockInfo) =
- IKnownStateRootWithHistory(STATE_ROOT_HISTORY_ADDESS).stateRootInfo(stateRoot);
- require(searchResult, "unkown root");
- require(stateRootToKeystoreStorageRoot[stateRoot] == bytes32(0), "storage root already proved");
- bytes memory keyStoreAccountDetailsBytes = MerklePatriciaVerifier.getValueFromProof(
- currentBlockInfo.storageRootHash, keccak256(abi.encodePacked(L1_KEYSTORE_ADDRESS)), accountProof
- );
- Rlp.Item[] memory keyStoreDetails = Rlp.toList(Rlp.toItem(keyStoreAccountDetailsBytes));
- bytes32 keyStoreStorageRootHash = Rlp.toBytes32(keyStoreDetails[2]);
- stateRootToKeystoreStorageRoot[stateRoot] = keyStoreStorageRootHash;
- if (currentBlockInfo.blockNumber > latestProofL1BlockNumber) {
- latestProofL1BlockNumber = currentBlockInfo.blockNumber;
- }
- emit KeyStoreStorageProved(stateRoot, keyStoreStorageRootHash);
- }
- /**
- * @notice Proves the L1 keystore
- * @param l1Slot Slot of L1 keystore
- * @param stateRoot State root to be proved
- * @param newSigningKey New signing key to be set
- * @param rawOwners Raw owners to be associated with the signing key
- * @param keyProof Proof for the key
- */
-
- function proofL1Keystore(
- bytes32 l1Slot,
- bytes32 stateRoot,
- bytes32 newSigningKey,
- bytes memory rawOwners,
- bytes memory keyProof
- ) external {
- require(newSigningKey == keccak256(rawOwners), "invalid raw owner data");
- (bool searchResult, BlockInfo memory currentBlockInfo) =
- IKnownStateRootWithHistory(STATE_ROOT_HISTORY_ADDESS).stateRootInfo(stateRoot);
- require(searchResult, "unkown stateRoot root");
- bytes32 keyStoreStorageRootHash = stateRootToKeystoreStorageRoot[stateRoot];
- require(keyStoreStorageRootHash != bytes32(0), "storage root not set");
-
- // when verify merkel patricia proof for storage value, the tree path = keccaka256("l1slot")
- bytes32 proofSigningKey = Rlp.rlpBytesToBytes32(
- MerklePatriciaVerifier.getValueFromProof(keyStoreStorageRootHash, keccak256(abi.encode(l1Slot)), keyProof)
- );
- require(proofSigningKey == newSigningKey, "key not match");
- // store the new proof signing key to slot mapping
-
- uint256 blockNumber = lastProofBlock[l1Slot];
- require(currentBlockInfo.blockNumber > blockNumber, "needs to proof newer block");
-
- l1SlotToSigningKey[l1Slot] = newSigningKey;
- lastProofBlock[l1Slot] = currentBlockInfo.blockNumber;
- l1SlotToRawOwners[l1Slot] = rawOwners;
- emit L1KeyStoreProved(l1Slot, newSigningKey);
- }
- /**
- * @notice Retrieves the signing key hash associated with a given L1 slot
- * @param l1Slot Slot of L1 keystore
- * @return signingKeyHash The signing key hash associated with the L1 slot
- */
-
- function keystoreBySlot(bytes32 l1Slot) external view returns (bytes32 signingKeyHash) {
- return (l1SlotToSigningKey[l1Slot]);
- }
- /**
- * @notice Retrieves the raw owners associated with a given L1 slot
- * @param l1Slot Slot of L1 keystore
- * @return owners The raw owners associated with the L1 slot
- */
-
- function rawOwnersBySlot(bytes32 l1Slot) external view override returns (bytes memory owners) {
- return l1SlotToRawOwners[l1Slot];
- }
-}
diff --git a/contracts/modules/keystore/KnownStateRootWithHistoryBase.sol b/contracts/modules/keystore/KnownStateRootWithHistoryBase.sol
deleted file mode 100644
index afe9a74f..00000000
--- a/contracts/modules/keystore/KnownStateRootWithHistoryBase.sol
+++ /dev/null
@@ -1,108 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "./IKnownStateRootWithHistory.sol";
-import "./BlockVerifier.sol";
-
-/**
- * @title KnownStateRootWithHistoryBase
- * @notice Abstract contract for maintaining a history of known state roots and associated block info
- */
-abstract contract KnownStateRootWithHistoryBase is IKnownStateRootWithHistory {
- /* Size of the state root history */
- uint256 public constant ROOT_HISTORY_SIZE = 100;
- /* Current index in the circular buffer of state roots */
- uint256 public currentRootIndex = 0;
- /* Mapping of block numbers to associated block information */
- mapping(uint256 => BlockInfo) public stateRoots;
- /* Mapping of block numbers to block hashes */
- mapping(uint256 => bytes32) public blockHashs;
-
- event L1BlockSyncd(uint256 indexed blockNumber, bytes32 blockHash);
- event NewStateRoot(bytes32 indexed stateRoot, uint256 indexed blockNumber, address user);
- /**
- * @notice Checks if a given state root is known
- * @param _stateRoot The state root to check
- * @return True if the state root is known, false otherwise
- */
-
- function isKnownStateRoot(bytes32 _stateRoot) public view override returns (bool) {
- if (_stateRoot == 0) {
- return false;
- }
- uint256 _currentRootIndex = currentRootIndex;
- uint256 i = _currentRootIndex;
-
- do {
- BlockInfo memory blockinfo = stateRoots[i];
- if (_stateRoot == blockinfo.storageRootHash) {
- return true;
- }
- if (i == 0) {
- i = ROOT_HISTORY_SIZE;
- }
- i--;
- } while (i != _currentRootIndex);
- return false;
- }
- /**
- * @notice Inserts a new state root and associated block info
- * @param _blockNumber The number of the block
- * @param _blockInfo Serialized block info data
- */
-
- function insertNewStateRoot(uint256 _blockNumber, bytes memory _blockInfo) external {
- bytes32 _blockHash = blockHashs[_blockNumber];
- require(_blockHash != bytes32(0), "blockhash not set");
- (bytes32 stateRoot, uint256 blockTimestamp, uint256 blockNumber) =
- BlockVerifier.extractStateRootAndTimestamp(_blockInfo, _blockHash);
-
- require(!isKnownStateRoot(stateRoot), "duplicate state root");
-
- BlockInfo memory currentBlockInfo = stateRoots[currentRootIndex];
- require(blockNumber > currentBlockInfo.blockNumber, "blockNumber too old");
-
- uint256 newRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE;
- currentRootIndex = newRootIndex;
-
- stateRoots[newRootIndex].blockHash = _blockHash;
- stateRoots[newRootIndex].storageRootHash = stateRoot;
- stateRoots[newRootIndex].blockNumber = blockNumber;
- stateRoots[newRootIndex].blockTimestamp = blockTimestamp;
- emit NewStateRoot(stateRoot, blockNumber, msg.sender);
- }
- /**
- * @notice Retrieves information about a given state root
- * @param _stateRoot The state root to query
- * @return result True if the state root is known, false otherwise
- * @return info BlockInfo structure associated with the given state root
- */
-
- function stateRootInfo(bytes32 _stateRoot) external view override returns (bool result, BlockInfo memory info) {
- if (_stateRoot == 0) {
- return (false, info);
- }
- uint256 _currentRootIndex = currentRootIndex;
- uint256 i = _currentRootIndex;
-
- do {
- BlockInfo memory blockinfo = stateRoots[i];
- if (_stateRoot == blockinfo.storageRootHash) {
- return (true, blockinfo);
- }
- if (i == 0) {
- i = ROOT_HISTORY_SIZE;
- }
- i--;
- } while (i != _currentRootIndex);
- return (false, info);
- }
- /**
- * @notice Retrieves information about the latest known state root
- * @return info BlockInfo structure associated with the latest state root
- */
-
- function lastestStateRootInfo() external view returns (BlockInfo memory info) {
- return stateRoots[currentRootIndex];
- }
-}
diff --git a/contracts/modules/keystore/MerklePatriciaVerifier.sol b/contracts/modules/keystore/MerklePatriciaVerifier.sol
deleted file mode 100644
index 079028a9..00000000
--- a/contracts/modules/keystore/MerklePatriciaVerifier.sol
+++ /dev/null
@@ -1,130 +0,0 @@
-pragma solidity ^0.8.20;
-
-import {Rlp} from "./Rlp.sol";
-/*
-This code is based on https://github.com/Keydonix/uniswap-oracle/blob/master/contracts/source/MerklePatriciaVerifier.sol
-Credit to the original authors and contributors.
-*/
-
-library MerklePatriciaVerifier {
- /*
- * @dev Extracts the value from a merkle proof
- * @param expectedRoot The expected hash of the root node of the trie.
- * @param path The path in the trie leading to value.
- * @param proofNodesRlp RLP encoded array of proof nodes.
- * @return The value proven to exist in the merkle patricia tree whose root is `expectedRoot` at the path `path`
- *
- * WARNING: Does not currently support validation of unset/0 values!
- */
- function getValueFromProof(bytes32 expectedRoot, bytes32 path, bytes memory proofNodesRlp)
- internal
- pure
- returns (bytes memory)
- {
- Rlp.Item memory rlpParentNodes = Rlp.toItem(proofNodesRlp);
- Rlp.Item[] memory parentNodes = Rlp.toList(rlpParentNodes);
-
- bytes memory currentNode;
- Rlp.Item[] memory currentNodeList;
-
- bytes32 nodeKey = expectedRoot;
- uint256 pathPtr = 0;
-
- // our input is a 32-byte path, but we have to prepend a single 0 byte to that and pass it along as a 33 byte memory array since that is what getNibbleArray wants
- bytes memory nibblePath = new bytes(33);
- assembly {
- mstore(add(nibblePath, 33), path)
- }
- nibblePath = _getNibbleArray(nibblePath);
-
- require(path.length != 0, "empty path provided");
-
- currentNode = Rlp.toBytes(parentNodes[0]);
-
- for (uint256 i = 0; i < parentNodes.length; i++) {
- require(pathPtr <= nibblePath.length, "Path overflow");
-
- currentNode = Rlp.toBytes(parentNodes[i]);
- require(nodeKey == keccak256(currentNode), "node doesn't match key");
- currentNodeList = Rlp.toList(parentNodes[i]);
-
- if (currentNodeList.length == 17) {
- if (pathPtr == nibblePath.length) {
- return Rlp.toData(currentNodeList[16]);
- }
-
- uint8 nextPathNibble = uint8(nibblePath[pathPtr]);
- require(nextPathNibble <= 16, "nibble too long");
- nodeKey = Rlp.toBytes32(currentNodeList[nextPathNibble]);
- pathPtr += 1;
- } else if (currentNodeList.length == 2) {
- uint256 nibblesToTravers = _nibblesToTraverse(Rlp.toData(currentNodeList[0]), nibblePath, pathPtr);
- pathPtr += nibblesToTravers;
- // leaf node
- if (pathPtr == nibblePath.length) {
- return Rlp.toData(currentNodeList[1]);
- }
- //extension node
- require(nibblesToTravers != 0, "invalid extension node");
-
- nodeKey = Rlp.toBytes32(currentNodeList[1]);
- } else {
- revert("unexpected length array");
- }
- }
- revert("not enough proof nodes");
- }
-
- function _nibblesToTraverse(bytes memory encodedPartialPath, bytes memory path, uint256 pathPtr)
- private
- pure
- returns (uint256)
- {
- uint256 len;
- // encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath
- // and slicedPath have elements that are each one hex character (1 nibble)
- bytes memory partialPath = _getNibbleArray(encodedPartialPath);
- bytes memory slicedPath = new bytes(partialPath.length);
-
- // pathPtr counts nibbles in path
- // partialPath.length is a number of nibbles
- for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) {
- bytes1 pathNibble = path[i];
- slicedPath[i - pathPtr] = pathNibble;
- }
-
- if (keccak256(partialPath) == keccak256(slicedPath)) {
- len = partialPath.length;
- } else {
- len = 0;
- }
- return len;
- }
-
- // bytes byteArray must be hp encoded
- function _getNibbleArray(bytes memory byteArray) private pure returns (bytes memory) {
- bytes memory nibbleArray;
- if (byteArray.length == 0) return nibbleArray;
-
- uint8 offset;
- uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, byteArray));
- if (hpNibble == 1 || hpNibble == 3) {
- nibbleArray = new bytes(byteArray.length*2-1);
- bytes1 oddNibble = _getNthNibbleOfBytes(1, byteArray);
- nibbleArray[0] = oddNibble;
- offset = 1;
- } else {
- nibbleArray = new bytes(byteArray.length*2-2);
- offset = 0;
- }
-
- for (uint256 i = offset; i < nibbleArray.length; i++) {
- nibbleArray[i] = _getNthNibbleOfBytes(i - offset + 2, byteArray);
- }
- return nibbleArray;
- }
-
- function _getNthNibbleOfBytes(uint256 n, bytes memory str) private pure returns (bytes1) {
- return bytes1(n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10);
- }
-}
diff --git a/contracts/modules/keystore/OptimismKeyStoreProofModule/IL1Block.sol b/contracts/modules/keystore/OptimismKeyStoreProofModule/IL1Block.sol
deleted file mode 100644
index 925f7b82..00000000
--- a/contracts/modules/keystore/OptimismKeyStoreProofModule/IL1Block.sol
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-/**
- * @title IL1Block
- * @notice Interface for representing Layer 1 block properties, primarily block hash and block number
- */
-
-interface IL1Block {
- /**
- * @dev Fetches the hash of the L1 block
- * @return The block hash as bytes32
- */
- function hash() external returns (bytes32);
- /**
- * @dev Fetches the number of the L1 block
- * @return The block number as uint256
- */
- function number() external returns (uint256);
-}
diff --git a/contracts/modules/keystore/OptimismKeyStoreProofModule/OpKnownStateRootWithHistory.sol b/contracts/modules/keystore/OptimismKeyStoreProofModule/OpKnownStateRootWithHistory.sol
deleted file mode 100644
index 719cff76..00000000
--- a/contracts/modules/keystore/OptimismKeyStoreProofModule/OpKnownStateRootWithHistory.sol
+++ /dev/null
@@ -1,37 +0,0 @@
-pragma solidity ^0.8.20;
-
-import "../KnownStateRootWithHistoryBase.sol";
-import "./IL1Block.sol";
-
-/**
- * @title OpKnownStateRootWithHistory
- * @notice This contract is designed to work with the Optimism network to keep track of L1 block hashes in an L2 environment
- * The block hash information is retrieved from a contract deployed on L2 which provides L1 block attributes
- */
-contract OpKnownStateRootWithHistory is KnownStateRootWithHistoryBase {
- /* https://community.optimism.io/docs/developers/build/differences/#accessing-l1-information
- Reference to the L1Block interface that will provide the L1 block information. */
- IL1Block public immutable L1_BLOCK;
-
- /**
- * @dev Constructor to set the L1Block precompiler contract address
- * @param _l1block Address of the L1Block contract
- */
- constructor(address _l1block) {
- L1_BLOCK = IL1Block(_l1block);
- }
- /**
- * @dev Fetches the L1 block hash and number from the L1Block contract, then stores it
- * Emits an event after successfully setting the block hash
- */
-
- function setBlockHash() external {
- bytes32 l1BlockHash = L1_BLOCK.hash();
- uint256 l1BlockNumber = L1_BLOCK.number();
- require(l1BlockNumber != 0, "l1 block number is 0");
- require(l1BlockHash != bytes32(0), "l1 block hash is 0");
- require(blockHashs[l1BlockNumber] == bytes32(0), "l1 blockhash already set");
- blockHashs[l1BlockNumber] = l1BlockHash;
- emit L1BlockSyncd(l1BlockNumber, l1BlockHash);
- }
-}
diff --git a/contracts/modules/keystore/Rlp.sol b/contracts/modules/keystore/Rlp.sol
deleted file mode 100644
index c6b29aaf..00000000
--- a/contracts/modules/keystore/Rlp.sol
+++ /dev/null
@@ -1,414 +0,0 @@
-pragma solidity ^0.8.20;
-
-// source: https://github.com/Keydonix/uniswap-oracle/blob/master/contracts/source/Rlp.sol
-library Rlp {
- uint256 constant DATA_SHORT_START = 0x80;
- uint256 constant DATA_LONG_START = 0xB8;
- uint256 constant LIST_SHORT_START = 0xC0;
- uint256 constant LIST_LONG_START = 0xF8;
-
- uint256 constant DATA_LONG_OFFSET = 0xB7;
- uint256 constant LIST_LONG_OFFSET = 0xF7;
-
- struct Item {
- uint256 _unsafe_memPtr; // Pointer to the RLP-encoded bytes.
- uint256 _unsafe_length; // Number of bytes. This is the full length of the string.
- }
-
- struct Iterator {
- Item _unsafe_item; // Item that's being iterated over.
- uint256 _unsafe_nextPtr; // Position of the next item in the list.
- }
-
- /* Iterator */
-
- function next(Iterator memory self) internal pure returns (Item memory subItem) {
- require(hasNext(self), "Rlp.sol:Rlp:next:1");
- uint256 ptr = self._unsafe_nextPtr;
- uint256 itemLength = _itemLength(ptr);
- subItem._unsafe_memPtr = ptr;
- subItem._unsafe_length = itemLength;
- self._unsafe_nextPtr = ptr + itemLength;
- }
-
- function next(Iterator memory self, bool strict) internal pure returns (Item memory subItem) {
- subItem = next(self);
- require(!strict || _validate(subItem), "Rlp.sol:Rlp:next:2");
- }
-
- function hasNext(Iterator memory self) internal pure returns (bool) {
- Rlp.Item memory item = self._unsafe_item;
- return self._unsafe_nextPtr < item._unsafe_memPtr + item._unsafe_length;
- }
-
- /* Item */
-
- /// @dev Creates an Item from an array of RLP encoded bytes.
- /// @param self The RLP encoded bytes.
- /// @return An Item
- function toItem(bytes memory self) internal pure returns (Item memory) {
- uint256 len = self.length;
- if (len == 0) {
- return Item(0, 0);
- }
- uint256 memPtr;
- assembly {
- memPtr := add(self, 0x20)
- }
- return Item(memPtr, len);
- }
-
- /// @dev Creates an Item from an array of RLP encoded bytes.
- /// @param self The RLP encoded bytes.
- /// @param strict Will throw if the data is not RLP encoded.
- /// @return An Item
- function toItem(bytes memory self, bool strict) internal pure returns (Item memory) {
- Rlp.Item memory item = toItem(self);
- if (strict) {
- uint256 len = self.length;
- require(_payloadOffset(item) <= len, "Rlp.sol:Rlp:toItem4");
- require(_itemLength(item._unsafe_memPtr) == len, "Rlp.sol:Rlp:toItem:5");
- require(_validate(item), "Rlp.sol:Rlp:toItem:6");
- }
- return item;
- }
-
- /// @dev Check if the Item is null.
- /// @param self The Item.
- /// @return 'true' if the item is null.
- function isNull(Item memory self) internal pure returns (bool) {
- return self._unsafe_length == 0;
- }
-
- /// @dev Check if the Item is a list.
- /// @param self The Item.
- /// @return 'true' if the item is a list.
- function isList(Item memory self) internal pure returns (bool) {
- if (self._unsafe_length == 0) {
- return false;
- }
- uint256 memPtr = self._unsafe_memPtr;
- bool result;
- assembly {
- result := iszero(lt(byte(0, mload(memPtr)), 0xC0))
- }
- return result;
- }
-
- /// @dev Check if the Item is data.
- /// @param self The Item.
- /// @return 'true' if the item is data.
- function isData(Item memory self) internal pure returns (bool) {
- if (self._unsafe_length == 0) {
- return false;
- }
- uint256 memPtr = self._unsafe_memPtr;
- bool result;
- assembly {
- result := lt(byte(0, mload(memPtr)), 0xC0)
- }
- return result;
- }
-
- /// @dev Check if the Item is empty (string or list).
- /// @param self The Item.
- /// @return result 'true' if the item is null.
- function isEmpty(Item memory self) internal pure returns (bool) {
- if (isNull(self)) {
- return false;
- }
- uint256 b0;
- uint256 memPtr = self._unsafe_memPtr;
- assembly {
- b0 := byte(0, mload(memPtr))
- }
- return (b0 == DATA_SHORT_START || b0 == LIST_SHORT_START);
- }
-
- /// @dev Get the number of items in an RLP encoded list.
- /// @param self The Item.
- /// @return The number of items.
- function items(Item memory self) internal pure returns (uint256) {
- if (!isList(self)) {
- return 0;
- }
- uint256 b0;
- uint256 memPtr = self._unsafe_memPtr;
- assembly {
- b0 := byte(0, mload(memPtr))
- }
- uint256 pos = memPtr + _payloadOffset(self);
- uint256 last = memPtr + self._unsafe_length - 1;
- uint256 itms;
- while (pos <= last) {
- pos += _itemLength(pos);
- itms++;
- }
- return itms;
- }
-
- /// @dev Create an iterator.
- /// @param self The Item.
- /// @return An 'Iterator' over the item.
- function iterator(Item memory self) internal pure returns (Iterator memory) {
- require(isList(self), "Rlp.sol:Rlp:iterator:1");
- uint256 ptr = self._unsafe_memPtr + _payloadOffset(self);
- Iterator memory it;
- it._unsafe_item = self;
- it._unsafe_nextPtr = ptr;
- return it;
- }
-
- /// @dev Return the RLP encoded bytes.
- /// @param self The Item.
- /// @return The bytes.
- function toBytes(Item memory self) internal pure returns (bytes memory) {
- uint256 len = self._unsafe_length;
- require(len != 0, "Rlp.sol:Rlp:toBytes:2");
- bytes memory bts;
- bts = new bytes(len);
- _copyToBytes(self._unsafe_memPtr, bts, len);
- return bts;
- }
-
- /// @dev Decode an Item into bytes. This will not work if the
- /// Item is a list.
- /// @param self The Item.
- /// @return The decoded string.
- function toData(Item memory self) internal pure returns (bytes memory) {
- require(isData(self));
- (uint256 rStartPos, uint256 len) = _decode(self);
- bytes memory bts;
- bts = new bytes(len);
- _copyToBytes(rStartPos, bts, len);
- return bts;
- }
-
- /// @dev Get the list of sub-items from an RLP encoded list.
- /// Warning: This is inefficient, as it requires that the list is read twice.
- /// @param self The Item.
- /// @return Array of Items.
- function toList(Item memory self) internal pure returns (Item[] memory) {
- require(isList(self), "Rlp.sol:Rlp:toList:1");
- uint256 numItems = items(self);
- Item[] memory list = new Item[](numItems);
- Rlp.Iterator memory it = iterator(self);
- uint256 idx;
- while (hasNext(it)) {
- list[idx] = next(it);
- idx++;
- }
- return list;
- }
-
- /// @dev Decode an Item into an ascii string. This will not work if the
- /// Item is a list.
- /// @param self The Item.
- /// @return The decoded string.
- function toAscii(Item memory self) internal pure returns (string memory) {
- require(isData(self), "Rlp.sol:Rlp:toAscii:1");
- (uint256 rStartPos, uint256 len) = _decode(self);
- bytes memory bts = new bytes(len);
- _copyToBytes(rStartPos, bts, len);
- string memory str = string(bts);
- return str;
- }
-
- /// @dev Decode an Item into a uint. This will not work if the
- /// Item is a list.
- /// @param self The Item.
- /// @return The decoded string.
- function toUint(Item memory self) internal pure returns (uint256) {
- require(isData(self), "Rlp.sol:Rlp:toUint:1");
- (uint256 rStartPos, uint256 len) = _decode(self);
- require(len <= 32, "Rlp.sol:Rlp:toUint:3");
- require(len != 0, "Rlp.sol:Rlp:toUint:4");
- uint256 data;
- assembly {
- data := div(mload(rStartPos), exp(256, sub(32, len)))
- }
- return data;
- }
-
- /// @dev Decode an Item into a boolean. This will not work if the
- /// Item is a list.
- /// @param self The Item.
- /// @return The decoded string.
- function toBool(Item memory self) internal pure returns (bool) {
- require(isData(self), "Rlp.sol:Rlp:toBool:1");
- (uint256 rStartPos, uint256 len) = _decode(self);
- require(len == 1, "Rlp.sol:Rlp:toBool:3");
- uint256 temp;
- assembly {
- temp := byte(0, mload(rStartPos))
- }
- require(temp <= 1, "Rlp.sol:Rlp:toBool:8");
- return temp == 1 ? true : false;
- }
-
- /// @dev Decode an Item into a byte. This will not work if the
- /// Item is a list.
- /// @param self The Item.
- /// @return The decoded string.
- function toByte(Item memory self) internal pure returns (bytes1) {
- require(isData(self), "Rlp.sol:Rlp:toByte:1");
- (uint256 rStartPos, uint256 len) = _decode(self);
- require(len == 1, "Rlp.sol:Rlp:toByte:3");
- bytes1 temp;
- assembly {
- temp := byte(0, mload(rStartPos))
- }
- return bytes1(temp);
- }
-
- /// @dev Decode an Item into an int. This will not work if the
- /// Item is a list.
- /// @param self The Item.
- /// @return The decoded string.
- function toInt(Item memory self) internal pure returns (int256) {
- return int256(toUint(self));
- }
-
- /// @dev Decode an Item into a bytes32. This will not work if the
- /// Item is a list.
- /// @param self The Item.
- /// @return The decoded string.
- function toBytes32(Item memory self) internal pure returns (bytes32) {
- return bytes32(toUint(self));
- }
-
- /// @dev Decode an Item into an address. This will not work if the
- /// Item is a list.
- /// @param self The Item.
- /// @return The decoded string.
- function toAddress(Item memory self) internal pure returns (address) {
- require(isData(self), "Rlp.sol:Rlp:toAddress:1");
- (uint256 rStartPos, uint256 len) = _decode(self);
- require(len == 20, "Rlp.sol:Rlp:toAddress:3");
- address data;
- assembly {
- data := div(mload(rStartPos), exp(256, 12))
- }
- return data;
- }
-
- // Get the payload offset.
- function _payloadOffset(Item memory self) private pure returns (uint256) {
- if (self._unsafe_length == 0) {
- return 0;
- }
- uint256 b0;
- uint256 memPtr = self._unsafe_memPtr;
- assembly {
- b0 := byte(0, mload(memPtr))
- }
- if (b0 < DATA_SHORT_START) {
- return 0;
- }
- if (b0 < DATA_LONG_START || (b0 >= LIST_SHORT_START && b0 < LIST_LONG_START)) {
- return 1;
- }
- if (b0 < LIST_SHORT_START) {
- return b0 - DATA_LONG_OFFSET + 1;
- }
- return b0 - LIST_LONG_OFFSET + 1;
- }
-
- // Get the full length of an Item.
- function _itemLength(uint256 memPtr) private pure returns (uint256 len) {
- uint256 b0;
- assembly {
- b0 := byte(0, mload(memPtr))
- }
- if (b0 < DATA_SHORT_START) {
- len = 1;
- } else if (b0 < DATA_LONG_START) {
- len = b0 - DATA_SHORT_START + 1;
- } else if (b0 < LIST_SHORT_START) {
- assembly {
- let bLen := sub(b0, 0xB7) // bytes length (DATA_LONG_OFFSET)
- let dLen := div(mload(add(memPtr, 1)), exp(256, sub(32, bLen))) // data length
- len := add(1, add(bLen, dLen)) // total length
- }
- } else if (b0 < LIST_LONG_START) {
- len = b0 - LIST_SHORT_START + 1;
- } else {
- assembly {
- let bLen := sub(b0, 0xF7) // bytes length (LIST_LONG_OFFSET)
- let dLen := div(mload(add(memPtr, 1)), exp(256, sub(32, bLen))) // data length
- len := add(1, add(bLen, dLen)) // total length
- }
- }
- }
-
- // Get start position and length of the data.
- function _decode(Item memory self) private pure returns (uint256 memPtr, uint256 len) {
- require(isData(self), "Rlp.sol:Rlp:_decode:1");
- uint256 b0;
- uint256 start = self._unsafe_memPtr;
- assembly {
- b0 := byte(0, mload(start))
- }
- if (b0 < DATA_SHORT_START) {
- memPtr = start;
- len = 1;
- return (memPtr, len);
- }
- if (b0 < DATA_LONG_START) {
- len = self._unsafe_length - 1;
- memPtr = start + 1;
- } else {
- uint256 bLen;
- assembly {
- bLen := sub(b0, 0xB7) // DATA_LONG_OFFSET
- }
- len = self._unsafe_length - 1 - bLen;
- memPtr = start + bLen + 1;
- }
- return (memPtr, len);
- }
-
- // Assumes that enough memory has been allocated to store in target.
- function _copyToBytes(uint256 sourceBytes, bytes memory destinationBytes, uint256 btsLen) internal pure {
- // Exploiting the fact that 'tgt' was the last thing to be allocated,
- // we can write entire words, and just overwrite any excess.
- assembly {
- let words := div(add(btsLen, 31), 32)
- let sourcePointer := sourceBytes
- let destinationPointer := add(destinationBytes, 32)
- for { let i := 0 } lt(i, words) { i := add(i, 1) } {
- let offset := mul(i, 32)
- mstore(add(destinationPointer, offset), mload(add(sourcePointer, offset)))
- }
- mstore(add(destinationBytes, add(32, mload(destinationBytes))), 0)
- }
- }
-
- // Check that an Item is valid.
- function _validate(Item memory self) private pure returns (bool ret) {
- // Check that RLP is well-formed.
- uint256 b0;
- uint256 b1;
- uint256 memPtr = self._unsafe_memPtr;
- assembly {
- b0 := byte(0, mload(memPtr))
- b1 := byte(1, mload(memPtr))
- }
- if (b0 == DATA_SHORT_START + 1 && b1 < DATA_SHORT_START) {
- return false;
- }
- return true;
- }
-
- function rlpBytesToUint256(bytes memory source) internal pure returns (uint256 result) {
- return Rlp.toUint(Rlp.toItem(source));
- }
-
- function rlpBytesToAddress(bytes memory source) internal pure returns (address result) {
- return Rlp.toAddress(Rlp.toItem(source));
- }
-
- function rlpBytesToBytes32(bytes memory source) internal pure returns (bytes32 result) {
- return Rlp.toBytes32(Rlp.toItem(source));
- }
-}
diff --git a/contracts/modules/keystore/arbitrum/ArbKeyStoreCrossChainMerkleRootManager.sol b/contracts/modules/keystore/arbitrum/ArbKeyStoreCrossChainMerkleRootManager.sol
new file mode 100644
index 00000000..67f3f6ac
--- /dev/null
+++ b/contracts/modules/keystore/arbitrum/ArbKeyStoreCrossChainMerkleRootManager.sol
@@ -0,0 +1,39 @@
+pragma solidity ^0.8.17;
+
+import {IInbox} from "@arbitrum/nitro-contracts/src/bridge/IInbox.sol";
+import {MerkleRootHistoryBase} from "../base/MerkleRootHistoryBase.sol";
+import "@openzeppelin/contracts/access/Ownable.sol";
+import {IKeyStoreMerkleProof} from "../../../keystore/L1/base/BaseMerkleTree.sol";
+
+contract ArbKeyStoreCrossChainMerkleRootManager is Ownable {
+ address public l2Target;
+ address public l1KeyStore;
+ IInbox public immutable inbox;
+
+ event KeyStoreMerkleRootSyncedToArb(uint256 ticketId, bytes32 merkleRoot);
+
+ constructor(address _l2Target, address _l1KeyStore, address _inbox, address _owner) Ownable(_owner) {
+ l2Target = _l2Target;
+ l1KeyStore = _l1KeyStore;
+ inbox = IInbox(_inbox);
+ }
+
+ function updateL2Target(address _l2Target) public onlyOwner {
+ l2Target = _l2Target;
+ }
+
+ function syncKeyStoreMerkleRootToArb(uint256 _maxSubmissionCost, uint256 _maxGas, uint256 _gasPriceBid)
+ public
+ payable
+ returns (uint256)
+ {
+ bytes32 merkleRoot = IKeyStoreMerkleProof(l1KeyStore).getMerkleRoot();
+ bytes memory data = abi.encodeCall(MerkleRootHistoryBase.setMerkleRoot, (merkleRoot));
+ uint256 ticketID = inbox.createRetryableTicket{value: msg.value}(
+ l2Target, 0, _maxSubmissionCost, msg.sender, msg.sender, _maxGas, _gasPriceBid, data
+ );
+
+ emit KeyStoreMerkleRootSyncedToArb(ticketID, merkleRoot);
+ return ticketID;
+ }
+}
diff --git a/contracts/modules/keystore/arbitrum/ArbMerkleRootHistory.sol b/contracts/modules/keystore/arbitrum/ArbMerkleRootHistory.sol
new file mode 100644
index 00000000..cadd0b7b
--- /dev/null
+++ b/contracts/modules/keystore/arbitrum/ArbMerkleRootHistory.sol
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+import "../base/MerkleRootHistoryBase.sol";
+import "@arbitrum/nitro-contracts/src/libraries/AddressAliasHelper.sol";
+
+contract ArbMerkleRootHistory is MerkleRootHistoryBase {
+ constructor(address _l1Target, address _owner) MerkleRootHistoryBase(_l1Target, _owner) {}
+
+ function isValidL1Sender() internal view override returns (bool) {
+ return msg.sender == AddressAliasHelper.applyL1ToL2Alias(l1Target);
+ }
+}
diff --git a/contracts/modules/keystore/base/MerkleRootHistoryBase.sol b/contracts/modules/keystore/base/MerkleRootHistoryBase.sol
new file mode 100644
index 00000000..9116ed4c
--- /dev/null
+++ b/contracts/modules/keystore/base/MerkleRootHistoryBase.sol
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+import "@openzeppelin/contracts/access/Ownable.sol";
+import "../interfaces/IMerkleRoot.sol";
+
+abstract contract MerkleRootHistoryBase is Ownable, IMerkleRoot {
+ address public l1Target;
+ mapping(uint256 => bytes32) public merkleRoots;
+ uint32 public constant ROOT_HISTORY_SIZE = 30;
+ uint32 public currentRootIndex;
+ bytes32 public latestMerkleRoot;
+
+ constructor(address _l1Target, address _owner) Ownable(_owner) {
+ l1Target = _l1Target;
+ }
+
+ function updateL1Target(address _l1Target) public onlyOwner {
+ l1Target = _l1Target;
+ }
+
+ function isKnownRoot(bytes32 _root) public view returns (bool) {
+ if (_root == 0) {
+ return false;
+ }
+ uint32 _currentRootIndex = currentRootIndex;
+ uint32 i = _currentRootIndex;
+ do {
+ if (_root == merkleRoots[i]) {
+ return true;
+ }
+ if (i == 0) {
+ i = ROOT_HISTORY_SIZE;
+ }
+ i--;
+ } while (i != _currentRootIndex);
+ return false;
+ }
+
+ function setMerkleRoot(bytes32 l1MerkleRoot) external onlyFromL1 {
+ require(l1MerkleRoot != bytes32(0), "merkle root is 0");
+ require(isKnownRoot(l1MerkleRoot) == false, "merkle root already known");
+ uint32 newRootIndex = (currentRootIndex + 1) % ROOT_HISTORY_SIZE;
+ currentRootIndex = newRootIndex;
+ merkleRoots[newRootIndex] = l1MerkleRoot;
+ latestMerkleRoot = l1MerkleRoot;
+ emit L1MerkleRootSynced(l1MerkleRoot, block.number);
+ }
+
+ modifier onlyFromL1() {
+ require(isValidL1Sender(), "Only L1 allowed");
+ _;
+ }
+
+ function isValidL1Sender() internal virtual returns (bool);
+}
diff --git a/contracts/modules/keystore/interfaces/ICrossDomainMessenger.sol b/contracts/modules/keystore/interfaces/ICrossDomainMessenger.sol
new file mode 100644
index 00000000..516b68d0
--- /dev/null
+++ b/contracts/modules/keystore/interfaces/ICrossDomainMessenger.sol
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+interface ICrossDomainMessenger {
+ /**
+ *
+ * Events *
+ *
+ */
+
+ event SentMessage(
+ address indexed target,
+ address sender,
+ bytes message,
+ uint256 messageNonce,
+ uint256 gasLimit
+ );
+ event RelayedMessage(bytes32 indexed msgHash);
+ event FailedRelayedMessage(bytes32 indexed msgHash);
+
+ /**
+ *
+ * Variables *
+ *
+ */
+
+ function xDomainMessageSender() external view returns (address);
+
+ /**
+ *
+ * Public Functions *
+ *
+ */
+
+ /**
+ * Sends a cross domain message to the target messenger.
+ * @param _target Target contract address.
+ * @param _message Message to send to the target.
+ * @param _gasLimit Gas limit for the provided message.
+ */
+ function sendMessage(
+ address _target,
+ bytes calldata _message,
+ uint32 _gasLimit
+ ) external;
+}
diff --git a/contracts/modules/keystore/interfaces/IKeyStoreModule.sol b/contracts/modules/keystore/interfaces/IKeyStoreModule.sol
new file mode 100644
index 00000000..5f1d8357
--- /dev/null
+++ b/contracts/modules/keystore/interfaces/IKeyStoreModule.sol
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+interface IKeyStoreModule {
+ event KeyStoreSyncd(address indexed _wallet, bytes32 indexed _newOwners);
+ event KeyStoreInited(
+ address indexed _wallet, bytes32 _initialKey, bytes32 initialGuardianHash, uint64 guardianSafePeriod
+ );
+
+ function syncL1Keystore(address wallet) external;
+}
diff --git a/contracts/modules/keystore/interfaces/IMerkleRoot.sol b/contracts/modules/keystore/interfaces/IMerkleRoot.sol
new file mode 100644
index 00000000..50b8b8c0
--- /dev/null
+++ b/contracts/modules/keystore/interfaces/IMerkleRoot.sol
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+interface IMerkleRoot {
+ function isKnownRoot(bytes32 _root) external view returns (bool);
+
+ event L1MerkleRootSynced(bytes32 indexed _root, uint256 _blockNumber);
+}
diff --git a/contracts/modules/keystore/optimism/OpKeyStoreCrossChainMerkleRootManager.sol b/contracts/modules/keystore/optimism/OpKeyStoreCrossChainMerkleRootManager.sol
new file mode 100644
index 00000000..42ff263b
--- /dev/null
+++ b/contracts/modules/keystore/optimism/OpKeyStoreCrossChainMerkleRootManager.sol
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+import "@openzeppelin/contracts/access/Ownable.sol";
+import {IKeyStoreMerkleProof} from "../../../keystore/L1/base/BaseMerkleTree.sol";
+import "../interfaces/ICrossDomainMessenger.sol";
+import {MerkleRootHistoryBase} from "../base/MerkleRootHistoryBase.sol";
+
+contract OpKeyStoreCrossChainMerkleRootManager is Ownable {
+ address public l2Target;
+ address public l1KeyStore;
+ ICrossDomainMessenger public immutable l1CrossDomainMessenger;
+
+ event KeyStoreMerkleRootSyncedToOp(uint256 ticketId, bytes32 merkleRoot);
+
+ // https://community.optimism.io/docs/useful-tools/networks/#op-goerli
+
+ constructor(address _l2Target, address _l1KeyStore, address _l1CrossDomainMessenger, address _owner)
+ Ownable(_owner)
+ {
+ l2Target = _l2Target;
+ l1KeyStore = _l1KeyStore;
+ l1CrossDomainMessenger = ICrossDomainMessenger(_l1CrossDomainMessenger);
+ }
+
+ function updateL2Target(address _l2Target) public onlyOwner {
+ l2Target = _l2Target;
+ }
+
+ function syncKeyStoreMerkleRootToOp() public {
+ bytes32 merkleRoot = IKeyStoreMerkleProof(l1KeyStore).getMerkleRoot();
+ bytes memory data = abi.encodeCall(MerkleRootHistoryBase.setMerkleRoot, (merkleRoot));
+ ICrossDomainMessenger(l1CrossDomainMessenger).sendMessage(l2Target, data, 200000);
+ emit KeyStoreMerkleRootSyncedToOp(block.number, merkleRoot);
+ }
+}
diff --git a/contracts/modules/keystore/optimism/OpMerkleRootHistory.sol b/contracts/modules/keystore/optimism/OpMerkleRootHistory.sol
new file mode 100644
index 00000000..0515dec4
--- /dev/null
+++ b/contracts/modules/keystore/optimism/OpMerkleRootHistory.sol
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+import "../base/MerkleRootHistoryBase.sol";
+import "../interfaces/ICrossDomainMessenger.sol";
+
+contract OpMerkleRootHistory is MerkleRootHistoryBase {
+ address public constant CROSS_DOMAIN_MESSENGER = 0x4200000000000000000000000000000000000007;
+
+ constructor(address _l1Target, address _owner) MerkleRootHistoryBase(_l1Target, _owner) {}
+
+ function isValidL1Sender() internal view override returns (bool) {
+ return msg.sender == address(CROSS_DOMAIN_MESSENGER)
+ && ICrossDomainMessenger(CROSS_DOMAIN_MESSENGER).xDomainMessageSender() == l1Target;
+ }
+}
diff --git a/contracts/paymaster/ERC20Paymaster.sol b/contracts/paymaster/ERC20Paymaster.sol
index 2293bb86..b26ab95a 100644
--- a/contracts/paymaster/ERC20Paymaster.sol
+++ b/contracts/paymaster/ERC20Paymaster.sol
@@ -7,13 +7,12 @@ pragma solidity ^0.8.0;
// Import the required libraries and contracts
import "@account-abstraction/contracts/core/BasePaymaster.sol";
-import "@account-abstraction/contracts/core/Helpers.sol";
import "@account-abstraction/contracts/interfaces/UserOperation.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
-import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./interfaces/IOracle.sol";
import "@account-abstraction/contracts/interfaces/IEntryPoint.sol";
+import {Execution} from "@soulwallet-core/contracts/interface/IStandardExecutor.sol";
struct TokenSetting {
uint256 tokenDecimals;
@@ -114,6 +113,7 @@ contract ERC20Paymaster is BasePaymaster {
/ (1e18 * PRICE_DENOMINATOR);
require(tokenRequiredPreFund <= maxCost, "Paymaster: maxCost too low");
+ bool sponsorWalletCreation;
if (userOp.initCode.length != 0) {
// This operation prevents a malicious user from draining the Paymaster's deposit in a single active wallet user operation.
@@ -122,11 +122,13 @@ contract ERC20Paymaster is BasePaymaster {
require(requiredPreFund < MAX_ALLOW_SPONSOR_FUND_ACTIVE_WALLET, "Paymaster: maxCost too high");
require(ERC20Token.balanceOf(sender) >= tokenRequiredPreFund, "Paymaster: not enough balance");
_validateConstructor(userOp, token, tokenRequiredPreFund);
+ sponsorWalletCreation = true;
} else {
ERC20Token.safeTransferFrom(sender, address(this), tokenRequiredPreFund);
+ sponsorWalletCreation = false;
}
- return (abi.encode(sender, token, costOfPost, exchangeRate, tokenRequiredPreFund), 0);
+ return (abi.encode(sender, token, costOfPost, exchangeRate, tokenRequiredPreFund, sponsorWalletCreation), 0);
}
/*
@@ -142,28 +144,21 @@ contract ERC20Paymaster is BasePaymaster {
require(factory == WALLET_FACTORY, "Paymaster: unknown wallet factory");
require(
/*
- * 0x18dfb3c7 executeBatch(address[],bytes[])
- * 0x47e1da2a executeBatch(address[],uint256[],bytes[])
+ * 0x34fcd5be executeBatch((address,uint256,bytes)[])
*/
- bytes4(userOp.callData) == bytes4(0x47e1da2a) || bytes4(userOp.callData) == bytes4(0x18dfb3c7),
+ bytes4(userOp.callData) == bytes4(0x34fcd5be),
"invalid callData"
);
- address[] memory dest;
- bytes[] memory func;
- if (bytes4(userOp.callData) == bytes4(0x47e1da2a)) {
- (dest,, func) = abi.decode(userOp.callData[4:], (address[], uint256[], bytes[]));
- } else {
- (dest, func) = abi.decode(userOp.callData[4:], (address[], bytes[]));
- }
+ Execution[] memory executions;
+ executions = abi.decode(userOp.callData[4:], (Execution[]));
- require(dest.length == func.length, "Paymaster: invalid callData length");
require(isSupportToken(token), "Paymaster: token not support");
bool checkAllowance = false;
- for (uint256 i = 0; i < dest.length; i++) {
- address destAddr = dest[i];
+ for (uint256 i = 0; i < executions.length; i++) {
+ address destAddr = executions[i].target;
// check it contains approve operation, 0x095ea7b3 approve(address,uint256)
- if (destAddr == token && bytes4(func[i]) == bytes4(0x095ea7b3)) {
- (address spender, uint256 amount) = _decodeApprove(func[i]);
+ if (destAddr == token && bytes4(executions[i].data) == bytes4(0x095ea7b3)) {
+ (address spender, uint256 amount) = _decodeApprove(executions[i].data);
require(spender == address(this), "Paymaster: invalid spender");
require(amount >= tokenRequiredPreFund, "Paymaster: not enough approve");
checkAllowance = true;
@@ -172,7 +167,7 @@ contract ERC20Paymaster is BasePaymaster {
}
require(checkAllowance, "no approve found");
// callGasLimit
- uint256 callGasLimit = dest.length * _SAFE_APPROVE_GAS_COST;
+ uint256 callGasLimit = executions.length * _SAFE_APPROVE_GAS_COST;
require(userOp.callGasLimit >= callGasLimit, "Paymaster: gas too low for postOp");
}
@@ -189,12 +184,21 @@ contract ERC20Paymaster is BasePaymaster {
if (mode == PostOpMode.postOpReverted) {
return; // Do nothing here to not revert the whole bundle and harm reputation
}
- (address sender, address payable token, uint256 costOfPost, uint256 exchangeRate, uint256 tokenRequiredPreFund)
- = abi.decode(context, (address, address, uint256, uint256, uint256));
+ (
+ address sender,
+ address payable token,
+ uint256 costOfPost,
+ uint256 exchangeRate,
+ uint256 tokenRequiredPreFund,
+ bool sponsorWalletCreation
+ ) = abi.decode(context, (address, address, uint256, uint256, uint256, bool));
uint256 tokenRequiredFund =
(actualGasCost + costOfPost) * supportedToken[token].priceMarkup * exchangeRate / (1e18 * PRICE_DENOMINATOR);
- // refund unsed precharge token
- if (tokenRequiredPreFund > tokenRequiredFund) {
+ if (sponsorWalletCreation) {
+ // if sponsor during wallet creatation, charge the acutal amount
+ IERC20Metadata(token).safeTransferFrom(sender, address(this), tokenRequiredPreFund);
+ } else if (sponsorWalletCreation == false && tokenRequiredPreFund > tokenRequiredFund) {
+ // refund unsed precharge token
IERC20Metadata(token).safeTransfer(sender, tokenRequiredPreFund - tokenRequiredFund);
}
// update oracle
diff --git a/contracts/paymaster/interfaces/IOracle.sol b/contracts/paymaster/interfaces/IOracle.sol
index d732e090..3f14fdd2 100644
--- a/contracts/paymaster/interfaces/IOracle.sol
+++ b/contracts/paymaster/interfaces/IOracle.sol
@@ -1,3 +1,4 @@
+
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
diff --git a/contracts/plugin/BasePlugin.sol b/contracts/plugin/BasePlugin.sol
deleted file mode 100644
index f67ab18a..00000000
--- a/contracts/plugin/BasePlugin.sol
+++ /dev/null
@@ -1,99 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../interfaces/IPlugin.sol";
-import "../interfaces/ISoulWallet.sol";
-import "../interfaces/IPluginManager.sol";
-
-/**
- * @title BasePlugin
- * @dev Abstract base contract for creating plugins. Implements the IPlugin interface.
- */
-abstract contract BasePlugin is IPlugin {
- /**
- * @dev Bit flags for specifying supported hook types
- */
- uint8 internal constant GUARD_HOOK = 1 << 0;
- uint8 internal constant PRE_HOOK = 1 << 1;
- uint8 internal constant POST_HOOK = 1 << 2;
- /**
- * @dev Emitted when the plugin is initialized for a wallet
- */
-
- event PluginInit(address indexed wallet);
- /**
- * @dev Emitted when the plugin is deinitialized for a wallet
- */
- event PluginDeInit(address indexed wallet);
- /**
- * @dev Internal utility function to get the sender of the transaction
- */
-
- function _sender() internal view returns (address) {
- return msg.sender;
- }
- /**
- * @dev Virtual function for plugin-specific initialization logic
- */
-
- function _init(bytes calldata data) internal virtual;
- /**
- * @dev Virtual function for plugin-specific de-initialization logic
- */
- function _deInit() internal virtual;
- /**
- * @dev Specifies the hook types this plugin supports
- */
- function _supportsHook() internal pure virtual returns (uint8 hookType);
- /**
- * @dev Utility function to retrieve the address of the wallet invoking the plugin
- */
-
- function _wallet() internal view returns (address wallet) {
- wallet = _sender();
- }
- /**
- * @notice Checks if this contract implements a specific interface
- */
-
- function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
- return interfaceId == type(IPlugin).interfaceId;
- }
- /**
- * @dev Checks if the plugin is initialized for the given wallet
- */
-
- function inited(address wallet) internal view virtual returns (bool);
- /**
- * @notice Initializes the plugin for a wallet
- */
-
- function walletInit(bytes calldata data) external override {
- address wallet = _wallet();
- if (!inited(wallet)) {
- if (!ISoulWallet(wallet).isAuthorizedPlugin(address(this))) {
- revert("not authorized plugin");
- }
- _init(data);
- emit PluginInit(wallet);
- }
- }
- /**
- * @notice De-initializes the plugin for a wallet
- */
-
- function walletDeInit() external override {
- address wallet = _wallet();
- if (inited(wallet)) {
- if (ISoulWallet(wallet).isAuthorizedPlugin(address(this))) {
- revert("authorized plugin");
- }
- _deInit();
- emit PluginDeInit(wallet);
- }
- }
-
- function supportsHook() external pure override returns (uint8 hookType) {
- hookType = _supportsHook();
- }
-}
diff --git a/contracts/plugin/Dailylimit/Dailylimit.sol b/contracts/plugin/Dailylimit/Dailylimit.sol
deleted file mode 100644
index d7a1d848..00000000
--- a/contracts/plugin/Dailylimit/Dailylimit.sol
+++ /dev/null
@@ -1,308 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../BasePlugin.sol";
-import "./IDailylimit.sol";
-import "../../safeLock/SafeLock.sol";
-import "../../libraries/AddressLinkedList.sol";
-import "../../libraries/SignatureDecoder.sol";
-import "@account-abstraction/contracts/core/Helpers.sol";
-import "../../interfaces/IExecutionManager.sol";
-import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
-import "../../interfaces/IPluginStorage.sol";
-import "../../interfaces/IValidator.sol";
-import "../../interfaces/IValidatorManager.sol";
-
-contract Dailylimit is BasePlugin, IDailylimit, SafeLock {
- //using AddressLinkedList for mapping(address => address);
-
- address private constant _ETH_TOKEN_ADDRESS = address(2);
- uint256 private constant _MAX_TIMERANGE = 1 hours;
-
- uint256 private __seed;
-
- function _newSeed() private returns (uint256) {
- return ++__seed;
- }
-
- struct initSeed {
- uint256 currentDay;
- uint256 seed;
- }
-
- mapping(address => initSeed) private _currentDay;
-
- constructor() SafeLock("PLUGIN_DAILYLIMIT_SAFELOCK_SLOT", 2 days) {}
-
- struct DaySpent {
- uint256 dailyLimit;
- uint256 day;
- uint256 spent;
- }
-
- struct Layout {
- uint256 currentDay;
- mapping(address => address) tokens;
- mapping(address => DaySpent) daySpent;
- }
-
- function _packedToken(address token) private view returns (bytes32 packedToken) {
- packedToken = _packedToken(_wallet(), token);
- }
-
- function _packedToken(address wallet, address token) private view returns (bytes32 packedToken) {
- address _token = _getTokenAddress(token);
- uint256 seed = _currentDay[wallet].seed;
- packedToken = keccak256(abi.encodePacked(_token, seed));
- }
-
- function _packDaySpent(uint256 dailyLimit, uint256 day, uint256 spent) private pure returns (bytes memory) {
- return abi.encodePacked(dailyLimit, day, spent);
- }
-
- function _unpackDaySpent(bytes memory data) private pure returns (uint256 dailyLimit, uint256 day, uint256 spent) {
- require(data.length == 96, "Dailylimit: invalid data");
- (dailyLimit, day, spent) = abi.decode(data, (uint256, uint256, uint256));
- }
-
- function _saveTokenDaySpent(address token, uint256 dailyLimit, uint256 day, uint256 spent) private {
- bytes32 _token = _packedToken(token);
- bytes memory data = _packDaySpent(dailyLimit, day, spent);
- IPluginStorage pluginStorage = IPluginStorage(_wallet());
- pluginStorage.pluginDataStore(_token, data);
- }
-
- function _initTokenDaySpent(address token, uint256 dailyLimit) private {
- bytes32 _token = _packedToken(token);
- IPluginStorage pluginStorage = IPluginStorage(_wallet());
- require(pluginStorage.pluginDataLoad(address(this), _token).length == 0, "Dailylimit: token already added");
- bytes memory data = _packDaySpent(dailyLimit, 0, 0);
- pluginStorage.pluginDataStore(_token, data);
- }
-
- function _loadTokenDaySpent(address token)
- private
- view
- returns (bool isExist, uint256 dailyLimit, uint256 day, uint256 spent)
- {
- bytes32 _token = _packedToken(token);
- IPluginStorage pluginStorage = IPluginStorage(_wallet());
- bytes memory data = pluginStorage.pluginDataLoad(address(this), _token);
- if (data.length == 0) {
- return (false, 0, 0, 0);
- }
- isExist = true;
- (dailyLimit, day, spent) = _unpackDaySpent(data);
- }
-
- function _removeTokenDaySpent(address token) private {
- bytes32 _token = _packedToken(token);
- IPluginStorage pluginStorage = IPluginStorage(_wallet());
- pluginStorage.pluginDataStore(_token, "");
- }
-
- function _supportsHook() internal pure override returns (uint8 hookType) {
- hookType = GUARD_HOOK | POST_HOOK;
- }
-
- function inited(address wallet) internal view override returns (bool) {
- return _currentDay[wallet].currentDay != 0;
- }
-
- function _init(bytes calldata data) internal override {
- if (_currentDay[_wallet()].currentDay == 0) {
- _currentDay[_wallet()].seed = _newSeed();
- _currentDay[_wallet()].currentDay = _getDay(block.timestamp);
- // decode data
- (address[] memory tokens, uint256[] memory limits) = abi.decode(data, (address[], uint256[]));
- require(tokens.length == limits.length, "Dailylimit: invalid data");
- for (uint256 i = 0; i < tokens.length; i++) {
- address _token = tokens[i];
- uint256 limit = limits[i];
- require(limit > 0, "Dailylimit: invalid limit");
- _initTokenDaySpent(_token, limit);
- }
- emit DailyLimitChanged(tokens, limits);
- }
- }
-
- function _deInit() internal override {
- if (_currentDay[_wallet()].currentDay != 0) {
- _currentDay[_wallet()].currentDay = 0;
- }
- }
-
- function _getTokenAddress(address token) private pure returns (address) {
- return token == address(0) ? _ETH_TOKEN_ADDRESS : token;
- }
-
- function _getDay(uint256 timeNow) private pure returns (uint256) {
- return timeNow / 1 days;
- }
-
- function _decodeERC20Spent(bytes4 selector, address to, bytes memory data)
- private
- view
- returns (address token, uint256 spent)
- {
- if (selector == IERC20.transfer.selector) {
- (, spent) = abi.decode(data, (address, uint256));
- token = to;
- } else if (selector == IERC20.approve.selector) {
- (, spent) = abi.decode(data, (address, uint256));
- token = to;
- } else if (selector == IERC20.transferFrom.selector) {
- (address sender,, uint256 amount) = abi.decode(data, (address, address, uint256));
- if (sender == _wallet()) {
- token = to;
- spent = amount;
- }
- }
- }
-
- function _calcRequiredPrefund(UserOperation calldata userOp) private pure returns (uint256 requiredPrefund) {
- uint256 requiredGas = userOp.callGasLimit + userOp.verificationGasLimit + userOp.preVerificationGas;
- requiredPrefund = requiredGas * userOp.maxFeePerGas;
- }
-
- function guardHook(UserOperation calldata userOp, bytes32 userOpHash, bytes calldata guardData) external override {
- (userOpHash);
- IValidator validator = (IValidatorManager(_wallet())).validator();
- require(guardData.length == 0, "Dailylimit: guard signature not allowed");
- uint256 _validationData;
- (, bytes calldata validatorSignature) = SignatureDecoder.decodeSignature(userOp.signature);
- (_validationData,,) = validator.recoverSignature(userOpHash, validatorSignature);
-
- if (_validationData == 0) revert("Dailylimit: signature timerange invalid");
-
- ValidationData memory validationData = _parseValidationData(_validationData);
- require(
- validationData.validUntil - validationData.validAfter < _MAX_TIMERANGE, "Dailylimit: exceed max timerange"
- );
- uint256 currentDay = _getDay(validationData.validAfter);
-
- _currentDay[_wallet()].currentDay = currentDay;
- (bool isExist, uint256 dailyLimit, uint256 day, uint256 spent) = _loadTokenDaySpent(_ETH_TOKEN_ADDRESS);
- if (isExist) {
- if (userOp.paymasterAndData.length == 0) {
- uint256 ethGasFee = _calcRequiredPrefund(userOp);
- uint256 _newSpent = (day == currentDay ? spent : 0) + ethGasFee;
- require(_newSpent <= dailyLimit, "Dailylimit: ETH daily limit reached");
- _saveTokenDaySpent(_ETH_TOKEN_ADDRESS, dailyLimit, day == currentDay ? day : currentDay, _newSpent);
- }
- }
- }
-
- function preHook(address target, uint256 value, bytes calldata data) external pure override {
- (target, value, data);
- revert("Dailylimit: preHook not support");
- }
-
- function postHook(address target, uint256 value, bytes calldata data) external override {
- uint256 _day = _getDay(block.timestamp);
-
- if (value > 0) {
- (bool isExist, uint256 dailyLimit, uint256 day, uint256 spent) = _loadTokenDaySpent(_ETH_TOKEN_ADDRESS);
- if (isExist) {
- uint256 _newSpent = (day == _day ? spent : 0) + value;
- require(_newSpent <= dailyLimit, "Dailylimit: ETH daily limit reached");
- _saveTokenDaySpent(_ETH_TOKEN_ADDRESS, dailyLimit, day == _day ? day : _day, _newSpent);
- }
- }
-
- if (uint160(target) > 1) {
- (bool isExist, uint256 dailyLimit, uint256 day, uint256 spent) = _loadTokenDaySpent(target);
- if (isExist) {
- (, uint256 _spent) = _decodeERC20Spent(bytes4(data[0:4]), target, data[4:]);
- if (_spent > 0) {
- uint256 spentNow;
- if (day == _day) {
- spentNow = spent;
- } else {
- day = _day;
- spent = 0;
- }
- uint256 _newSpent = spentNow + _spent;
- require(_newSpent <= dailyLimit, "Dailylimit: token daily limit reached");
- _saveTokenDaySpent(target, dailyLimit, day, _newSpent);
- }
- }
- }
- }
-
- function reduceDailyLimits(address[] calldata token, uint256[] calldata limit) external override {
- require(token.length == limit.length, "Dailylimit: invalid data");
- for (uint256 i = 0; i < token.length; i++) {
- uint256 _amount = limit[i];
- require(_amount > 0, "Dailylimit: invalid amount");
- address _token = token[i];
- (bool isExist, uint256 dailyLimit, uint256 day, uint256 spent) = _loadTokenDaySpent(_token);
- if (isExist) {
- require(dailyLimit > _amount, "Dailylimit: exceed daily limit");
- _saveTokenDaySpent(_token, _amount, day, spent);
- } else {
- revert("Dailylimit: token not exist");
- }
- }
-
- emit DailyLimitChanged(token, limit);
- }
-
- function preSetDailyLimit(address[] calldata token, uint256[] calldata limit) external override {
- bytes32 hash = keccak256(abi.encode(token, limit));
- _lock(hash);
-
- emit PreSetDailyLimit(token, limit);
- }
-
- function cancelSetDailyLimit(address[] calldata token, uint256[] calldata limit) external override {
- bytes32 hash = keccak256(abi.encode(token, limit));
- _cancelLock(hash);
-
- emit CancelSetDailyLimit(token, limit);
- }
-
- function comfirmSetDailyLimit(address[] calldata token, uint256[] calldata limit) external override {
- bytes32 hash = keccak256(abi.encode(token, limit));
- _unlock(hash);
- require(token.length == limit.length, "Dailylimit: invalid data");
- for (uint256 i = 0; i < token.length; i++) {
- uint256 _amount = limit[i];
- address _token = token[i];
- (bool isExist,, uint256 day, uint256 spent) = _loadTokenDaySpent(_token);
- if (isExist) {
- if (_amount == 0) {
- _removeTokenDaySpent(_token);
- } else {
- _saveTokenDaySpent(_token, _amount, day, spent);
- }
- } else {
- if (_amount > 0) {
- _initTokenDaySpent(_token, _amount);
- }
- }
- }
-
- emit DailyLimitChanged(token, limit);
- }
-
- function getDailyLimit(address wallet, address token) external view override returns (uint256 dailyLimit) {
- bytes32 _token = _packedToken(wallet, token);
- IPluginStorage pluginStorage = IPluginStorage(wallet);
- bytes memory data = pluginStorage.pluginDataLoad(address(this), _token);
- if (data.length == 0) {
- return 0;
- }
- (dailyLimit,,) = _unpackDaySpent(data);
- }
-
- function getSpentToday(address wallet, address token) external view override returns (uint256 spent) {
- bytes32 _token = _packedToken(wallet, token);
- IPluginStorage pluginStorage = IPluginStorage(wallet);
- bytes memory data = pluginStorage.pluginDataLoad(address(this), _token);
- if (data.length == 0) {
- return 0;
- }
- (,, spent) = _unpackDaySpent(data);
- }
-}
diff --git a/contracts/plugin/Dailylimit/IDailylimit.sol b/contracts/plugin/Dailylimit/IDailylimit.sol
deleted file mode 100644
index a3ba6143..00000000
--- a/contracts/plugin/Dailylimit/IDailylimit.sol
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-interface IDailylimit {
- event DailyLimitChanged(address[] token, uint256[] limit);
- event PreSetDailyLimit(address[] token, uint256[] limit);
- event CancelSetDailyLimit(address[] token, uint256[] limit);
-
- function reduceDailyLimits(address[] calldata token, uint256[] calldata amount) external;
-
- function preSetDailyLimit(address[] calldata token, uint256[] calldata limit) external;
-
- function cancelSetDailyLimit(address[] calldata token, uint256[] calldata limit) external;
-
- function comfirmSetDailyLimit(address[] calldata token, uint256[] calldata limit) external;
-
- function getDailyLimit(address wallet, address token) external view returns (uint256);
-
- function getSpentToday(address wallet, address token) external view returns (uint256);
-}
diff --git a/contracts/plugin/Simple2FA/ISimple2FA.sol b/contracts/plugin/Simple2FA/ISimple2FA.sol
deleted file mode 100644
index 8cccf607..00000000
--- a/contracts/plugin/Simple2FA/ISimple2FA.sol
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-interface ISimple2FA {
- function signerAddress(address addr) external view returns (address);
-
- function reset2FA(address new2FA) external;
-
- function preReset2FA(address new2FA) external;
-
- function comfirmReset2FA(address new2FA) external;
-}
diff --git a/contracts/plugin/Simple2FA/Simple2FA.sol b/contracts/plugin/Simple2FA/Simple2FA.sol
deleted file mode 100644
index 9711147b..00000000
--- a/contracts/plugin/Simple2FA/Simple2FA.sol
+++ /dev/null
@@ -1,111 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../BasePlugin.sol";
-import "./ISimple2FA.sol";
-import "../../safeLock/SafeLock.sol";
-import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
-import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
-import "../../base/ExecutionManager.sol";
-import "../../libraries/DecodeCalldata.sol";
-
-contract Simple2FA is BasePlugin, ISimple2FA, SafeLock {
- using ECDSA for bytes32;
- using MessageHashUtils for bytes32;
-
- struct User2FA {
- bool initialized;
- address _2FAAddr;
- }
-
- mapping(address => User2FA) private _2FA;
-
- constructor() SafeLock("PLUGIN_SIMPLE2FA_SAFELOCK_SLOT", 2 days) {}
-
- function preHook(address target, uint256 value, bytes calldata data) external pure override {
- (target, value, data);
- revert("Simple2FA: no need to call preHook");
- }
-
- function postHook(address target, uint256 value, bytes calldata data) external pure override {
- (target, value, data);
- revert("Simple2FA: no need to call postHook");
- }
-
- function guardHook(UserOperation calldata userOp, bytes32 userOpHash, bytes calldata guardData)
- external
- view
- override
- {
- (userOp);
- address _2FAAddr = _2FA[msg.sender]._2FAAddr;
- if (_2FAAddr != address(0)) {
- if (guardData.length == 0) {
- // # 1. function execute(address dest, uint256 value, bytes calldata func)
- // userOp.callData;
- bytes4 selector = bytes4(userOp.callData[0:4]);
- require(selector == ExecutionManager.execute.selector, "Simple2FA: invalid selector");
- // decode callData
- (address dest,, bytes memory func) = abi.decode(userOp.callData[4:], (address, uint256, bytes));
- // check dest
- require(dest == address(this), "Simple2FA: invalid dest");
-
- // # 2. preReset2FA or comfirmReset2FA
- // check func
- selector = DecodeCalldata.decodeMethodId(func);
- require(
- selector == this.preReset2FA.selector || selector == this.comfirmReset2FA.selector,
- "Simple2FA: invalid selector"
- );
- } else {
- // check signature
- bytes32 hash = userOpHash.toEthSignedMessageHash();
- (address recovered, ECDSA.RecoverError error,) = ECDSA.tryRecover(hash, guardData);
- if (error != ECDSA.RecoverError.NoError) {
- revert("Simple2FA: invalid signature");
- } else {
- require(recovered == _2FAAddr, "Simple2FA: invalid signature");
- }
- }
- } else {
- // 2FA not set, skip
- require(guardData.length == 0, "Simple2FA: invalid signature");
- }
- }
-
- function _init(bytes calldata data) internal virtual override {
- (address _2FAAddr) = abi.decode(data, (address));
- _2FA[msg.sender] = User2FA({initialized: true, _2FAAddr: _2FAAddr});
- }
-
- function _deInit() internal virtual override {
- delete _2FA[msg.sender];
- }
-
- function _supportsHook() internal pure virtual override returns (uint8 hookType) {
- return GUARD_HOOK;
- }
-
- function inited(address wallet) internal view virtual override returns (bool) {
- return _2FA[wallet].initialized;
- }
-
- function reset2FA(address new2FA) external override {
- _2FA[msg.sender]._2FAAddr = new2FA;
- }
-
- function preReset2FA(address new2FA) external override {
- bytes32 hash = keccak256(abi.encode(msg.sender, new2FA));
- _lock(hash);
- }
-
- function comfirmReset2FA(address new2FA) external override {
- bytes32 hash = keccak256(abi.encode(msg.sender, new2FA));
- _unlock(hash);
- _2FA[msg.sender]._2FAAddr = new2FA;
- }
-
- function signerAddress(address addr) external view override returns (address) {
- return _2FA[addr]._2FAAddr;
- }
-}
diff --git a/contracts/proxy/SoulWalletProxy.sol b/contracts/proxy/SoulWalletProxy.sol
new file mode 100644
index 00000000..4ef7433f
--- /dev/null
+++ b/contracts/proxy/SoulWalletProxy.sol
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+/**
+ * @title SoulWalletProxy
+ * @notice A proxy contract that forwards calls to an implementation contract
+ * @dev This proxy uses the EIP-1967 standard for storage slots
+ */
+contract SoulWalletProxy {
+ /**
+ * @notice Storage slot with the address of the current implementation
+ * @dev This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1
+ */
+ bytes32 private constant _IMPLEMENTATION_SLOT =
+ 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
+
+ /**
+ * @notice Initializes the proxy with the address of the initial implementation contract
+ * @param logic Address of the initial implementation
+ */
+ constructor(address logic) {
+ assembly ("memory-safe") {
+ sstore(_IMPLEMENTATION_SLOT, logic)
+ }
+ }
+
+ /**
+ * @notice Fallback function which forwards all calls to the implementation contract
+ * @dev Uses delegatecall to ensure the context remains within the proxy
+ */
+ fallback() external payable {
+ assembly {
+ /* not memory-safe */
+ let _singleton := and(
+ sload(_IMPLEMENTATION_SLOT),
+ 0xffffffffffffffffffffffffffffffffffffffff
+ )
+ calldatacopy(0, 0, calldatasize())
+ let success := delegatecall(
+ gas(),
+ _singleton,
+ 0,
+ calldatasize(),
+ 0,
+ 0
+ )
+ returndatacopy(0, 0, returndatasize())
+ if eq(success, 0) {
+ revert(0, returndatasize())
+ }
+ return(0, returndatasize())
+ }
+ }
+}
diff --git a/contracts/safeLock/ISafeLock.sol b/contracts/safeLock/ISafeLock.sol
deleted file mode 100644
index a629b4d8..00000000
--- a/contracts/safeLock/ISafeLock.sol
+++ /dev/null
@@ -1,8 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-interface ISafeLock {
- function getSafeLockPeriod() external view returns (uint64);
-
- function getSafeLockStatus(bytes32 _safeLockHash) external view returns (uint64);
-}
diff --git a/contracts/safeLock/SafeLock.sol b/contracts/safeLock/SafeLock.sol
deleted file mode 100644
index c89fd74d..00000000
--- a/contracts/safeLock/SafeLock.sol
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "./ISafeLock.sol";
-
-abstract contract SafeLock is ISafeLock {
- bytes32 private immutable _SAFELOCK_SLOT;
- uint64 private immutable _SAFELOCK_PERIOD;
-
- constructor(string memory safeLockSlotName, uint64 safeLockPeriod) {
- _SAFELOCK_SLOT = keccak256(abi.encodePacked(safeLockSlotName));
- require(safeLockPeriod > 0, "SafeLock: safeLockPeriod must be greater than 0");
- _SAFELOCK_PERIOD = safeLockPeriod;
- }
-
- function _safeLockStatus() internal view returns (mapping(bytes32 => uint64) storage safeLockStatus) {
- bytes32 slot = _SAFELOCK_SLOT;
- assembly {
- safeLockStatus.slot := slot
- }
- }
-
- function _now() private view returns (uint64) {
- return uint64(block.timestamp);
- }
-
- function getSafeLockPeriod() external view returns (uint64) {
- return _SAFELOCK_PERIOD;
- }
-
- function getSafeLockStatus(bytes32 _safeLockHash) external view returns (uint64 unLockTime) {
- unLockTime = _safeLockStatus()[_safeLockHash];
- }
-
- function _tryLock(bytes32 _safeLockHash) internal returns (bool) {
- mapping(bytes32 => uint64) storage safeLockStatus = _safeLockStatus();
- if (safeLockStatus[_safeLockHash] != 0) {
- return false;
- }
- safeLockStatus[_safeLockHash] = _now() + _SAFELOCK_PERIOD;
- return true;
- }
-
- function _lock(bytes32 _safeLockHash) internal {
- require(_tryLock(_safeLockHash), "SafeLock: already locked");
- }
-
- function _cancelLock(bytes32 _safeLockHash) internal {
- _safeLockStatus()[_safeLockHash] = 0;
- }
-
- function _tryUnlock(bytes32 _safeLockHash) internal returns (bool) {
- mapping(bytes32 => uint64) storage safeLockStatus = _safeLockStatus();
- uint64 unlockTime = safeLockStatus[_safeLockHash];
- if (unlockTime == 0 || unlockTime > _now()) {
- return false;
- }
- safeLockStatus[_safeLockHash] = 0;
- return true;
- }
-
- function _unlock(bytes32 _safeLockHash) internal {
- require(_tryUnlock(_safeLockHash), "SafeLock: not unlock time");
- }
-}
diff --git a/contracts/validator/BaseValidator.sol b/contracts/validator/BaseValidator.sol
deleted file mode 100644
index c50ce357..00000000
--- a/contracts/validator/BaseValidator.sol
+++ /dev/null
@@ -1,141 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "../interfaces/IValidator.sol";
-import "./libraries/ValidatorSigDecoder.sol";
-import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
-import "../libraries/TypeConversion.sol";
-import "../libraries/Errors.sol";
-import "../libraries/WebAuthn.sol";
-/**
- * @title BaseValidator
- * @dev An abstract contract providing core signature validation functionalities
- */
-
-abstract contract BaseValidator is IValidator {
- using ECDSA for bytes32;
- using TypeConversion for address;
- // Typehashes used for creating EIP-712 compliant messages
-
- bytes32 private constant SOUL_WALLET_MSG_TYPEHASH = keccak256("SoulWalletMessage(bytes32 message)");
-
- bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH =
- keccak256("EIP712Domain(uint256 chainId,address verifyingContract)");
- // Abstract functions that need to be implemented by derived contracts
-
- function _packSignatureHash(bytes32 hash, uint8 signatureType, uint256 validationData)
- internal
- pure
- virtual
- returns (bytes32);
-
- function _pack1271SignatureHash(bytes32 hash, uint8 signatureType, uint256 validationData)
- internal
- pure
- virtual
- returns (bytes32);
- /**
- * @dev Recovers the signer from a signature
- * @param signatureType The type of signature
- * @param rawHash The message hash that was signed
- * @param rawSignature The signature itself
- * @return recovered The recovered signer's address or public key as bytes32
- * @return success Indicates whether recovery was successful
- */
-
- function recover(uint8 signatureType, bytes32 rawHash, bytes calldata rawSignature)
- internal
- view
- returns (bytes32 recovered, bool success)
- {
- if (signatureType == 0x0 || signatureType == 0x1) {
- //ecdas recover
- (address recoveredAddr, ECDSA.RecoverError error,) = ECDSA.tryRecover(rawHash, rawSignature);
- if (error != ECDSA.RecoverError.NoError) {
- success = false;
- } else {
- success = true;
- }
- recovered = recoveredAddr.toBytes32();
- } else if (signatureType == 0x2 || signatureType == 0x3) {
- bytes32 publicKey = WebAuthn.recover(rawHash, rawSignature);
- if (publicKey == 0) {
- recovered = publicKey;
- success = false;
- } else {
- recovered = publicKey;
- success = true;
- }
- } else {
- revert Errors.INVALID_SIGNTYPE();
- }
- }
- /**
- * @dev Recovers the signer from a validator signature
- * @param rawHash The message hash that was signed
- * @param rawSignature The signature itself
- * @return validationData same as defined in EIP4337
- * @return recovered The recovered signer's address or public key as bytes32
- * @return success Indicates whether recovery was successful
- */
-
- function recoverSignature(bytes32 rawHash, bytes calldata rawSignature)
- external
- view
- override
- returns (uint256 validationData, bytes32 recovered, bool success)
- {
- uint8 signatureType;
- bytes calldata signature;
- (signatureType, validationData, signature) = ValidatorSigDecoder.decodeValidatorSignature(rawSignature);
-
- bytes32 hash = _packSignatureHash(rawHash, signatureType, validationData);
-
- (recovered, success) = recover(signatureType, hash, signature);
- }
- /**
- * @dev Recovers the signer from a EIP-1271 style signature
- * @param rawHash The message hash that was signed
- * @param rawSignature The signature itself
- * @return validationData same as defined in EIP4337
- * @return recovered The recovered signer's address or public key as bytes32
- * @return success Indicates whether recovery was successful
- */
-
- function recover1271Signature(bytes32 rawHash, bytes calldata rawSignature)
- external
- view
- override
- returns (uint256 validationData, bytes32 recovered, bool success)
- {
- uint8 signatureType;
- bytes calldata signature;
- (signatureType, validationData, signature) = ValidatorSigDecoder.decodeValidatorSignature(rawSignature);
- bytes32 hash = _pack1271SignatureHash(rawHash, signatureType, validationData);
- (recovered, success) = recover(signatureType, hash, signature);
- }
- /**
- * @dev Encodes a raw hash with EIP-712 compliant formatting
- * @param rawHash The raw hash to be encoded
- * @return The EIP-712 compliant encoded hash
- */
-
- function encodeRawHash(bytes32 rawHash) public view returns (bytes32) {
- bytes32 encode1271MessageHash = keccak256(abi.encode(SOUL_WALLET_MSG_TYPEHASH, rawHash));
- bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), address(msg.sender)));
- return keccak256(abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator, encode1271MessageHash));
- }
- /**
- * @dev Fetches the chain ID. This can be used for EIP-712 signature encoding
- * @return The chain ID
- */
-
- function getChainId() public view returns (uint256) {
- uint256 id;
- // solhint-disable-next-line no-inline-assembly
- assembly {
- id := chainid()
- }
- return id;
- }
-}
diff --git a/contracts/validator/DefaultValidator.sol b/contracts/validator/DefaultValidator.sol
deleted file mode 100644
index 8282d2b6..00000000
--- a/contracts/validator/DefaultValidator.sol
+++ /dev/null
@@ -1,79 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0
-pragma solidity ^0.8.20;
-
-import "./BaseValidator.sol";
-import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
-/**
- * @title DefaultValidator
- * @dev Provides default implementations for signature hash packing
- */
-
-contract DefaultValidator is BaseValidator {
- // Utility for Ethereum typed structured data hashing
- using MessageHashUtils for bytes32;
- // Utility for converting addresses to bytes32
- using TypeConversion for address;
-
- /**
- * @dev Packs the given hash with the specified validation data based on the signature type
- * - Type 0x0: Standard Ethereum signed message
- * - Type 0x1: Ethereum signed message combined with validation data
- * - Type 0x2: Passkey signature (unchanged hash)
- * - Type 0x3: Passkey signature combined with validation data
- * @param hash The original hash to be packed
- * @param signatureType The type of signature
- * @param validationData same as defined in EIP4337
- * @return packedHash The resulting hash after packing based on signature type
- */
- function _packSignatureHash(bytes32 hash, uint8 signatureType, uint256 validationData)
- internal
- pure
- override
- returns (bytes32 packedHash)
- {
- if (signatureType == 0x0) {
- packedHash = hash.toEthSignedMessageHash();
- } else if (signatureType == 0x1) {
- packedHash = keccak256(abi.encodePacked(hash, validationData)).toEthSignedMessageHash();
- } else if (signatureType == 0x2) {
- // passkey sign doesn't need toEthSignedMessageHash
- packedHash = hash;
- } else if (signatureType == 0x3) {
- // passkey sign doesn't need toEthSignedMessageHash
- packedHash = keccak256(abi.encodePacked(hash, validationData));
- } else {
- revert Errors.INVALID_SIGNTYPE();
- }
- }
- /**
- * @dev Packs the given hash for EIP-1271 compatible signatures. EIP-1271 represents signatures
- * that are verified by smart contracts themselves.
- * - Type 0x0: Unchanged hash.
- * - Type 0x1: Hash combined with validation data
- * - Type 0x2: Unchanged hash
- * - Type 0x3: Hash combined with validation data
- * @param hash The original hash to be packed
- * @param signatureType The type of signature
- * @param validationData Additional data used for certain signature types
- * @return packedHash The resulting hash after packing
- */
-
- function _pack1271SignatureHash(bytes32 hash, uint8 signatureType, uint256 validationData)
- internal
- pure
- override
- returns (bytes32 packedHash)
- {
- if (signatureType == 0x0) {
- packedHash = hash;
- } else if (signatureType == 0x1) {
- packedHash = keccak256(abi.encodePacked(hash, validationData));
- } else if (signatureType == 0x2) {
- packedHash = hash;
- } else if (signatureType == 0x3) {
- packedHash = keccak256(abi.encodePacked(hash, validationData));
- } else {
- revert Errors.INVALID_SIGNTYPE();
- }
- }
-}
diff --git a/contracts/validator/KeystoreValidator.sol b/contracts/validator/KeystoreValidator.sol
index a4af8703..a205679d 100644
--- a/contracts/validator/KeystoreValidator.sol
+++ b/contracts/validator/KeystoreValidator.sol
@@ -1,60 +1,78 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;
+import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
+import "../keystore/L1/interfaces/IKeyStoreValidator.sol";
+import "./libraries/ValidatorSigDecoder.sol";
+import "../libraries/WebAuthn.sol";
+import "../libraries/Errors.sol";
+import "../libraries/TypeConversion.sol";
-import "./BaseValidator.sol";
-/**
- * @title KeystoreValidator
- * @dev Validates signatures based on the Keystore standard
- */
-
-contract KeystoreValidator is BaseValidator {
- using ECDSA for bytes32;
+contract KeyStoreValidator is IKeyStoreValidator{
using TypeConversion for address;
- /**
- * @dev Packs the hash message with `signatureData.validationData`
- * @param hash The hash that needs to be packed with validationData
- * @param signatureType The type of the signature
- * @param validationData The data used for validation as per EIP-4337
- * @return packedHash The resultant packed hash
- */
+ function recoverSignature(
+ bytes32 rawHash,
+ bytes calldata rawSignature
+ ) external view returns (bytes32 recovered, bool success) {
+ uint8 signatureType;
+ bytes calldata signature;
+ uint256 validationData;
+ (signatureType, validationData, signature) = ValidatorSigDecoder
+ .decodeValidatorSignature(rawSignature);
+
+ bytes32 hash = _packSignatureHash(
+ rawHash,
+ signatureType,
+ validationData
+ );
+
+ (recovered, success) = recover(signatureType, hash, signature);
+ }
- function _packSignatureHash(bytes32 hash, uint8 signatureType, uint256 validationData)
- internal
- pure
- override
- returns (bytes32 packedHash)
- {
+ function _packSignatureHash(
+ bytes32 _hash,
+ uint8 signatureType,
+ uint256 validationData
+ ) internal pure returns (bytes32 packedHash) {
if (signatureType == 0x0) {
- packedHash = hash;
+ packedHash = _hash;
} else if (signatureType == 0x1) {
- packedHash = keccak256(abi.encodePacked(hash, validationData));
+ packedHash = keccak256(abi.encodePacked(_hash, validationData));
} else if (signatureType == 0x2) {
- // passkey sign doesn't need toEthSignedMessageHash
- packedHash = hash;
+ packedHash = _hash;
} else if (signatureType == 0x3) {
- // passkey sign doesn't need toEthSignedMessageHash
- packedHash = keccak256(abi.encodePacked(hash, validationData));
+ packedHash = keccak256(abi.encodePacked(_hash, validationData));
} else {
revert Errors.INVALID_SIGNTYPE();
}
}
- /**
- * @dev Function for packing 1271 signature hash
- * This implementation always reverts because `KeystoreValidator` doesn't support EIP-1271 signatures
- * @param hash The hash to be packed
- * @param signatureType The type of the signature
- * @param validationData The data used for validation as per EIP-4337
- * @return This function always reverts and never returns
- */
- function _pack1271SignatureHash(bytes32 hash, uint8 signatureType, uint256 validationData)
- internal
- pure
- virtual
- override
- returns (bytes32)
- {
- revert("KeystoreValidator doesn't support 1271");
+ function recover(
+ uint8 signatureType,
+ bytes32 rawHash,
+ bytes calldata rawSignature
+ ) internal view returns (bytes32 recovered, bool success) {
+ if (signatureType == 0x0 || signatureType == 0x1) {
+ //ecdas recover
+ (address recoveredAddr, ECDSA.RecoverError error, ) = ECDSA
+ .tryRecover(rawHash, rawSignature);
+ if (error != ECDSA.RecoverError.NoError) {
+ success = false;
+ } else {
+ success = true;
+ }
+ recovered = recoveredAddr.toBytes32();
+ } else if (signatureType == 0x2 || signatureType == 0x3) {
+ bytes32 publicKey = WebAuthn.recover(rawHash, rawSignature);
+ if (publicKey == 0) {
+ recovered = publicKey;
+ success = false;
+ } else {
+ recovered = publicKey;
+ success = true;
+ }
+ } else {
+ revert Errors.INVALID_SIGNTYPE();
+ }
}
}
diff --git a/contracts/validator/SoulWalletDefaultValidator.sol b/contracts/validator/SoulWalletDefaultValidator.sol
new file mode 100644
index 00000000..a8734395
--- /dev/null
+++ b/contracts/validator/SoulWalletDefaultValidator.sol
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+import {IValidator} from "@soulwallet-core/contracts/interface/IValidator.sol";
+import {IOwnable} from "@soulwallet-core/contracts/interface/IOwnable.sol";
+import {UserOperation} from "@soulwallet-core/contracts/interface/IHook.sol";
+import "@account-abstraction/contracts/core/Helpers.sol";
+import "./libraries/ValidatorSigDecoder.sol";
+import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
+import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
+import {Errors} from "../libraries/Errors.sol";
+import {TypeConversion} from "../libraries/TypeConversion.sol";
+import {WebAuthn} from "../libraries/WebAuthn.sol";
+
+/**
+ * @title SoulWalletDefaultValidator
+ * @dev A contract that implements the IValidator interface for validating user operations and signatures.
+ */
+contract SoulWalletDefaultValidator is IValidator {
+ // Magic value indicating a valid signature for ERC-1271 contracts
+ // bytes4(keccak256("isValidSignature(bytes32,bytes)")
+ bytes4 internal constant MAGICVALUE = 0x1626ba7e;
+ // Constants indicating different invalid states
+ bytes4 internal constant INVALID_ID = 0xffffffff;
+ bytes4 internal constant INVALID_TIME_RANGE = 0xfffffffe;
+ // ERC4337 constants
+ uint256 constant SIG_VALIDATION_FAILED = 1;
+ // Utility for Ethereum typed structured data hashing
+
+ using MessageHashUtils for bytes32;
+ using TypeConversion for address;
+
+ function validateUserOp(UserOperation calldata, bytes32 userOpHash, bytes calldata validatorSignature)
+ external
+ view
+ override
+ returns (uint256 validationData)
+ {
+ uint8 signatureType;
+ bytes calldata signature;
+ (signatureType, validationData, signature) = ValidatorSigDecoder.decodeValidatorSignature(validatorSignature);
+
+ bytes32 hash = _packSignatureHash(userOpHash, signatureType, validationData);
+ bytes32 recovered;
+ bool success;
+ (recovered, success) = recover(signatureType, hash, signature);
+ if (!success) {
+ return SIG_VALIDATION_FAILED;
+ }
+ bool ownerCheck = _isOwner(recovered);
+ if (!ownerCheck) {
+ return SIG_VALIDATION_FAILED;
+ }
+ return validationData;
+ }
+
+ function validateSignature(address, /*unused sender*/ bytes32 rawHash, bytes calldata validatorSignature)
+ external
+ view
+ override
+ returns (bytes4 magicValue)
+ {
+ uint8 signatureType;
+ bytes calldata signature;
+ uint256 validationData;
+ (signatureType, validationData, signature) = ValidatorSigDecoder.decodeValidatorSignature(validatorSignature);
+
+ bytes32 hash = _pack1271SignatureHash(rawHash, signatureType, validationData);
+ bytes32 recovered;
+ bool success;
+ (recovered, success) = recover(signatureType, hash, signature);
+ if (!success) {
+ return INVALID_ID;
+ }
+ bool ownerCheck = _isOwner(recovered);
+ if (!ownerCheck) {
+ return INVALID_ID;
+ }
+
+ if (validationData > 0) {
+ ValidationData memory _validationData = _parseValidationData(validationData);
+ bool outOfTimeRange =
+ (block.timestamp > _validationData.validUntil) || (block.timestamp < _validationData.validAfter);
+ if (outOfTimeRange) {
+ return INVALID_TIME_RANGE;
+ }
+ }
+ return MAGICVALUE;
+ }
+
+ function _packSignatureHash(bytes32 hash, uint8 signatureType, uint256 validationData)
+ internal
+ pure
+ returns (bytes32 packedHash)
+ {
+ if (signatureType == 0x0) {
+ packedHash = hash.toEthSignedMessageHash();
+ } else if (signatureType == 0x1) {
+ packedHash = keccak256(abi.encodePacked(hash, validationData)).toEthSignedMessageHash();
+ } else if (signatureType == 0x2) {
+ // passkey sign doesn't need toEthSignedMessageHash
+ packedHash = hash;
+ } else if (signatureType == 0x3) {
+ // passkey sign doesn't need toEthSignedMessageHash
+ packedHash = keccak256(abi.encodePacked(hash, validationData));
+ } else {
+ revert Errors.INVALID_SIGNTYPE();
+ }
+ }
+
+ function _pack1271SignatureHash(bytes32 hash, uint8 signatureType, uint256 validationData)
+ internal
+ pure
+ returns (bytes32 packedHash)
+ {
+ if (signatureType == 0x0) {
+ packedHash = hash;
+ } else if (signatureType == 0x1) {
+ packedHash = keccak256(abi.encodePacked(hash, validationData));
+ } else if (signatureType == 0x2) {
+ packedHash = hash;
+ } else if (signatureType == 0x3) {
+ packedHash = keccak256(abi.encodePacked(hash, validationData));
+ } else {
+ revert Errors.INVALID_SIGNTYPE();
+ }
+ }
+
+ function _isOwner(bytes32 recovered) private view returns (bool isOwner) {
+ return IOwnable(address(msg.sender)).isOwner(recovered);
+ }
+
+ function recover(uint8 signatureType, bytes32 rawHash, bytes calldata rawSignature)
+ internal
+ view
+ returns (bytes32 recovered, bool success)
+ {
+ if (signatureType == 0x0 || signatureType == 0x1) {
+ //ecdas recover
+ (address recoveredAddr, ECDSA.RecoverError error,) = ECDSA.tryRecover(rawHash, rawSignature);
+ if (error != ECDSA.RecoverError.NoError) {
+ success = false;
+ } else {
+ success = true;
+ }
+ recovered = recoveredAddr.toBytes32();
+ } else if (signatureType == 0x2 || signatureType == 0x3) {
+ bytes32 publicKey = WebAuthn.recover(rawHash, rawSignature);
+ if (publicKey == 0) {
+ recovered = publicKey;
+ success = false;
+ } else {
+ recovered = publicKey;
+ success = true;
+ }
+ } else {
+ revert Errors.INVALID_SIGNTYPE();
+ }
+ }
+
+ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
+ return interfaceId == type(IValidator).interfaceId;
+ }
+
+ function Init(bytes calldata) external override {}
+
+ function DeInit() external override {}
+}
diff --git a/contracts/validator/libraries/ValidatorSigDecoder.sol b/contracts/validator/libraries/ValidatorSigDecoder.sol
index b7d00ef8..30ca3224 100644
--- a/contracts/validator/libraries/ValidatorSigDecoder.sol
+++ b/contracts/validator/libraries/ValidatorSigDecoder.sol
@@ -81,28 +81,49 @@ library ValidatorSigDecoder {
*/
- function decodeValidatorSignature(bytes calldata validatorSignature)
+ function decodeValidatorSignature(
+ bytes calldata validatorSignature
+ )
internal
pure
- returns (uint8 signatureType, uint256 validationData, bytes calldata signature)
+ returns (
+ uint8 signatureType,
+ uint256 validationData,
+ bytes calldata signature
+ )
{
- require(validatorSignature.length >= 1, "validator signature too short");
+ require(
+ validatorSignature.length >= 1,
+ "validator signature too short"
+ );
signatureType = uint8(bytes1(validatorSignature[0:1]));
if (signatureType == 0x0) {
- require(validatorSignature.length == 66, "invalid validator signature length");
+ require(
+ validatorSignature.length == 66,
+ "invalid validator signature length"
+ );
validationData = 0;
signature = validatorSignature[1:66];
} else if (signatureType == 0x1) {
- require(validatorSignature.length == 98, "invalid validator signature length");
+ require(
+ validatorSignature.length == 98,
+ "invalid validator signature length"
+ );
validationData = uint256(bytes32(validatorSignature[1:33]));
signature = validatorSignature[33:98];
} else if (signatureType == 0x2) {
- require(validatorSignature.length >= 129, "invalid validator signature length");
+ require(
+ validatorSignature.length >= 129,
+ "invalid validator signature length"
+ );
validationData = 0;
signature = validatorSignature[1:];
} else if (signatureType == 0x3) {
- require(validatorSignature.length >= 161, "invalid validator signature length");
+ require(
+ validatorSignature.length >= 161,
+ "invalid validator signature length"
+ );
validationData = uint256(bytes32(validatorSignature[1:33]));
signature = validatorSignature[33:];
} else {
diff --git a/foundry.toml b/foundry.toml
index 8887525a..ad0a41db 100644
--- a/foundry.toml
+++ b/foundry.toml
@@ -1,25 +1,10 @@
[profile.default]
-src = 'contracts'
+src = "contracts"
test = 'test'
out = "out"
libs = ["lib"]
-gas_reports = [
- "EntryPoint",
- "KeyStore",
- "SoulWalletFactory",
- "SoulWalletProxy",
- "SoulWallet",
- "SecurityControlModule",
- "SocialRecoveryModule",
- "TrustedModuleManager",
- "TrustedPluginManager",
- "Dailylimit",
- "Upgrade",
- "ERC20Paymaster",
- "Simple2FA"
-]
-# gas_reports_ignore = ["dev","test"]
-solc = "0.8.21"
+
+solc = "0.8.23"
optimizer = true
optimizer_runs = 100000
via_ir = true
@@ -37,4 +22,4 @@ optimism = "${OPTIMISM_RPC_URL}"
goerli = { key = "${GOERLI_SCAN_API_KEY}", chain = "goerli" }
optimismgoerli = { key = "${OPTIMISM_GOERLI_SCAN_API_KEY}", chain = "optimism-goerli" }
-# See more config options https://github.com/foundry-rs/foundry/tree/master/config
+# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
diff --git a/lib/SoulWalletCore/.github/workflows/test.yml b/lib/SoulWalletCore/.github/workflows/test.yml
new file mode 100644
index 00000000..44e34cb8
--- /dev/null
+++ b/lib/SoulWalletCore/.github/workflows/test.yml
@@ -0,0 +1,34 @@
+name: test
+
+on: workflow_dispatch
+
+env:
+ FOUNDRY_PROFILE: ci
+
+jobs:
+ check:
+ strategy:
+ fail-fast: true
+
+ name: Foundry project
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ submodules: recursive
+
+ - name: Install Foundry
+ uses: foundry-rs/foundry-toolchain@v1
+ with:
+ version: nightly
+
+ - name: Run Forge build
+ run: |
+ forge --version
+ forge build
+ id: build
+
+ - name: Run Forge tests
+ run: |
+ forge test -vvv
+ id: test
diff --git a/lib/SoulWalletCore/.gitignore b/lib/SoulWalletCore/.gitignore
new file mode 100644
index 00000000..379e35da
--- /dev/null
+++ b/lib/SoulWalletCore/.gitignore
@@ -0,0 +1,22 @@
+# Compiler files
+cache/
+out/
+
+# Ignores development broadcast logs
+!/broadcast
+/broadcast/*/31337/
+/broadcast/**/dry-run/
+
+# Docs
+docs/
+
+# Mac files
+.DS_Store
+
+# Dotenv file
+.env
+**/artifacts/
+compiler_config.json
+.deps/
+node_modules
+package-lock.json
diff --git a/lib/SoulWalletCore/.gitmodules b/lib/SoulWalletCore/.gitmodules
new file mode 100644
index 00000000..24f93154
--- /dev/null
+++ b/lib/SoulWalletCore/.gitmodules
@@ -0,0 +1,12 @@
+[submodule "lib/forge-std"]
+ path = lib/forge-std
+ url = https://github.com/foundry-rs/forge-std
+[submodule "lib/openzeppelin-contracts"]
+ path = lib/openzeppelin-contracts
+ url = https://github.com/Openzeppelin/openzeppelin-contracts
+ branch = release-v5.0
+[submodule "lib/account-abstraction"]
+ path = lib/account-abstraction
+ url = https://github.com/SoulWallet/account-abstraction
+ branch = v0.6.0-with-openzeppelin-v5
+
diff --git a/lib/SoulWalletCore/LICENSE b/lib/SoulWalletCore/LICENSE
new file mode 100644
index 00000000..78651f6f
--- /dev/null
+++ b/lib/SoulWalletCore/LICENSE
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and`show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/lib/SoulWalletCore/README.md b/lib/SoulWalletCore/README.md
new file mode 100644
index 00000000..93d350f9
--- /dev/null
+++ b/lib/SoulWalletCore/README.md
@@ -0,0 +1,64 @@
+# SoulWalletCore
+
+SoulWalletCore is a flexible and reusable smart contract wallet framework compliant with the EIP-4337 standard. It aims to provide a simple, adaptable, and easily integrable foundation for various wallet functionalities and extensions.
+
+## ⚠️ Disclaimer
+
+**The SoulWalletCore has not been audited and is provided as-is. It is not recommended for use in production environments.** Users and developers should exercise caution and use at their own risk.
+
+## Features
+
+- **EIP-4337 Compliant**: Ensures alignment with the latest developments in the Ethereum community.
+- **Modular Design**: Facilitates easy addition or removal of features by developers according to their needs.
+- **Reusability**: Designed for easy reuse across different projects.
+- **Wallet Implementation Examples**: Includes multiple wallet examples based on SoulWalletCore to help developers get started quickly.
+
+## Directory Structure
+
+- `contracts/` - Contains all contract codes.
+ - `base/` - Base contracts providing core functionalities.
+ - `interface/` - Definitions of contract interfaces.
+ - `snippets/` - Reusable code snippets.
+ - `utils/` - Utility and helper contracts.
+ - `validators/` - Contracts related to validators.
+- `examples/` - Examples of wallets developed based on SoulWalletCore.
+
+## Getting Started
+
+To start using SoulWalletCore, clone the repository:
+
+```sh
+git clone https://github.com/SoulWallet/SoulWalletCore.git
+cd SoulWalletCore
+```
+
+Next, choose or modify the contract examples as per your requirements.
+
+## Example Usage
+
+Refer to the examples in the `examples/` directory to understand how to build custom wallets based on SoulWalletCore.
+
+- [BasicModularAccount](examples/BasicModularAccount.sol): A basic example of a modular account.
+- [CustomAccessModularAccount](examples/CustomAccessModularAccount.sol): An example with custom permission.
+- [AddFunctionDemo](examples/AddFunctionDemo/): An implementation example with a custom function added.
+- [ModularAccountWithBuildinEOAValidator](examples/ModularAccountWithBuildinEOAValidator.sol): An example of a modular account with built-in EOA signature validation.
+- [UpgradableModularAccount](examples/UpgradableModularAccount.sol): An example of an upgradable modular account.
+ - Note: Due to the flexibility in implementing upgradable contracts, it is not implemented in SoulWalletCore. However, you can refer to this example.
+
+## Contributions
+
+We welcome contributions in any form, be it feature enhancements, bug reports, or documentation updates. Please submit pull requests or issues through GitHub.
+
+## License
+
+This project is licensed under the [GPL-3.0 License](LICENSE)
+
+### License Clarification
+
+This project makes use of code from the [eth-infinitism/account-abstraction](https://github.com/eth-infinitism/account-abstraction) repository, which is licensed under the GPL-3.0 license. However, all code developed for this project is based on the MIT license.
+
+#### Using Our Code in Non-GPL-3.0 Projects
+
+If you intend to use our code in projects that are not licensed under GPL-3.0, you can directly copy the files that are independently licensed under MIT from our repository into your project. This approach ensures compliance with the MIT license, provided that the copied files are standalone and do not depend on any GPL-3.0 licensed code from our project.
+
+Please be aware that while you are free to use, modify, and distribute these MIT-licensed files, the GPL-3.0 licensed code from the eth-infinitism/account-abstraction repository may impose certain restrictions if used in your projects. It is important to ensure that your use of these files adheres to the respective license terms.
diff --git a/lib/SoulWalletCore/contracts/SoulWalletCore.sol b/lib/SoulWalletCore/contracts/SoulWalletCore.sol
new file mode 100644
index 00000000..81e96dcd
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/SoulWalletCore.sol
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IAccount, UserOperation} from "./interface/IAccount.sol";
+import {EntryPointManager} from "./base/EntryPointManager.sol";
+import {FallbackManager} from "./base/FallbackManager.sol";
+import {ModuleManager} from "./base/ModuleManager.sol";
+import {OwnerManager} from "./base/OwnerManager.sol";
+import {StandardExecutor} from "./base/StandardExecutor.sol";
+import {ValidatorManager} from "./base/ValidatorManager.sol";
+import {HookManager} from "./base/HookManager.sol";
+import {SignatureDecoder} from "./utils/SignatureDecoder.sol";
+import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";
+import {UserOperationLib} from "./utils/UserOperationLib.sol";
+
+contract SoulWalletCore is
+ IAccount,
+ IERC1271,
+ EntryPointManager,
+ OwnerManager,
+ ModuleManager,
+ HookManager,
+ StandardExecutor,
+ ValidatorManager,
+ FallbackManager
+{
+ constructor(address _entryPoint) EntryPointManager(_entryPoint) {}
+
+ function isValidSignature(bytes32 hash, bytes calldata signature)
+ public
+ view
+ virtual
+ override
+ returns (bytes4 magicValue)
+ {
+ (address validator, bytes calldata validatorSignature, bytes calldata hookSignature) =
+ SignatureDecoder.signatureSplit(signature);
+
+ /*
+ Warning!!!
+ This function uses `return` to terminate the execution of the entire contract.
+ If any `Hook` fails, this function will stop the contract's execution and
+ return `bytes4(0)`, skipping all the subsequent unexecuted code.
+ */
+ _preIsValidSignatureHook(hash, hookSignature);
+
+ /*
+ When any hook execution fails, this line will not be executed.
+ */
+ return _isValidSignature(hash, validator, validatorSignature);
+ }
+
+ /**
+ * @dev If you need to redefine the signatures structure, please override this function.
+ */
+ function _decodeSignature(bytes calldata signature)
+ internal
+ view
+ virtual
+ returns (address validator, bytes calldata validatorSignature, bytes calldata hookSignature)
+ {
+ return SignatureDecoder.signatureSplit(signature);
+ }
+
+ function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)
+ public
+ payable
+ virtual
+ override
+ returns (uint256 validationData)
+ {
+ _onlyEntryPoint();
+
+ assembly ("memory-safe") {
+ if missingAccountFunds {
+ // ignore failure (its EntryPoint's job to verify, not account.)
+ pop(call(gas(), caller(), missingAccountFunds, 0x00, 0x00, 0x00, 0x00))
+ }
+ }
+ (address validator, bytes calldata validatorSignature, bytes calldata hookSignature) =
+ _decodeSignature(UserOperationLib.getSignature(userOp));
+
+ /*
+ Warning!!!
+ This function uses `return` to terminate the execution of the entire contract.
+ If any `Hook` fails, this function will stop the contract's execution and
+ return `SIG_VALIDATION_FAILED`, skipping all the subsequent unexecuted code.
+ */
+ _preUserOpValidationHook(userOp, userOpHash, missingAccountFunds, hookSignature);
+
+ /*
+ When any hook execution fails, this line will not be executed.
+ */
+ return _validateUserOp(userOp, userOpHash, validator, validatorSignature);
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/base/Authority.sol b/lib/SoulWalletCore/contracts/base/Authority.sol
new file mode 100644
index 00000000..fe00e497
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/base/Authority.sol
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {AuthoritySnippet} from "../snippets/Authority.sol";
+
+abstract contract Authority is AuthoritySnippet {
+ /**
+ * a custom error for caller must be self or module
+ */
+ error CALLER_MUST_BE_SELF_OR_MODULE();
+
+ /**
+ * a custom error for caller must be module
+ */
+ error CALLER_MUST_BE_MODULE();
+
+ /**
+ * @notice Ensures the calling contract is an authorized module
+ */
+ function _onlyModule() internal view override {
+ if (!_isAuthorizedModule()) {
+ revert CALLER_MUST_BE_MODULE();
+ }
+ }
+
+ /**
+ * @notice Ensures the calling contract is either the Authority contract itself or an authorized module
+ * @dev Uses the inherited `_isAuthorizedModule()` from ModuleAuth for module-based authentication
+ */
+ function _onlySelfOrModule() internal view override {
+ if (msg.sender != address(this) && !_isAuthorizedModule()) {
+ revert CALLER_MUST_BE_SELF_OR_MODULE();
+ }
+ }
+
+ /**
+ * @dev Check if access to the following functions:
+ * 1. setFallbackHandler
+ */
+ function fallbackManagementAccess() internal view virtual override {
+ _onlySelfOrModule();
+ }
+
+ /**
+ * @dev Check if access to the following functions:
+ * 1. installHook
+ * 2. uninstallHook
+ * 3. installModule
+ * 4. uninstallModule
+ */
+ function pluginManagementAccess() internal view virtual override {
+ _onlySelfOrModule();
+ }
+
+ /**
+ * @dev Check if access to the following functions:
+ * 1. addOwner
+ * 2. removeOwner
+ * 3. resetOwner
+ */
+ function ownerManagementAccess() internal view virtual override {
+ _onlySelfOrModule();
+ }
+
+ /**
+ * @dev Check if access to the following functions:
+ * 1. execute
+ * 2. executeBatch
+ */
+ function executorAccess() internal view virtual override {
+ _onlyEntryPoint();
+ }
+
+ /**
+ * @dev Check if access to the following functions:
+ * 1. installValidator
+ * 2. uninstallValidator
+ */
+ function validatorManagementAccess() internal view virtual override {
+ _onlySelfOrModule();
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/base/EntryPointManager.sol b/lib/SoulWalletCore/contracts/base/EntryPointManager.sol
new file mode 100644
index 00000000..c9e5d1bd
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/base/EntryPointManager.sol
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {Authority} from "./Authority.sol";
+
+abstract contract EntryPointManager is Authority {
+ /**
+ * @dev use immutable to save gas
+ */
+ address internal immutable _ENTRY_POINT;
+
+ /**
+ * a custom error for caller must be entry point
+ */
+ error CALLER_MUST_BE_ENTRY_POINT();
+
+ constructor(address _entryPoint) {
+ _ENTRY_POINT = _entryPoint;
+ }
+
+ function entryPoint() external view returns (address) {
+ return _ENTRY_POINT;
+ }
+
+ /**
+ * @notice Ensures the calling contract is the entrypoint
+ */
+ function _onlyEntryPoint() internal view override {
+ if (msg.sender != _ENTRY_POINT) {
+ revert CALLER_MUST_BE_ENTRY_POINT();
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/base/FallbackManager.sol b/lib/SoulWalletCore/contracts/base/FallbackManager.sol
new file mode 100644
index 00000000..be20f9ad
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/base/FallbackManager.sol
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {Authority} from "./Authority.sol";
+import {IFallbackManager} from "../interface/IFallbackManager.sol";
+import {AccountStorage} from "../utils/AccountStorage.sol";
+import {FallbackManagerSnippet} from "../snippets/FallbackManager.sol";
+
+abstract contract FallbackManager is IFallbackManager, Authority, FallbackManagerSnippet {
+ receive() external payable virtual {}
+
+ /**
+ * @dev Sets the address of the fallback handler contract
+ * @param fallbackContract The address of the new fallback handler contract
+ */
+ function _setFallbackHandler(address fallbackContract) internal virtual override {
+ AccountStorage.layout().defaultFallbackContract = fallbackContract;
+ }
+
+ /**
+ * @notice Fallback function that forwards all requests to the fallback handler contract
+ * @dev The request is forwarded using a STATICCALL
+ * It ensures that the state of the contract doesn't change even if the fallback function has state-changing operations
+ */
+ fallback() external payable virtual {
+ address fallbackContract = AccountStorage.layout().defaultFallbackContract;
+ assembly ("memory-safe") {
+ function allocate(length) -> pos {
+ pos := mload(0x40)
+ mstore(0x40, add(pos, length))
+ }
+
+ if iszero(fallbackContract) { return(0, 0) }
+ let calldataPtr := allocate(calldatasize())
+ calldatacopy(calldataPtr, 0, calldatasize())
+
+ let result := staticcall(gas(), fallbackContract, calldataPtr, calldatasize(), 0, 0)
+
+ let returndataPtr := allocate(returndatasize())
+ returndatacopy(returndataPtr, 0, returndatasize())
+
+ if iszero(result) { revert(returndataPtr, returndatasize()) }
+ return(returndataPtr, returndatasize())
+ }
+ }
+
+ /**
+ * @notice Sets the address of the fallback handler and emits the FallbackChanged event
+ * @param fallbackContract The address of the new fallback handler
+ */
+ function setFallbackHandler(address fallbackContract) external virtual override {
+ fallbackManagementAccess();
+ _setFallbackHandler(fallbackContract);
+ emit FallbackChanged(fallbackContract);
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/base/HookManager.sol b/lib/SoulWalletCore/contracts/base/HookManager.sol
new file mode 100644
index 00000000..4e093ea5
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/base/HookManager.sol
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {Authority} from "./Authority.sol";
+import {IHookManager} from "../interface/IHookManager.sol";
+import {IHook} from "../interface/IHook.sol";
+import {IPluggable} from "../interface/IPluggable.sol";
+import {IAccount, UserOperation} from "../interface/IAccount.sol";
+import {AccountStorage} from "../utils/AccountStorage.sol";
+import {AddressLinkedList} from "../utils/AddressLinkedList.sol";
+import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
+import {SIG_VALIDATION_FAILED} from "../utils/Constants.sol";
+import {HookManagerSnippet} from "../snippets/HookManager.sol";
+
+abstract contract HookManager is Authority, IHookManager, HookManagerSnippet {
+ using AddressLinkedList for mapping(address => address);
+
+ error INVALID_HOOK();
+ error INVALID_HOOK_TYPE();
+ error HOOK_NOT_EXISTS();
+ error INVALID_HOOK_SIGNATURE();
+
+ bytes4 private constant INTERFACE_ID_HOOK = type(IHook).interfaceId;
+
+ /*
+ Capability flags for the hook:
+ 0x01: preIsValidSignatureHook: execute before isValidSignature
+ 0x02: preUserOpValidationHook: execute before validateUserOp
+ */
+
+ uint8 internal constant PRE_IS_VALID_SIGNATURE_HOOK = 1 << 0;
+ uint8 internal constant PRE_USER_OP_VALIDATION_HOOK = 1 << 1;
+
+ /**
+ * @dev Check if the hook is installed
+ * @param hook The address of the hook
+ */
+ function isInstalledHook(address hook) external view override returns (bool) {
+ return AccountStorage.layout().preUserOpValidationHook.isExist(hook)
+ || AccountStorage.layout().preIsValidSignatureHook.isExist(hook);
+ }
+
+ /**
+ * @dev checks whether a address is a valid hook
+ * note: If you need to extend the interface, override this function
+ * @param hookAddress hook address
+ */
+ function _isSupportsHookInterface(address hookAddress) internal view virtual override returns (bool supported) {
+ bytes memory callData = abi.encodeWithSelector(IERC165.supportsInterface.selector, INTERFACE_ID_HOOK);
+ assembly ("memory-safe") {
+ // memorySafe: The scratch space between memory offset 0 and 64.
+
+ let result := staticcall(gas(), hookAddress, add(callData, 0x20), mload(callData), 0x00, 0x20)
+ if gt(result, 0) { supported := mload(0x00) }
+ }
+ }
+
+ /**
+ * @dev Install a hook
+ * @param hookAddress The address of the hook
+ * @param initData The init data of the hook
+ * @param capabilityFlags Capability flags for the hook
+ */
+ function _installHook(address hookAddress, bytes memory initData, uint8 capabilityFlags)
+ internal
+ virtual
+ override
+ {
+ if (_isSupportsHookInterface(hookAddress) == false) {
+ revert INVALID_HOOK();
+ }
+
+ if (capabilityFlags & (PRE_USER_OP_VALIDATION_HOOK | PRE_IS_VALID_SIGNATURE_HOOK) == 0) {
+ revert INVALID_HOOK_TYPE();
+ }
+ if (capabilityFlags & PRE_IS_VALID_SIGNATURE_HOOK == PRE_IS_VALID_SIGNATURE_HOOK) {
+ AccountStorage.layout().preIsValidSignatureHook.add(hookAddress);
+ }
+ if (capabilityFlags & PRE_USER_OP_VALIDATION_HOOK == PRE_USER_OP_VALIDATION_HOOK) {
+ AccountStorage.layout().preUserOpValidationHook.add(hookAddress);
+ }
+
+ bytes4 invalidHookSelector = INVALID_HOOK.selector;
+ bytes memory callData = abi.encodeWithSelector(IPluggable.Init.selector, initData);
+ assembly ("memory-safe") {
+ // memorySafe: The scratch space between memory offset 0 and 64.
+
+ let result := call(gas(), hookAddress, 0, add(callData, 0x20), mload(callData), 0x00, 0x00)
+ if iszero(result) {
+ mstore(0x00, invalidHookSelector)
+ revert(0x00, 4)
+ }
+ }
+
+ emit HookInstalled(hookAddress);
+ }
+
+ /**
+ * @dev Uninstall a hook
+ * 1. revert if the hook is not installed
+ * 2. call hook.deInit() with 1M gas, emit HOOK_UNINSTALL_WITHERROR if the call failed
+ * @param hookAddress The address of the hook
+ */
+ function _uninstallHook(address hookAddress) internal virtual override {
+ bool removed1 = AccountStorage.layout().preIsValidSignatureHook.tryRemove(hookAddress);
+ bool removed2 = AccountStorage.layout().preUserOpValidationHook.tryRemove(hookAddress);
+ if (removed1 == false && removed2 == false) {
+ revert HOOK_NOT_EXISTS();
+ }
+
+ (bool success,) =
+ hookAddress.call{gas: 1000000 /* max to 1M gas */ }(abi.encodeWithSelector(IPluggable.DeInit.selector));
+
+ if (success) {
+ emit HookUninstalled(hookAddress);
+ } else {
+ emit HookUninstalledwithError(hookAddress);
+ }
+ }
+
+ /**
+ * @dev Uninstall a hook
+ * @param hookAddress The address of the hook
+ */
+ function uninstallHook(address hookAddress) external virtual override {
+ pluginManagementAccess();
+ _uninstallHook(hookAddress);
+ }
+
+ /**
+ * @dev List all installed hooks
+ */
+ function listHook()
+ external
+ view
+ virtual
+ override
+ returns (address[] memory preIsValidSignatureHooks, address[] memory preUserOpValidationHooks)
+ {
+ mapping(address => address) storage preIsValidSignatureHook = AccountStorage.layout().preIsValidSignatureHook;
+ preIsValidSignatureHooks =
+ preIsValidSignatureHook.list(AddressLinkedList.SENTINEL_ADDRESS, preIsValidSignatureHook.size());
+ mapping(address => address) storage preUserOpValidationHook = AccountStorage.layout().preUserOpValidationHook;
+ preUserOpValidationHooks =
+ preUserOpValidationHook.list(AddressLinkedList.SENTINEL_ADDRESS, preUserOpValidationHook.size());
+ }
+
+ /**
+ * @dev Get the next hook signature
+ * @param hookSignatures The hook signatures
+ * @param cursor The cursor of the hook signatures
+ */
+ function _nextHookSignature(bytes calldata hookSignatures, uint256 cursor)
+ private
+ pure
+ returns (address _hookAddr, uint256 _cursorFrom, uint256 _cursorEnd)
+ {
+ /*
+ +--------------------------------------------------------------------------------+
+ | multi-hookSignature |
+ +--------------------------------------------------------------------------------+
+ | hookSignature | hookSignature | ... | hookSignature |
+ +-----------------------+--------------------------------------------------------+
+ | dynamic data | dynamic data | ... | dynamic data |
+ +--------------------------------------------------------------------------------+
+
+ +----------------------------------------------------------------------+
+ | hookSignature |
+ +----------------------------------------------------------------------+
+ | Hook address | hookSignature length | hookSignature |
+ +----------------------+-----------------------------------------------+
+ | 20bytes | 4bytes(uint32) | bytes |
+ +----------------------------------------------------------------------+
+ */
+ uint256 dataLen = hookSignatures.length;
+
+ if (dataLen > cursor) {
+ assembly ("memory-safe") {
+ let ptr := add(hookSignatures.offset, cursor)
+ _hookAddr := shr(0x60, calldataload(ptr))
+ if iszero(_hookAddr) { revert(0, 0) }
+ _cursorFrom := add(cursor, 24) //20+4
+ let guardSigLen := shr(0xe0, calldataload(add(ptr, 20)))
+ if iszero(guardSigLen) { revert(0, 0) }
+ _cursorEnd := add(_cursorFrom, guardSigLen)
+ }
+ }
+ }
+
+ /**
+ * @dev Call preIsValidSignatureHook for all installed hooks
+ * @param hash The hash of the data to be signed
+ * @param hookSignatures The hook signatures
+ */
+ function _preIsValidSignatureHook(bytes32 hash, bytes calldata hookSignatures) internal view virtual {
+ address _hookAddr;
+ uint256 _cursorFrom;
+ uint256 _cursorEnd;
+ (_hookAddr, _cursorFrom, _cursorEnd) = _nextHookSignature(hookSignatures, _cursorEnd);
+
+ mapping(address => address) storage preIsValidSignatureHook = AccountStorage.layout().preIsValidSignatureHook;
+ address hookAddress = preIsValidSignatureHook[AddressLinkedList.SENTINEL_ADDRESS];
+ while (uint160(hookAddress) > AddressLinkedList.SENTINEL_UINT) {
+ bytes calldata currentHookSignature;
+ if (hookAddress == _hookAddr) {
+ currentHookSignature = hookSignatures[_cursorFrom:_cursorEnd];
+ // next
+ _hookAddr = address(0);
+ if (_cursorEnd > 0) {
+ (_hookAddr, _cursorFrom, _cursorEnd) = _nextHookSignature(hookSignatures, _cursorEnd);
+ }
+ } else {
+ currentHookSignature = hookSignatures[0:0];
+ }
+
+ bytes memory callData =
+ abi.encodeWithSelector(IHook.preIsValidSignatureHook.selector, hash, currentHookSignature);
+ assembly ("memory-safe") {
+ // memorySafe: The scratch space between memory offset 0 and 64.
+
+ let result := staticcall(gas(), hookAddress, add(callData, 0x20), mload(callData), 0x00, 0x00)
+ if iszero(result) {
+ /*
+ Warning!!!
+ This function uses `return` to terminate the execution of the entire contract.
+ If any `Hook` fails, this function will stop the contract's execution and
+ return `bytes4(0)`, skipping all the subsequent unexecuted code.
+ */
+ mstore(0x00, 0x00000000)
+ return(0x00, 0x20)
+ }
+ }
+
+ hookAddress = preIsValidSignatureHook[hookAddress];
+ }
+
+ if (_hookAddr != address(0)) {
+ revert INVALID_HOOK_SIGNATURE();
+ }
+ }
+
+ /**
+ * @dev Call preUserOpValidationHook for all installed hooks
+ *
+ * Warning!!!
+ * This function uses `return` to terminate the execution of the entire contract.
+ * If any `Hook` fails, this function will stop the contract's execution and
+ * return `SIG_VALIDATION_FAILED`, skipping all the subsequent unexecuted code.
+ *
+ *
+ *
+ * @param userOp The UserOperation
+ * @param userOpHash The hash of the UserOperation
+ * @param missingAccountFunds The missing account funds
+ * @param hookSignatures The hook signatures
+ */
+ function _preUserOpValidationHook(
+ UserOperation calldata userOp,
+ bytes32 userOpHash,
+ uint256 missingAccountFunds,
+ bytes calldata hookSignatures
+ ) internal virtual {
+ address _hookAddr;
+ uint256 _cursorFrom;
+ uint256 _cursorEnd;
+ (_hookAddr, _cursorFrom, _cursorEnd) = _nextHookSignature(hookSignatures, _cursorEnd);
+
+ mapping(address => address) storage preUserOpValidationHook = AccountStorage.layout().preUserOpValidationHook;
+ address hookAddress = preUserOpValidationHook[AddressLinkedList.SENTINEL_ADDRESS];
+ while (uint160(hookAddress) > AddressLinkedList.SENTINEL_UINT) {
+ bytes calldata currentHookSignature;
+ if (hookAddress == _hookAddr) {
+ currentHookSignature = hookSignatures[_cursorFrom:_cursorEnd];
+ // next
+ _hookAddr = address(0);
+ if (_cursorEnd > 0) {
+ (_hookAddr, _cursorFrom, _cursorEnd) = _nextHookSignature(hookSignatures, _cursorEnd);
+ }
+ } else {
+ currentHookSignature = hookSignatures[0:0];
+ }
+
+ bytes memory callData = abi.encodeWithSelector(
+ IHook.preUserOpValidationHook.selector, userOp, userOpHash, missingAccountFunds, currentHookSignature
+ );
+ assembly ("memory-safe") {
+ // memorySafe: The scratch space between memory offset 0 and 64.
+
+ let result := call(gas(), hookAddress, 0, add(callData, 0x20), mload(callData), 0x00, 0x00)
+ if iszero(result) {
+ /*
+ Warning!!!
+ This function uses `return` to terminate the execution of the entire contract.
+ If any `Hook` fails, this function will stop the contract's execution and
+ return `SIG_VALIDATION_FAILED`, skipping all the subsequent unexecuted code.
+ */
+ mstore(0x00, SIG_VALIDATION_FAILED)
+ return(0x00, 0x20)
+ }
+ }
+
+ hookAddress = preUserOpValidationHook[hookAddress];
+ }
+ if (_hookAddr != address(0)) {
+ revert INVALID_HOOK_SIGNATURE();
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/base/ModuleManager.sol b/lib/SoulWalletCore/contracts/base/ModuleManager.sol
new file mode 100644
index 00000000..10950687
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/base/ModuleManager.sol
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IModule} from "../interface/IModule.sol";
+import {IPluggable} from "../interface/IPluggable.sol";
+import {IModuleManager} from "../interface/IModuleManager.sol";
+import {AccountStorage} from "../utils/AccountStorage.sol";
+import {Authority} from "./Authority.sol";
+import {AddressLinkedList} from "../utils/AddressLinkedList.sol";
+import {SelectorLinkedList} from "../utils/SelectorLinkedList.sol";
+import {ModuleManagerSnippet} from "../snippets/ModuleManager.sol";
+import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
+
+abstract contract ModuleManager is IModuleManager, Authority, ModuleManagerSnippet {
+ using AddressLinkedList for mapping(address => address);
+ using SelectorLinkedList for mapping(bytes4 => bytes4);
+
+ error MODULE_EXECUTE_FROM_MODULE_RECURSIVE();
+ error INVALID_MODULE();
+ error CALLER_MUST_BE_AUTHORIZED_MODULE();
+
+ bytes4 private constant INTERFACE_ID_MODULE = type(IModule).interfaceId;
+
+ function _moduleMapping() internal view returns (mapping(address => address) storage modules) {
+ modules = AccountStorage.layout().modules;
+ }
+
+ /**
+ * @dev checks whether the caller is a authorized module
+ * caller: msg.sender
+ * method: msg.sig
+ * @return bool
+ */
+ function _isAuthorizedModule() internal view override returns (bool) {
+ return AccountStorage.layout().moduleSelectors[msg.sender].isExist(msg.sig);
+ }
+
+ /**
+ * @dev checks whether a address is a authorized module
+ */
+ function _isInstalledModule(address module) internal view virtual override returns (bool) {
+ return _moduleMapping().isExist(module);
+ }
+
+ /**
+ * @dev checks whether a address is a installed module
+ */
+ function isInstalledModule(address module) external view override returns (bool) {
+ return _isInstalledModule(module);
+ }
+
+ /**
+ * @dev checks whether a address is a module
+ * note: If you need to extend the interface, override this function
+ * @param moduleAddress module address
+ */
+ function _isSupportsModuleInterface(address moduleAddress)
+ internal
+ view
+ virtual
+ override
+ returns (bool supported)
+ {
+ bytes memory callData = abi.encodeWithSelector(IERC165.supportsInterface.selector, INTERFACE_ID_MODULE);
+ assembly ("memory-safe") {
+ // memorySafe: The scratch space between memory offset 0 and 64.
+
+ let result := staticcall(gas(), moduleAddress, add(callData, 0x20), mload(callData), 0x00, 0x20)
+ if gt(result, 0) { supported := mload(0x00) }
+ }
+ }
+
+ /**
+ * @dev install a module
+ * @param moduleAddress module address
+ * @param initData module init data
+ * @param selectors function selectors that the module is allowed to call
+ */
+ function _installModule(address moduleAddress, bytes memory initData, bytes4[] memory selectors)
+ internal
+ virtual
+ override
+ {
+ if (_isSupportsModuleInterface(moduleAddress) == false) {
+ revert INVALID_MODULE();
+ }
+
+ mapping(address => address) storage modules = _moduleMapping();
+ modules.add(moduleAddress);
+ mapping(bytes4 => bytes4) storage moduleSelectors = AccountStorage.layout().moduleSelectors[moduleAddress];
+
+ for (uint256 i = 0; i < selectors.length; i++) {
+ moduleSelectors.add(selectors[i]);
+ }
+ bytes memory callData = abi.encodeWithSelector(IPluggable.Init.selector, initData);
+ bytes4 invalidModuleSelector = INVALID_MODULE.selector;
+ assembly ("memory-safe") {
+ // memorySafe: The scratch space between memory offset 0 and 64.
+
+ let result := call(gas(), moduleAddress, 0, add(callData, 0x20), mload(callData), 0x00, 0x00)
+ if iszero(result) {
+ mstore(0x00, invalidModuleSelector)
+ revert(0x00, 4)
+ }
+ }
+
+ emit ModuleInstalled(moduleAddress);
+ }
+
+ /**
+ * @dev uninstall a module
+ * @param moduleAddress module address
+ */
+ function _uninstallModule(address moduleAddress) internal virtual override {
+ mapping(address => address) storage modules = _moduleMapping();
+ modules.remove(moduleAddress);
+ AccountStorage.layout().moduleSelectors[moduleAddress].clear();
+ (bool success,) =
+ moduleAddress.call{gas: 1000000 /* max to 1M gas */ }(abi.encodeWithSelector(IPluggable.DeInit.selector));
+ if (success) {
+ emit ModuleUninstalled(moduleAddress);
+ } else {
+ emit ModuleUninstalledwithError(moduleAddress);
+ }
+ }
+
+ /**
+ * @dev uninstall a module
+ * @param moduleAddress module address
+ */
+ function uninstallModule(address moduleAddress) external virtual override {
+ pluginManagementAccess();
+ _uninstallModule(moduleAddress);
+ }
+
+ /**
+ * @dev Provides a list of all added modules and their respective authorized function selectors
+ * @return modules An array of the addresses of all added modules
+ * @return selectors A 2D array where each inner array represents the function selectors
+ * that the corresponding module in the 'modules' array is allowed to call
+ */
+ function listModule()
+ external
+ view
+ virtual
+ override
+ returns (address[] memory modules, bytes4[][] memory selectors)
+ {
+ mapping(address => address) storage _modules = _moduleMapping();
+ uint256 moduleSize = _moduleMapping().size();
+ modules = new address[](moduleSize);
+ mapping(address => mapping(bytes4 => bytes4)) storage moduleSelectors = AccountStorage.layout().moduleSelectors;
+ selectors = new bytes4[][](moduleSize);
+
+ uint256 i = 0;
+ address addr = _modules[AddressLinkedList.SENTINEL_ADDRESS];
+ while (uint160(addr) > AddressLinkedList.SENTINEL_UINT) {
+ {
+ modules[i] = addr;
+ mapping(bytes4 => bytes4) storage moduleSelector = moduleSelectors[addr];
+
+ {
+ uint256 selectorSize = moduleSelector.size();
+ bytes4[] memory _selectors = new bytes4[](selectorSize);
+ uint256 j = 0;
+ bytes4 selector = moduleSelector[SelectorLinkedList.SENTINEL_SELECTOR];
+ while (uint32(selector) > SelectorLinkedList.SENTINEL_UINT) {
+ _selectors[j] = selector;
+
+ selector = moduleSelector[selector];
+ unchecked {
+ j++;
+ }
+ }
+ selectors[i] = _selectors;
+ }
+ }
+
+ addr = _modules[addr];
+ unchecked {
+ i++;
+ }
+ }
+ }
+
+ /**
+ * @notice Allows a module to execute a function within the system. This ensures that the
+ * module can only call functions it is permitted to.
+ * @param dest The address of the destination contract where the function will be executed
+ * @param value The amount of ether (in wei) to be sent with the function call
+ * @param func The function data to be executed
+ */
+ function executeFromModule(address dest, uint256 value, bytes memory func) external virtual override {
+ if (_isAuthorizedModule() == false) {
+ revert CALLER_MUST_BE_AUTHORIZED_MODULE();
+ }
+
+ if (dest == address(this)) revert MODULE_EXECUTE_FROM_MODULE_RECURSIVE();
+ assembly ("memory-safe") {
+ // memorySafe: Memory allocated by yourself using a mechanism like the allocate function described above.
+
+ function allocate(length) -> pos {
+ pos := mload(0x40)
+ mstore(0x40, add(pos, length))
+ }
+
+ let result := call(gas(), dest, value, add(func, 0x20), mload(func), 0, 0)
+
+ let returndataPtr := allocate(returndatasize())
+ returndatacopy(returndataPtr, 0, returndatasize())
+
+ if iszero(result) { revert(returndataPtr, returndatasize()) }
+ return(returndataPtr, returndatasize())
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/base/OwnerManager.sol b/lib/SoulWalletCore/contracts/base/OwnerManager.sol
new file mode 100644
index 00000000..e0aa0a4d
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/base/OwnerManager.sol
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {Authority} from "./Authority.sol";
+import {IOwnerManager} from "../interface/IOwnerManager.sol";
+import {AccountStorage} from "../utils/AccountStorage.sol";
+import {Bytes32LinkedList} from "../utils/Bytes32LinkedList.sol";
+import {OwnerManagerSnippet} from "../snippets/OwnerManager.sol";
+
+abstract contract OwnerManager is IOwnerManager, Authority, OwnerManagerSnippet {
+ using Bytes32LinkedList for mapping(bytes32 => bytes32);
+
+ /**
+ * @notice Helper function to get the owner mapping from account storage
+ * @return owners Mapping of current owners
+ */
+ function _ownerMapping() internal view override returns (mapping(bytes32 => bytes32) storage owners) {
+ owners = AccountStorage.layout().owners;
+ }
+
+ /**
+ * @notice Checks if the provided owner is a current owner
+ * @param owner Address in bytes32 format to check
+ * @return true if provided owner is a current owner, false otherwise
+ */
+ function _isOwner(bytes32 owner) internal view virtual override returns (bool) {
+ return _ownerMapping().isExist(owner);
+ }
+
+ /**
+ * @notice External function to check if the provided owner is a current owner
+ * @param owner Address in bytes32 format to check
+ * @return true if provided owner is a current owner, false otherwise
+ */
+ function isOwner(bytes32 owner) external view virtual override returns (bool) {
+ return _isOwner(owner);
+ }
+
+ /**
+ * @notice Internal function to add an owner
+ * @param owner Address in bytes32 format to add
+ */
+ function _addOwner(bytes32 owner) internal virtual override {
+ _ownerMapping().add(owner);
+ emit OwnerAdded(owner);
+ }
+
+ /**
+ * @notice add an owner
+ * @param owner Address in bytes32 format to add
+ */
+ function addOwner(bytes32 owner) external virtual override {
+ ownerManagementAccess();
+ _addOwner(owner);
+ }
+
+ /**
+ * @notice Internal function to remove an owner
+ * @param owner Address in bytes32 format to remove
+ */
+ function _removeOwner(bytes32 owner) internal virtual override {
+ _ownerMapping().remove(owner);
+ emit OwnerRemoved(owner);
+ }
+
+ /**
+ * @notice remove an owner
+ * @param owner Address in bytes32 format to remove
+ */
+ function removeOwner(bytes32 owner) external virtual override {
+ ownerManagementAccess();
+ _removeOwner(owner);
+ }
+
+ function _resetOwner(bytes32 newOwner) internal virtual override {
+ _clearOwner();
+ _ownerMapping().add(newOwner);
+ }
+
+ function _clearOwner() internal virtual override {
+ _ownerMapping().clear();
+ emit OwnerCleared();
+ }
+
+ function resetOwner(bytes32 newOwner) external virtual override {
+ ownerManagementAccess();
+ _resetOwner(newOwner);
+ }
+
+ function listOwner() external view virtual override returns (bytes32[] memory owners) {
+ mapping(bytes32 => bytes32) storage _owners = _ownerMapping();
+ owners = _owners.list(Bytes32LinkedList.SENTINEL_BYTES32, _owners.size());
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/base/StandardExecutor.sol b/lib/SoulWalletCore/contracts/base/StandardExecutor.sol
new file mode 100644
index 00000000..efd5222c
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/base/StandardExecutor.sol
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {Authority} from "./Authority.sol";
+import {IStandardExecutor, Execution} from "../interface/IStandardExecutor.sol";
+import {EntryPointManager} from "./EntryPointManager.sol";
+
+abstract contract StandardExecutor is Authority, IStandardExecutor, EntryPointManager {
+ /**
+ * @dev execute method
+ * only entrypoint can call this method
+ * @param target the target address
+ * @param value the value
+ * @param data the data
+ */
+ function execute(address target, uint256 value, bytes calldata data) external payable virtual override {
+ executorAccess();
+
+ assembly ("memory-safe") {
+ // memorySafe: Memory allocated by yourself using a mechanism like the allocate function described above.
+
+ function allocate(length) -> pos {
+ pos := mload(0x40)
+ mstore(0x40, add(pos, length))
+ }
+
+ let calldataPtr := allocate(data.length)
+ calldatacopy(calldataPtr, data.offset, data.length)
+
+ let result := call(gas(), target, value, calldataPtr, data.length, 0, 0)
+
+ // note: return data is ignored
+ if iszero(result) {
+ let returndataPtr := allocate(returndatasize())
+ returndatacopy(returndataPtr, 0, returndatasize())
+ revert(returndataPtr, returndatasize())
+ }
+ }
+ }
+
+ /**
+ * @dev execute batch method
+ * only entrypoint can call this method
+ * @param executions the executions
+ */
+ function executeBatch(Execution[] calldata executions) external payable virtual override {
+ executorAccess();
+
+ for (uint256 i = 0; i < executions.length; i++) {
+ Execution calldata execution = executions[i];
+ address target = execution.target;
+ uint256 value = execution.value;
+ bytes calldata data = execution.data;
+
+ assembly ("memory-safe") {
+ // memorySafe: Memory allocated by yourself using a mechanism like the allocate function described above.
+
+ function allocate(length) -> pos {
+ pos := mload(0x40)
+ mstore(0x40, add(pos, length))
+ }
+
+ let calldataPtr := allocate(data.length)
+ calldatacopy(calldataPtr, data.offset, data.length)
+
+ let result := call(gas(), target, value, calldataPtr, data.length, 0, 0)
+
+ // note: return data is ignored
+ if iszero(result) {
+ let returndataPtr := allocate(returndatasize())
+ returndatacopy(returndataPtr, 0, returndatasize())
+ revert(returndataPtr, returndatasize())
+ }
+ }
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/base/ValidatorManager.sol b/lib/SoulWalletCore/contracts/base/ValidatorManager.sol
new file mode 100644
index 00000000..2cc27280
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/base/ValidatorManager.sol
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {Authority} from "./Authority.sol";
+import {IValidatorManager} from "../interface/IValidatorManager.sol";
+import {IValidator} from "../interface/IValidator.sol";
+import {UserOperation} from "../interface/IAccount.sol";
+import {AccountStorage} from "../utils/AccountStorage.sol";
+import {AddressLinkedList} from "../utils/AddressLinkedList.sol";
+import {SIG_VALIDATION_FAILED} from "../utils/Constants.sol";
+import {ValidatorManagerSnippet} from "../snippets/ValidatorManager.sol";
+import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
+import {IPluggable} from "../interface/IPluggable.sol";
+
+abstract contract ValidatorManager is Authority, IValidatorManager, ValidatorManagerSnippet {
+ using AddressLinkedList for mapping(address => address);
+
+ error INVALID_VALIDATOR();
+
+ bytes4 private constant INTERFACE_ID_VALIDATOR = type(IValidator).interfaceId;
+
+ /**
+ * @dev checks whether a address is a installed validator
+ */
+ function _isInstalledValidator(address validator) internal view virtual override returns (bool) {
+ return AccountStorage.layout().validators.isExist(validator);
+ }
+
+ /**
+ * @dev checks whether a address is a valid validator
+ * note: If you need to extend the interface, override this function
+ * @param validator validator address
+ */
+ function _isSupportsValidatorInterface(address validator) internal view virtual override returns (bool supported) {
+ bytes memory callData = abi.encodeWithSelector(IERC165.supportsInterface.selector, INTERFACE_ID_VALIDATOR);
+ assembly ("memory-safe") {
+ // memorySafe: The scratch space between memory offset 0 and 64.
+
+ let result := staticcall(gas(), validator, add(callData, 0x20), mload(callData), 0x00, 0x20)
+ if gt(result, 0) { supported := mload(0x00) }
+ }
+ }
+
+ /**
+ * @dev install a validator
+ */
+ function _installValidator(address validator, bytes memory initData) internal virtual override {
+ if (_isSupportsValidatorInterface(validator) == false) {
+ revert INVALID_VALIDATOR();
+ }
+
+ AccountStorage.layout().validators.add(validator);
+
+ bytes memory callData = abi.encodeWithSelector(IPluggable.Init.selector, initData);
+ bytes4 invalidValidatorSelector = INVALID_VALIDATOR.selector;
+ assembly ("memory-safe") {
+ // memorySafe: The scratch space between memory offset 0 and 64.
+
+ let result := call(gas(), validator, 0, add(callData, 0x20), mload(callData), 0x00, 0x00)
+ if iszero(result) {
+ mstore(0x00, invalidValidatorSelector)
+ revert(0x00, 4)
+ }
+ }
+
+ emit ValidatorInstalled(validator);
+ }
+
+ /**
+ * @dev uninstall a validator
+ */
+ function _uninstallValidator(address validator) internal virtual override {
+ AccountStorage.layout().validators.remove(validator);
+ (bool success,) =
+ validator.call{gas: 1000000 /* max to 1M gas */ }(abi.encodeWithSelector(IPluggable.DeInit.selector));
+ if (success) {
+ emit ValidatorUninstalled(validator);
+ } else {
+ emit ValidatorUninstalledwithError(validator);
+ }
+ }
+
+ /**
+ * @dev uninstall a validator
+ */
+ function uninstallValidator(address validator) external virtual override {
+ validatorManagementAccess();
+ _uninstallValidator(validator);
+ }
+
+ /**
+ * @dev list validators
+ */
+ function listValidator() external view virtual override returns (address[] memory validators) {
+ mapping(address => address) storage validator = AccountStorage.layout().validators;
+ validators = validator.list(AddressLinkedList.SENTINEL_ADDRESS, validator.size());
+ }
+
+ /**
+ * @dev EIP-1271
+ * @param hash hash of the data to be signed
+ * @param validator validator address
+ * @param validatorSignature Signature byte array associated with _data
+ * @return magicValue Magic value 0x1626ba7e if the validator is registered and signature is valid
+ */
+ function _isValidSignature(bytes32 hash, address validator, bytes calldata validatorSignature)
+ internal
+ view
+ virtual
+ override
+ returns (bytes4 magicValue)
+ {
+ if (_isInstalledValidator(validator) == false) {
+ return bytes4(0);
+ }
+ bytes memory callData =
+ abi.encodeWithSelector(IValidator.validateSignature.selector, msg.sender, hash, validatorSignature);
+ assembly ("memory-safe") {
+ // memorySafe: The scratch space between memory offset 0 and 64.
+
+ let result := staticcall(gas(), validator, add(callData, 0x20), mload(callData), 0x00, 0x20)
+ if result { magicValue := mload(0x00) }
+ }
+ }
+
+ /**
+ * @dev validate UserOperation
+ * @param userOp UserOperation
+ * @param userOpHash UserOperation hash
+ * @param validator validator address
+ * @param validatorSignature validator signature
+ * @return validationData refer to https://github.com/eth-infinitism/account-abstraction/blob/v0.6.0/contracts/interfaces/IAccount.sol#L24-L30
+ */
+ function _validateUserOp(
+ UserOperation calldata userOp,
+ bytes32 userOpHash,
+ address validator,
+ bytes calldata validatorSignature
+ ) internal virtual override returns (uint256 validationData) {
+ if (_isInstalledValidator(validator) == false) {
+ return SIG_VALIDATION_FAILED;
+ }
+ bytes memory callData =
+ abi.encodeWithSelector(IValidator.validateUserOp.selector, userOp, userOpHash, validatorSignature);
+
+ assembly ("memory-safe") {
+ // memorySafe: The scratch space between memory offset 0 and 64.
+
+ let result := call(gas(), validator, 0, add(callData, 0x20), mload(callData), 0x00, 0x20)
+ if iszero(result) { mstore(0x00, SIG_VALIDATION_FAILED) }
+ validationData := mload(0x00)
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/extensions/HookInstaller.sol b/lib/SoulWalletCore/contracts/extensions/HookInstaller.sol
new file mode 100644
index 00000000..1f53e98b
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/extensions/HookInstaller.sol
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {AuthoritySnippet} from "../snippets/Authority.sol";
+import {HookManagerSnippet} from "../snippets/HookManager.sol";
+
+abstract contract HookInstaller is AuthoritySnippet, HookManagerSnippet {
+ /**
+ * @dev Install a hook
+ * @param hookAndData [0:20]: hook address, [20:]: hook data
+ * @param capabilityFlags Capability flags for the hook
+ */
+ function installHook(bytes calldata hookAndData, uint8 capabilityFlags) external {
+ pluginManagementAccess();
+ _installHook(address(bytes20(hookAndData[:20])), hookAndData[20:], capabilityFlags);
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/extensions/ModuleInstaller.sol b/lib/SoulWalletCore/contracts/extensions/ModuleInstaller.sol
new file mode 100644
index 00000000..4bc629f4
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/extensions/ModuleInstaller.sol
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {AuthoritySnippet} from "../snippets/Authority.sol";
+import {ModuleManagerSnippet} from "../snippets/ModuleManager.sol";
+
+abstract contract ModuleInstaller is AuthoritySnippet, ModuleManagerSnippet {
+ /**
+ * @dev install a module
+ * @param moduleAndData [0:20]: module address, [20:]: module init data
+ * @param selectors function selectors that the module is allowed to call
+ */
+ function installModule(bytes calldata moduleAndData, bytes4[] calldata selectors) external {
+ pluginManagementAccess();
+ _installModule(address(bytes20(moduleAndData[:20])), moduleAndData[20:], selectors);
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/extensions/ValidatorInstaller.sol b/lib/SoulWalletCore/contracts/extensions/ValidatorInstaller.sol
new file mode 100644
index 00000000..fb2ba834
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/extensions/ValidatorInstaller.sol
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {AuthoritySnippet} from "../snippets/Authority.sol";
+import {ValidatorManagerSnippet} from "../snippets/ValidatorManager.sol";
+
+abstract contract ValidatorInstaller is AuthoritySnippet, ValidatorManagerSnippet {
+ /**
+ * @dev Install a validator
+ * @param validatorAndData [0:20]: validator address, [20:]: validator data
+ */
+ function installValidator(bytes calldata validatorAndData) external {
+ validatorManagementAccess();
+ _installValidator(address(bytes20(validatorAndData[:20])), validatorAndData[20:]);
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/interface/IAccount.sol b/lib/SoulWalletCore/contracts/interface/IAccount.sol
new file mode 100644
index 00000000..701b1a06
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/interface/IAccount.sol
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import {UserOperation} from "@account-abstraction/contracts/interfaces/UserOperation.sol";
+
+interface IAccount {
+ /**
+ * Validate user's signature and nonce
+ * the entryPoint will make the call to the recipient only if this validation call returns successfully.
+ * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).
+ * This allows making a "simulation call" without a valid signature
+ * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.
+ *
+ * @dev Must validate caller is the entryPoint.
+ * Must validate the signature and nonce
+ * @param userOp the operation that is about to be executed.
+ * @param userOpHash hash of the user's request data. can be used as the basis for signature.
+ * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.
+ * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.
+ * The excess is left as a deposit in the entrypoint, for future calls.
+ * can be withdrawn anytime using "entryPoint.withdrawTo()"
+ * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.
+ * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode
+ * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,
+ * otherwise, an address of an "authorizer" contract.
+ * <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite"
+ * <6-byte> validAfter - first timestamp this operation is valid
+ * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.
+ * Note that the validation code cannot use block.timestamp (or block.number) directly.
+ */
+ function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)
+ external
+ payable
+ returns (uint256 validationData);
+}
diff --git a/contracts/interfaces/IFallbackManager.sol b/lib/SoulWalletCore/contracts/interface/IFallbackManager.sol
similarity index 73%
rename from contracts/interfaces/IFallbackManager.sol
rename to lib/SoulWalletCore/contracts/interface/IFallbackManager.sol
index 88ac8cb6..93afad65 100644
--- a/contracts/interfaces/IFallbackManager.sol
+++ b/lib/SoulWalletCore/contracts/interface/IFallbackManager.sol
@@ -1,17 +1,13 @@
-// SPDX-License-Identifier: GPL-3.0
+// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
-/**
- * @title IFallbackManager
- * @dev Interface for setting and managing the fallback contract.
- * The fallback contract is called when no other function matches the provided function signature.
- */
interface IFallbackManager {
/**
* @notice Emitted when the fallback contract is changed
* @param fallbackContract The address of the newly set fallback contract
*/
event FallbackChanged(address indexed fallbackContract);
+
/**
* @notice Set a new fallback contract
* @dev This function allows setting a new address as the fallback contract. The fallback contract will receive
diff --git a/lib/SoulWalletCore/contracts/interface/IHook.sol b/lib/SoulWalletCore/contracts/interface/IHook.sol
new file mode 100644
index 00000000..7cfc4a67
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/interface/IHook.sol
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {UserOperation} from "../interface/IAccount.sol";
+import {IPluggable} from "./IPluggable.sol";
+
+interface IHook is IPluggable {
+ /*
+ NOTE: Any implementation must ensure that the `hookSignature` exactly matches your expectations,
+ otherwise, you will face security risks.
+ For example:
+ if you do not require any `hookSignature`, make sure your implementation included the following code:
+ `require(hookSignature.length == 0)`
+
+ NOTE: All implemention must ensure that the DeInit() function can be covered by 100,000 gas in all scenarios.
+ */
+
+ /**
+ * @dev Should return whether the signature provided is valid for the provided data
+ * @param hash Hash of the data to be signed
+ * @param hookSignature Signature byte array associated with _data
+ */
+ function preIsValidSignatureHook(bytes32 hash, bytes calldata hookSignature) external view;
+
+ /**
+ * @dev Hook that is called before any userOp is executed.
+ * NOTE: Do not rely on userOperation.signature, which may be empty in some versions of the implementation. see: contract/utils/CalldataPack.sol
+ * must revert if the userOp is invalid.
+ */
+ function preUserOpValidationHook(
+ UserOperation calldata userOp,
+ bytes32 userOpHash,
+ uint256 missingAccountFunds,
+ bytes calldata hookSignature
+ ) external;
+}
diff --git a/lib/SoulWalletCore/contracts/interface/IHookManager.sol b/lib/SoulWalletCore/contracts/interface/IHookManager.sol
new file mode 100644
index 00000000..4a6ba03d
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/interface/IHookManager.sol
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+interface IHookManager {
+ /**
+ * @notice Emitted when a hook is installed
+ * @param hook hook
+ */
+ event HookInstalled(address hook);
+
+ /**
+ * @notice Emitted when a hook is uninstalled
+ * @param hook hook
+ */
+ event HookUninstalled(address hook);
+
+ /**
+ * @notice Emitted when a hook is uninstalled with error
+ * @param hook hook
+ */
+ event HookUninstalledwithError(address hook);
+
+ function uninstallHook(address hookAddress) external;
+
+ function isInstalledHook(address hook) external view returns (bool);
+
+ function listHook()
+ external
+ view
+ returns (address[] memory preIsValidSignatureHooks, address[] memory preUserOpValidationHooks);
+}
diff --git a/lib/SoulWalletCore/contracts/interface/IModule.sol b/lib/SoulWalletCore/contracts/interface/IModule.sol
new file mode 100644
index 00000000..300ddb43
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/interface/IModule.sol
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IPluggable} from "./IPluggable.sol";
+
+interface IModule is IPluggable {
+/*
+ NOTE: All implemention must ensure that the DeInit() function can be covered by 100,000 gas in all scenarios.
+ */
+}
diff --git a/lib/SoulWalletCore/contracts/interface/IModuleManager.sol b/lib/SoulWalletCore/contracts/interface/IModuleManager.sol
new file mode 100644
index 00000000..f223c686
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/interface/IModuleManager.sol
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+interface IModuleManager {
+ /**
+ * @notice Emitted when a module is installed
+ * @param module module
+ */
+ event ModuleInstalled(address module);
+
+ /**
+ * @notice Emitted when a module is uninstalled
+ * @param module module
+ */
+ event ModuleUninstalled(address module);
+
+ /**
+ * @notice Emitted when a module is uninstalled with error
+ * @param module module
+ */
+ event ModuleUninstalledwithError(address module);
+
+ function uninstallModule(address moduleAddress) external;
+
+ function isInstalledModule(address module) external view returns (bool);
+
+ /**
+ * @notice Provides a list of all added modules and their respective authorized function selectors
+ * @return modules An array of the addresses of all added modules
+ * @return selectors A 2D array where each inner array represents the function selectors
+ * that the corresponding module in the 'modules' array is allowed to call
+ */
+ function listModule() external view returns (address[] memory modules, bytes4[][] memory selectors);
+ /**
+ * @notice Allows a module to execute a function within the system. This ensures that the
+ * module can only call functions it is permitted to, based on its declared `requiredFunctions`
+ * @param dest The address of the destination contract where the function will be executed
+ * @param value The amount of ether (in wei) to be sent with the function call
+ * @param func The function data to be executed
+ */
+ function executeFromModule(address dest, uint256 value, bytes calldata func) external;
+}
diff --git a/lib/SoulWalletCore/contracts/interface/IOwnable.sol b/lib/SoulWalletCore/contracts/interface/IOwnable.sol
new file mode 100644
index 00000000..694a8ac6
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/interface/IOwnable.sol
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+interface IOwnable {
+ /**
+ * @notice Checks if a given bytes32 ID corresponds to an owner within the system
+ * @param owner The bytes32 ID to check
+ * @return True if the ID corresponds to an owner, false otherwise
+ */
+
+ function isOwner(bytes32 owner) external view returns (bool);
+}
diff --git a/lib/SoulWalletCore/contracts/interface/IOwnerManager.sol b/lib/SoulWalletCore/contracts/interface/IOwnerManager.sol
new file mode 100644
index 00000000..534b50d1
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/interface/IOwnerManager.sol
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IOwnable} from "./IOwnable.sol";
+
+interface IOwnerManager is IOwnable {
+ /**
+ * @notice Emitted when an owner is added
+ * @param owner owner
+ */
+ event OwnerAdded(bytes32 indexed owner);
+
+ /**
+ * @notice Emitted when an owner is removed
+ * @param owner owner
+ */
+ event OwnerRemoved(bytes32 indexed owner);
+
+ /**
+ * @notice Emitted when all owners are removed
+ */
+ event OwnerCleared();
+
+ /**
+ * @notice Adds a new owner to the system
+ * @param owner The bytes32 ID of the owner to be added
+ */
+ function addOwner(bytes32 owner) external;
+
+ /**
+ * @notice Removes an existing owner from the system
+ * @param owner The bytes32 ID of the owner to be removed
+ */
+ function removeOwner(bytes32 owner) external;
+
+ /**
+ * @notice Resets the entire owner set, replacing it with a single new owner
+ * @param newOwner The bytes32 ID of the new owner
+ */
+ function resetOwner(bytes32 newOwner) external;
+
+ /**
+ * @notice Provides a list of all added owners
+ * @return owners An array of bytes32 IDs representing the owners
+ */
+ function listOwner() external view returns (bytes32[] memory owners);
+}
diff --git a/contracts/interfaces/IPluggable.sol b/lib/SoulWalletCore/contracts/interface/IPluggable.sol
similarity index 64%
rename from contracts/interfaces/IPluggable.sol
rename to lib/SoulWalletCore/contracts/interface/IPluggable.sol
index 47d252af..9043f7a0 100644
--- a/contracts/interfaces/IPluggable.sol
+++ b/lib/SoulWalletCore/contracts/interface/IPluggable.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;
-import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
+import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title Pluggable Interface
@@ -12,10 +12,14 @@ interface IPluggable is IERC165 {
* @notice Initializes a specific module or plugin for the wallet with the provided data
* @param data Initialization data required for the module or plugin
*/
- function walletInit(bytes calldata data) external;
+ function Init(bytes calldata data) external;
+
+ /*
+ NOTE: All implemention must ensure that the DeInit() function can be covered by 100,000 gas in all scenarios.
+ */
/**
* @notice Deinitializes a specific module or plugin from the wallet
*/
- function walletDeInit() external;
+ function DeInit() external;
}
diff --git a/lib/SoulWalletCore/contracts/interface/IStandardExecutor.sol b/lib/SoulWalletCore/contracts/interface/IStandardExecutor.sol
new file mode 100644
index 00000000..7e511f7a
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/interface/IStandardExecutor.sol
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+struct Execution {
+ // The target contract for account to execute.
+ address target;
+ // The value for the execution.
+ uint256 value;
+ // The call data for the execution.
+ bytes data;
+}
+
+interface IStandardExecutor {
+ /// @dev Standard execute method.
+ /// @param target The target contract for account to execute.
+ /// @param value The value for the execution.
+ /// @param data The call data for the execution.
+ function execute(address target, uint256 value, bytes calldata data) external payable;
+
+ /// @dev Standard executeBatch method.
+ /// @param executions The array of executions.
+ function executeBatch(Execution[] calldata executions) external payable;
+}
diff --git a/lib/SoulWalletCore/contracts/interface/IValidator.sol b/lib/SoulWalletCore/contracts/interface/IValidator.sol
new file mode 100644
index 00000000..8932d106
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/interface/IValidator.sol
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {UserOperation} from "../interface/IAccount.sol";
+import {IPluggable} from "./IPluggable.sol";
+
+interface IValidator is IPluggable {
+ /*
+ NOTE: Any implementation must ensure that the `validatorSignature` exactly matches your expectations,
+ otherwise, you will face security risks.
+ For example:
+ if you do not require any `validatorSignature`, make sure your implementation included the following code:
+ `require(validatorSignature.length == 0)`
+ */
+
+ /**
+ * @dev EIP-1271 Should return whether the signature provided is valid for the provided data
+ * @param sender Address of the message sender
+ * @param hash Hash of the data to be signed
+ * @param validatorSignature Signature byte array associated with _data
+ */
+ function validateSignature(address sender, bytes32 hash, bytes memory validatorSignature)
+ external
+ view
+ returns (bytes4 magicValue);
+
+ /**
+ * @dev EIP-4337 validate userOperation
+ * NOTE: Do not rely on userOperation.signature, which may be empty in some versions of the implementation, see: contract/utils/CalldataPack.sol
+ * @param userOp the operation that is about to be executed.
+ * @param userOpHash hash of the user's request data. can be used as the basis for signature.
+ * @param validatorSignature Signature
+ * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode
+ * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,
+ * otherwise, an address of an "authorizer" contract.
+ * <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite"
+ * <6-byte> validAfter - first timestamp this operation is valid
+ * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.
+ * Note that the validation code cannot use block.timestamp (or block.number) directly.
+ */
+ function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, bytes calldata validatorSignature)
+ external
+ returns (uint256 validationData);
+}
diff --git a/lib/SoulWalletCore/contracts/interface/IValidatorManager.sol b/lib/SoulWalletCore/contracts/interface/IValidatorManager.sol
new file mode 100644
index 00000000..8c909000
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/interface/IValidatorManager.sol
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IValidator} from "./IValidator.sol";
+
+interface IValidatorManager {
+ /**
+ * @notice Emitted when a validator is installed
+ * @param validator Validator
+ */
+ event ValidatorInstalled(address validator);
+
+ /**
+ * @notice Emitted when a validator is uninstalled
+ * @param validator Validator
+ */
+ event ValidatorUninstalled(address validator);
+
+ /**
+ * @notice Emitted when a validator is uninstalled with error
+ * @param validator Validator
+ */
+ event ValidatorUninstalledwithError(address validator);
+
+ function uninstallValidator(address validator) external;
+
+ function listValidator() external view returns (address[] memory validators);
+}
diff --git a/lib/SoulWalletCore/contracts/snippets/Authority.sol b/lib/SoulWalletCore/contracts/snippets/Authority.sol
new file mode 100644
index 00000000..dca44296
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/snippets/Authority.sol
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+abstract contract AuthoritySnippet {
+ /**
+ * @dev checks whether the caller is a authorized module
+ * caller: msg.sender
+ * method: msg.sig
+ * @return bool
+ */
+ function _isAuthorizedModule() internal view virtual returns (bool);
+
+ /**
+ * @notice Ensures the calling contract is the entrypoint
+ */
+ function _onlyEntryPoint() internal view virtual;
+
+ /**
+ * @notice Ensures the calling contract is an authorized module
+ */
+ function _onlyModule() internal view virtual;
+
+ /**
+ * @notice Ensures the calling contract is either the Authority contract itself or an authorized module
+ * @dev Uses the inherited `_isAuthorizedModule()` from ModuleAuth for module-based authentication
+ */
+ function _onlySelfOrModule() internal view virtual;
+
+ /**
+ * @dev Check if access to the following functions:
+ * 1. setFallbackHandler
+ */
+ function fallbackManagementAccess() internal view virtual;
+
+ /**
+ * @dev Check if access to the following functions:
+ * 1. installHook
+ * 2. uninstallHook
+ * 3. installModule
+ * 4. uninstallModule
+ */
+ function pluginManagementAccess() internal view virtual;
+
+ /**
+ * @dev Check if access to the following functions:
+ * 1. addOwner
+ * 2. removeOwner
+ * 3. resetOwner
+ */
+ function ownerManagementAccess() internal view virtual;
+
+ /**
+ * @dev Check if access to the following functions:
+ * 1. execute
+ * 2. executeBatch
+ */
+ function executorAccess() internal view virtual;
+
+ /**
+ * @dev Check if access to the following functions:
+ * 1. installValidator
+ * 2. uninstallValidator
+ */
+ function validatorManagementAccess() internal view virtual;
+}
diff --git a/lib/SoulWalletCore/contracts/snippets/FallbackManager.sol b/lib/SoulWalletCore/contracts/snippets/FallbackManager.sol
new file mode 100644
index 00000000..6d81bf3e
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/snippets/FallbackManager.sol
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+abstract contract FallbackManagerSnippet {
+ /**
+ * @dev Sets the address of the fallback handler contract
+ * @param fallbackContract The address of the new fallback handler contract
+ */
+ function _setFallbackHandler(address fallbackContract) internal virtual;
+}
diff --git a/lib/SoulWalletCore/contracts/snippets/HookManager.sol b/lib/SoulWalletCore/contracts/snippets/HookManager.sol
new file mode 100644
index 00000000..c1fb8b8c
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/snippets/HookManager.sol
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+abstract contract HookManagerSnippet {
+ /**
+ * @dev checks whether a address is a valid hook
+ * note: If you need to extend the interface, override this function
+ * @param hookAddress hook address
+ */
+ function _isSupportsHookInterface(address hookAddress) internal view virtual returns (bool);
+
+ /**
+ * @dev Install a hook
+ * @param hookAddress The address of the hook
+ * @param initData The init data of the hook
+ * @param capabilityFlags Capability flags for the hook
+ */
+ function _installHook(address hookAddress, bytes memory initData, uint8 capabilityFlags) internal virtual;
+
+ /**
+ * @dev Uninstall a hook
+ * 1. revert if the hook is not installed
+ * 2. call hook.deInit() with 1M gas, emit HOOK_UNINSTALL_WITHERROR if the call failed
+ * @param hookAddress The address of the hook
+ */
+ function _uninstallHook(address hookAddress) internal virtual;
+}
diff --git a/lib/SoulWalletCore/contracts/snippets/ModuleManager.sol b/lib/SoulWalletCore/contracts/snippets/ModuleManager.sol
new file mode 100644
index 00000000..470a0dd1
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/snippets/ModuleManager.sol
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+abstract contract ModuleManagerSnippet {
+ /**
+ * @dev checks whether a address is a authorized module
+ */
+ function _isInstalledModule(address module) internal view virtual returns (bool);
+
+ /**
+ * @dev checks whether a address is a module
+ * note: If you need to extend the interface, override this function
+ * @param moduleAddress module address
+ */
+ function _isSupportsModuleInterface(address moduleAddress) internal view virtual returns (bool);
+
+ /**
+ * @dev install a module
+ * @param moduleAddress module address
+ * @param initData module init data
+ * @param selectors function selectors that the module is allowed to call
+ */
+ function _installModule(address moduleAddress, bytes memory initData, bytes4[] memory selectors) internal virtual;
+
+ /**
+ * @dev uninstall a module
+ * @param moduleAddress module address
+ */
+ function _uninstallModule(address moduleAddress) internal virtual;
+}
diff --git a/lib/SoulWalletCore/contracts/snippets/OwnerManager.sol b/lib/SoulWalletCore/contracts/snippets/OwnerManager.sol
new file mode 100644
index 00000000..3b92a6a4
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/snippets/OwnerManager.sol
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+abstract contract OwnerManagerSnippet {
+ /**
+ * @dev Helper function to get the owner mapping from account storage
+ * @return owners Mapping of current owners
+ */
+ function _ownerMapping() internal view virtual returns (mapping(bytes32 => bytes32) storage owners);
+
+ /**
+ * @dev Checks if the provided owner is a current owner
+ * @param owner Address in bytes32 format to check
+ * @return true if provided owner is a current owner, false otherwise
+ */
+ function _isOwner(bytes32 owner) internal view virtual returns (bool);
+
+ /**
+ * @dev Add an owner
+ * @param owner Address in bytes32 format to add
+ */
+ function _addOwner(bytes32 owner) internal virtual;
+
+ /**
+ * @dev Remove an owner
+ * @param owner Address in bytes32 format to remove
+ */
+ function _removeOwner(bytes32 owner) internal virtual;
+
+ /**
+ * @dev Reset owner
+ */
+ function _resetOwner(bytes32 newOwner) internal virtual;
+
+ /**
+ * @dev Clear owner
+ */
+ function _clearOwner() internal virtual;
+}
diff --git a/lib/SoulWalletCore/contracts/snippets/ValidatorManager.sol b/lib/SoulWalletCore/contracts/snippets/ValidatorManager.sol
new file mode 100644
index 00000000..5f5032aa
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/snippets/ValidatorManager.sol
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {UserOperation} from "../interface/IAccount.sol";
+
+abstract contract ValidatorManagerSnippet {
+ /**
+ * @dev checks whether a address is a installed validator
+ */
+ function _isInstalledValidator(address validator) internal view virtual returns (bool);
+
+ /**
+ * @dev checks whether a address is a valid validator
+ * note: If you need to extend the interface, override this function
+ * @param validator validator address
+ */
+ function _isSupportsValidatorInterface(address validator) internal view virtual returns (bool);
+
+ /**
+ * @dev install a validator
+ */
+ function _installValidator(address validator, bytes memory initData) internal virtual;
+
+ /**
+ * @dev uninstall a validator
+ */
+ function _uninstallValidator(address validator) internal virtual;
+
+ /**
+ * @dev EIP-1271
+ * @param hash hash of the data to be signed
+ * @param validator validator address
+ * @param validatorSignature Signature byte array associated with _data
+ * @return magicValue Magic value 0x1626ba7e if the validator is registered and signature is valid
+ */
+ function _isValidSignature(bytes32 hash, address validator, bytes calldata validatorSignature)
+ internal
+ view
+ virtual
+ returns (bytes4 magicValue);
+
+ /**
+ * @dev validate UserOperation
+ * @param userOp UserOperation
+ * @param userOpHash UserOperation hash
+ * @param validator validator address
+ * @param validatorSignature validator signature
+ * @return validationData refer to https://github.com/eth-infinitism/account-abstraction/blob/v0.6.0/contracts/interfaces/IAccount.sol#L24-L30
+ */
+ function _validateUserOp(
+ UserOperation calldata userOp,
+ bytes32 userOpHash,
+ address validator,
+ bytes calldata validatorSignature
+ ) internal virtual returns (uint256 validationData);
+}
diff --git a/lib/SoulWalletCore/contracts/utils/AccountStorage.sol b/lib/SoulWalletCore/contracts/utils/AccountStorage.sol
new file mode 100644
index 00000000..b5214c70
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/utils/AccountStorage.sol
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+/**
+ * @title AccountStorage
+ * @notice A library that defines the storage layout for the SoulWallet account or contract.
+ */
+library AccountStorage {
+ bytes32 internal constant _ACCOUNT_SLOT = keccak256("soulwallet.contracts.AccountStorage");
+
+ struct Layout {
+ // base data
+ mapping(bytes32 => bytes32) owners;
+ address defaultFallbackContract;
+ // validators
+ mapping(address => address) validators;
+ // hooks
+ mapping(address => address) preIsValidSignatureHook;
+ mapping(address => address) preUserOpValidationHook;
+ // modules
+ mapping(address => address) modules;
+ mapping(address => mapping(bytes4 => bytes4)) moduleSelectors;
+ }
+
+ /**
+ * @notice Returns the layout of the storage for the account or contract.
+ * @return l The layout of the storage.
+ */
+ function layout() internal pure returns (Layout storage l) {
+ bytes32 slot = _ACCOUNT_SLOT;
+ assembly ("memory-safe") {
+ l.slot := slot
+ }
+ }
+}
diff --git a/contracts/libraries/AddressLinkedList.sol b/lib/SoulWalletCore/contracts/utils/AddressLinkedList.sol
similarity index 79%
rename from contracts/libraries/AddressLinkedList.sol
rename to lib/SoulWalletCore/contracts/utils/AddressLinkedList.sol
index fbffdc28..30d8fa3f 100644
--- a/contracts/libraries/AddressLinkedList.sol
+++ b/lib/SoulWalletCore/contracts/utils/AddressLinkedList.sol
@@ -1,22 +1,24 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;
-import "../libraries/Errors.sol";
-
/**
* @title Address Linked List
* @notice This library provides utility functions to manage a linked list of addresses
*/
library AddressLinkedList {
+ error INVALID_ADDRESS();
+ error ADDRESS_ALREADY_EXISTS();
+ error ADDRESS_NOT_EXISTS();
+
address internal constant SENTINEL_ADDRESS = address(1);
uint160 internal constant SENTINEL_UINT = 1;
+
/**
* @dev Modifier that checks if an address is valid.
*/
-
modifier onlyAddress(address addr) {
if (uint160(addr) <= SENTINEL_UINT) {
- revert Errors.INVALID_ADDRESS();
+ revert INVALID_ADDRESS();
}
_;
}
@@ -28,7 +30,7 @@ library AddressLinkedList {
function add(mapping(address => address) storage self, address addr) internal onlyAddress(addr) {
if (self[addr] != address(0)) {
- revert Errors.ADDRESS_ALREADY_EXISTS();
+ revert ADDRESS_ALREADY_EXISTS();
}
address _prev = self[SENTINEL_ADDRESS];
if (_prev == address(0)) {
@@ -39,34 +41,7 @@ library AddressLinkedList {
self[addr] = _prev;
}
}
- /**
- * @notice Replaces an old address with a new one in the linked list.
- * @param self The linked list mapping.
- * @param oldAddr The old address to be replaced.
- * @param newAddr The new address.
- */
- function replace(mapping(address => address) storage self, address oldAddr, address newAddr) internal {
- if (!isExist(self, oldAddr)) {
- revert Errors.ADDRESS_NOT_EXISTS();
- }
- if (isExist(self, newAddr)) {
- revert Errors.ADDRESS_ALREADY_EXISTS();
- }
-
- address cursor = SENTINEL_ADDRESS;
- while (true) {
- address _addr = self[cursor];
- if (_addr == oldAddr) {
- address next = self[_addr];
- self[newAddr] = next;
- self[cursor] = newAddr;
- self[_addr] = address(0);
- return;
- }
- cursor = _addr;
- }
- }
/**
* @notice Removes an address from the linked list.
* @param self The linked list mapping.
@@ -75,7 +50,7 @@ library AddressLinkedList {
function remove(mapping(address => address) storage self, address addr) internal {
if (!tryRemove(self, addr)) {
- revert Errors.ADDRESS_NOT_EXISTS();
+ revert ADDRESS_NOT_EXISTS();
}
}
/**
@@ -107,10 +82,13 @@ library AddressLinkedList {
*/
function clear(mapping(address => address) storage self) internal {
- for (address addr = self[SENTINEL_ADDRESS]; uint160(addr) > SENTINEL_UINT; addr = self[addr]) {
+ address addr = self[SENTINEL_ADDRESS];
+ self[SENTINEL_ADDRESS] = address(0);
+ while (uint160(addr) > SENTINEL_UINT) {
+ address _addr = self[addr];
self[addr] = address(0);
+ addr = _addr;
}
- self[SENTINEL_ADDRESS] = address(0);
}
/**
* @notice Checks if an address exists in the linked list.
diff --git a/contracts/libraries/Bytes32LinkedList.sol b/lib/SoulWalletCore/contracts/utils/Bytes32LinkedList.sol
similarity index 73%
rename from contracts/libraries/Bytes32LinkedList.sol
rename to lib/SoulWalletCore/contracts/utils/Bytes32LinkedList.sol
index f48add62..e646dc51 100644
--- a/contracts/libraries/Bytes32LinkedList.sol
+++ b/lib/SoulWalletCore/contracts/utils/Bytes32LinkedList.sol
@@ -1,21 +1,23 @@
-// SPDX-License-Identifier: GPL-3.0
+// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
-import "../libraries/Errors.sol";
-
library Bytes32LinkedList {
+ error INVALID_DATA();
+ error DATA_ALREADY_EXISTS();
+ error DATA_NOT_EXISTS();
+
bytes32 internal constant SENTINEL_BYTES32 = 0x0000000000000000000000000000000000000000000000000000000000000001;
modifier onlyBytes32(bytes32 data) {
if (data <= SENTINEL_BYTES32) {
- revert Errors.INVALID_DATA();
+ revert INVALID_DATA();
}
_;
}
function add(mapping(bytes32 => bytes32) storage self, bytes32 data) internal onlyBytes32(data) {
if (self[data] != bytes32(0)) {
- revert Errors.DATA_ALREADY_EXISTS();
+ revert DATA_ALREADY_EXISTS();
}
bytes32 _prev = self[SENTINEL_BYTES32];
if (_prev == bytes32(0)) {
@@ -27,31 +29,9 @@ library Bytes32LinkedList {
}
}
- function replace(mapping(bytes32 => bytes32) storage self, bytes32 oldData, bytes32 newData) internal {
- if (!isExist(self, oldData)) {
- revert Errors.DATA_NOT_EXISTS();
- }
- if (isExist(self, newData)) {
- revert Errors.DATA_ALREADY_EXISTS();
- }
-
- bytes32 cursor = SENTINEL_BYTES32;
- while (true) {
- bytes32 _data = self[cursor];
- if (_data == oldData) {
- bytes32 next = self[_data];
- self[newData] = next;
- self[cursor] = newData;
- self[_data] = bytes32(0);
- return;
- }
- cursor = _data;
- }
- }
-
function remove(mapping(bytes32 => bytes32) storage self, bytes32 data) internal {
if (!tryRemove(self, data)) {
- revert Errors.DATA_NOT_EXISTS();
+ revert DATA_NOT_EXISTS();
}
}
@@ -73,10 +53,13 @@ library Bytes32LinkedList {
}
function clear(mapping(bytes32 => bytes32) storage self) internal {
- for (bytes32 data = self[SENTINEL_BYTES32]; data > SENTINEL_BYTES32; data = self[data]) {
+ bytes32 data = self[SENTINEL_BYTES32];
+ self[SENTINEL_BYTES32] = bytes32(0);
+ while (data > SENTINEL_BYTES32) {
+ bytes32 _data = self[data];
self[data] = bytes32(0);
+ data = _data;
}
- self[SENTINEL_BYTES32] = bytes32(0);
}
function isExist(mapping(bytes32 => bytes32) storage self, bytes32 data)
diff --git a/lib/SoulWalletCore/contracts/utils/CalldataPack.sol b/lib/SoulWalletCore/contracts/utils/CalldataPack.sol
new file mode 100644
index 00000000..8179fcd7
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/utils/CalldataPack.sol
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {UserOperation} from "../interface/IAccount.sol";
+import {IValidator} from "../interface/IValidator.sol";
+
+library CallDataPack {
+ /**
+ * @dev Executing abi.encodeWithSelector with a custom function can save at least 1322 gas (when the signature length is 89), and the savings are even greater in cases where userOp contains a longer signature or hookData.
+ *
+ * Benchmark: `forge test -vv --match-contract "CalldataPackTest" | grep 'gasDiff'`
+ * Result:
+ * gasDiff_EOASignature: 1322
+ * gasDiff_es256: 1390
+ * gasDiff_es256 with 1k hookdata 1744
+ * gasDiff_es256 with 2k hookdata 2087
+ *
+ * Whether to remove userOp.signature from calldata depends on the position of userOp.signature
+ * If userOp.signature is not the last field, it will be included in the encoded result
+ * If userOp.signature is the last field, it will not be included in the encoded result
+ */
+ function encodeWithoutUserOpSignature_validateUserOp_UserOperation_bytes32_bytes(
+ UserOperation calldata userOp,
+ bytes32 userOpHash,
+ bytes calldata validatorSignature
+ ) internal pure returns (bytes memory callData) {
+ /*
+ Equivalent code:
+ UserOperation memory _userOp = userOp;
+ _userOp.signature = "";
+ bytes memory callData = abi.encodeWithSelector(IValidator.validateUserOp.selector, _userOp, userOpHash, validatorSignature);
+ */
+
+ /*
+ struct UserOperation {
+ address sender;
+ uint256 nonce;
+ bytes initCode;
+ bytes callData;
+ uint256 callGasLimit;
+ uint256 verificationGasLimit;
+ uint256 preVerificationGas;
+ uint256 maxFeePerGas;
+ uint256 maxPriorityFeePerGas;
+ bytes paymasterAndData;
+ bytes signature;
+ }
+
+ In calldata, the data structure of the UserOperation is always:
+ refer to:https://docs.soliditylang.org/en/develop/abi-spec.html
+ offset: 0x00 000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # sender
+ offset: 0x20 000000000000000000000000000000000000000000000000000b0b0b0b0b0b0b # nonce
+ offset: 0x40 0000000000000000000000000000000000000000000000000000000000000160 # initCode offset
+ offset: 0x60 00000000000000000000000000000000000000000000000000000000000001a0 # callData offset
+ offset: 0x80 000000000000000000000000000000000000000000000000000e0e0e0e0e0e0e # callGasLimit
+ offset: 0xa0 000000000000000000000000000000000000000000000000000f0f0f0f0f0f0f # verificationGasLimit
+ offset: 0xc0 0000000000000000000000000000000000000000000000000010101010101010 # preVerificationGas
+ offset: 0xe0 0000000000000000000000000000000000000000000000000011111111111111 # maxFeePerGas
+ offset:0x100 0000000000000000000000000000000000000000000000000012121212121212 # maxPriorityFeePerGas
+ offset:0x120 00000000000000000000000000000000000000000000000000000000000001e0 # paymasterAndData offset
+ offset:0x140 0000000000000000000000000000000000000000000000000000000000000220 # signature offset
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ──┐
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx │ dynamic data
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx │
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ──┘
+
+
+ In the known SDK implementation, the last field `signature` of the struct is packed at the end.
+ However, manual encoding allows the position of signature to be moved earlier (still valid data).
+ In our process, we detect the position of signature. If it's not the last field, we fallback to encoding with `abi.encodeWithSelector()`.
+ If signature is detected as the last field, we can construct calldata with low cost using calldatacopy.
+ */
+
+ // Check if userOp.signature is the last field, if not, fallback to `abi.encodeWithSelector()`
+ {
+ uint256 lastfield = 0; // 0: last field is signature, 1: last field is not signature
+ assembly ("memory-safe") {
+ let userOpOffset := userOp
+ let _initCodeOffset := calldataload(add(userOpOffset, 0x40))
+ let _signatureOffset := calldataload(add(userOpOffset, 0x140))
+ // if(_initCodeOffset >= _signatureOffset) { lastfield = 1 }
+ if iszero(lt(_initCodeOffset, _signatureOffset)) { lastfield := 1 }
+
+ let _callDataOffset := calldataload(add(userOpOffset, 0x60))
+ // if(_callDataOffset >= _signatureOffset) { lastfield = 1 }
+ if iszero(lt(_callDataOffset, _signatureOffset)) { lastfield := 1 }
+
+ let _paymasterAndDataOffset := calldataload(add(userOpOffset, 0x120))
+ // if(_paymasterAndDataOffset >= _signatureOffset) { lastfield = 1 }
+ if iszero(lt(_paymasterAndDataOffset, _signatureOffset)) { lastfield := 1 }
+ }
+ if (lastfield == 1) {
+ return
+ abi.encodeWithSelector(IValidator.validateUserOp.selector, userOp, userOpHash, validatorSignature);
+ }
+ }
+
+ /**
+ * The validatorSignature comes from the slice of the Signature,
+ * so don't try to get the length of the validatorSignature via calldataload(sub(validatorSignature.offset,32))
+ */
+ uint256 validatorSignatureLength = validatorSignature.length;
+ bytes4 selector = IValidator.validateUserOp.selector;
+ assembly ("memory-safe") {
+ /*
+ The structure of calldata is:
+ refer to:https://docs.soliditylang.org/en/develop/abi-spec.html
+
+ 5d719936 # selector
+ 0000000000000000000000000000000000000000000000000000000000000060 # offset of userOp
+ 0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a # userOpHash
+ 00000000000000000000000000000000000000000000000000000000000002a0 # offset of validatorSignature
+ 000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ──┐
+ 000000000000000000000000000000000000000000000000000b0b0b0b0b0b0b │
+ 0000000000000000000000000000000000000000000000000000000000000160 │
+ 00000000000000000000000000000000000000000000000000000000000001a0 │
+ 000000000000000000000000000000000000000000000000000e0e0e0e0e0e0e │
+ 000000000000000000000000000000000000000000000000000f0f0f0f0f0f0f │
+ 0000000000000000000000000000000000000000000000000010101010101010 │
+ 0000000000000000000000000000000000000000000000000011111111111111 ├── userOp (signature length is 0)
+ 0000000000000000000000000000000000000000000000000012121212121212 │
+ 00000000000000000000000000000000000000000000000000000000000001e0 │
+ 0000000000000000000000000000000000000000000000000000000000000220 │
+ 0000000000000000000000000000000000000000000000000000000000000010 │
+ 0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c00000000000000000000000000000000 │
+ 0000000000000000000000000000000000000000000000000000000000000010 │
+ 0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d00000000000000000000000000000000 │
+ 000000000000000000000000000000000000000000000000000000000000000d │
+ 1313131313131313131313131300000000000000000000000000000000000000 │
+ 0000000000000000000000000000000000000000000000000000000000000000 ──┴── (validatorSignature length is 0)
+ 0000000000000000000000000000000000000000000000000000000000000020 # validatorSignature length
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # validatorSignature
+
+ */
+ // Offset of userOp in calldata
+ let userOpOffset := userOp
+ let _signatureOffset := calldataload(add(userOpOffset, 0x140))
+
+ /*
+ Length of userOp, excluding signature, but includes an additional 32bytes for recording the length of signature = 0
+ The length should be a multiple of 32, so no need for alignment like ValidatorSignatureLength
+ */
+ let paddedUserOpLength := add(_signatureOffset, 32)
+
+ // Round up to the nearest multiple of 32, bytes: enc(X) is the sequence of bytes in X padded with trailing zero-bytes to a length of 32 bytes.
+ let paddedValidatorSignatureLength := mul(div(add(validatorSignatureLength, 31), 32), 32)
+
+ // Total length of call data: 4(selecter) + 32(offset of userOp) + 32(userOpHash) + 32(offset of validatorSignature) + paddedUserOpLength + 32(validatorSignature length)+ paddedValidatorSignatureLength
+ let callDataLength := add(add(132, paddedUserOpLength), paddedValidatorSignatureLength)
+
+ // Allocate memory: callDataLength - 4 bytes header + 32 (padding 4 bytes header to 32 bytes) + 32 (record data length)
+ let ptr := mload(0x40)
+ mstore(0x40, add(add(32, ptr), add(32, add(callDataLength, 28))))
+
+ // 4 bytes header and callData length, shift callData length 4bytes to align with selector in the same storage slot
+ mstore(add(0x20, ptr), or(shl(32, callDataLength), shr(224, selector))) // Shift 4-byte header right by 8*(32-4)
+ // offset of userOp
+ mstore(add(0x40, ptr), 0x60)
+ // userOp Hash
+ mstore(add(0x60, ptr), userOpHash)
+ // offset of validatorSignature, paddedUserOpLength+ 3*0x20
+ mstore(add(0x80, ptr), add(paddedUserOpLength, 0x60))
+ // userOp
+ calldatacopy(add(0xa0, ptr), userOpOffset, paddedUserOpLength)
+ let validatorSignatureOffset := add(add(0xa0, ptr), paddedUserOpLength)
+ /*
+ Set the signature length to 0, as an extra 32bytes data (original length of signature) was copied in the previous step of calldatacopy
+ */
+ mstore(sub(validatorSignatureOffset, 32), 0)
+ // validatorSignature length
+ mstore(validatorSignatureOffset, validatorSignatureLength)
+ // validatorSignature
+ calldatacopy(add(0x20, validatorSignatureOffset), validatorSignature.offset, paddedValidatorSignatureLength)
+ // Non-32 alignment, 0x20-0x04, to follow bytes4-selecter immediately after callData length
+ callData := add(ptr, 28)
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/utils/Constants.sol b/lib/SoulWalletCore/contracts/utils/Constants.sol
new file mode 100644
index 00000000..21633d20
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/utils/Constants.sol
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+//return value in case of signature failure, with no time-range.
+// equivalent to _packValidationData(true,0,0);
+uint256 constant SIG_VALIDATION_FAILED = 1;
+
+uint256 constant SIG_VALIDATION_SUCCESS = 0;
diff --git a/contracts/libraries/SelectorLinkedList.sol b/lib/SoulWalletCore/contracts/utils/SelectorLinkedList.sol
similarity index 70%
rename from contracts/libraries/SelectorLinkedList.sol
rename to lib/SoulWalletCore/contracts/utils/SelectorLinkedList.sol
index 98777fe8..a0a95d9d 100644
--- a/contracts/libraries/SelectorLinkedList.sol
+++ b/lib/SoulWalletCore/contracts/utils/SelectorLinkedList.sol
@@ -1,26 +1,24 @@
-// SPDX-License-Identifier: GPL-3.0
+// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
-import "../libraries/Errors.sol";
-
library SelectorLinkedList {
+ error INVALID_SELECTOR();
+ error SELECTOR_ALREADY_EXISTS();
+ error SELECTOR_NOT_EXISTS();
+
bytes4 internal constant SENTINEL_SELECTOR = 0x00000001;
uint32 internal constant SENTINEL_UINT = 1;
- function isSafeSelector(bytes4 selector) internal pure returns (bool) {
- return uint32(selector) > SENTINEL_UINT;
- }
-
modifier onlySelector(bytes4 selector) {
- if (!isSafeSelector(selector)) {
- revert Errors.INVALID_SELECTOR();
+ if (uint32(selector) <= SENTINEL_UINT) {
+ revert INVALID_SELECTOR();
}
_;
}
function add(mapping(bytes4 => bytes4) storage self, bytes4 selector) internal onlySelector(selector) {
if (self[selector] != 0) {
- revert Errors.SELECTOR_ALREADY_EXISTS();
+ revert SELECTOR_ALREADY_EXISTS();
}
bytes4 _prev = self[SENTINEL_SELECTOR];
if (_prev == 0) {
@@ -41,31 +39,9 @@ library SelectorLinkedList {
}
}
- function replace(mapping(bytes4 => bytes4) storage self, bytes4 oldSelector, bytes4 newSelector) internal {
- if (!isExist(self, oldSelector)) {
- revert Errors.SELECTOR_NOT_EXISTS();
- }
- if (isExist(self, newSelector)) {
- revert Errors.SELECTOR_ALREADY_EXISTS();
- }
-
- bytes4 cursor = SENTINEL_SELECTOR;
- while (true) {
- bytes4 _selector = self[cursor];
- if (_selector == oldSelector) {
- bytes4 next = self[_selector];
- self[newSelector] = next;
- self[cursor] = newSelector;
- self[_selector] = 0;
- return;
- }
- cursor = _selector;
- }
- }
-
function remove(mapping(bytes4 => bytes4) storage self, bytes4 selector) internal {
if (!isExist(self, selector)) {
- revert Errors.SELECTOR_NOT_EXISTS();
+ revert SELECTOR_NOT_EXISTS();
}
bytes4 cursor = SENTINEL_SELECTOR;
@@ -86,10 +62,13 @@ library SelectorLinkedList {
}
function clear(mapping(bytes4 => bytes4) storage self) internal {
- for (bytes4 selector = self[SENTINEL_SELECTOR]; uint32(selector) > SENTINEL_UINT; selector = self[selector]) {
+ bytes4 selector = self[SENTINEL_SELECTOR];
+ self[SENTINEL_SELECTOR] = 0;
+ while (uint32(selector) > SENTINEL_UINT) {
+ bytes4 _selector = self[selector];
self[selector] = 0;
+ selector = _selector;
}
- self[SENTINEL_SELECTOR] = 0;
}
function isExist(mapping(bytes4 => bytes4) storage self, bytes4 selector)
diff --git a/lib/SoulWalletCore/contracts/utils/SignatureDecoder.sol b/lib/SoulWalletCore/contracts/utils/SignatureDecoder.sol
new file mode 100644
index 00000000..d558d749
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/utils/SignatureDecoder.sol
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+library SignatureDecoder {
+ /*
+
+ Signature:
+ [0:20]: `validator address`
+ [20:24]: n = `validator signature length`, bytes4 max to 16777215 bytes
+ [24:24+n]: `validator signature`
+ [24+n:]: `hook signature` [optional]
+
+ `hook signature`:
+ [0:20]: `first hook address`
+ [20:24]: n1 = `first hook signature length`, bytes4 max to 16777215 bytes
+ [24:24+n1]: `first hook signature`
+
+ `[optional]`
+ [24+n1:24+n1+20]: `second hook signature`
+ [24+n1+20:24+n1+24]: n2 = `second hook signature length`, bytes4 max to 16777215 bytes
+ [24+n1+24:24+n1+24+n2]: `second hook signature`
+
+ ...
+ */
+ function signatureSplit(bytes calldata self)
+ internal
+ pure
+ returns (address validator, bytes calldata validatorSignature, bytes calldata hookSignature)
+ {
+ /*
+ Equivalent code:
+ validator = address(bytes20(self[0:20]));
+ uint32 validatorSignatureLength = uint32(bytes4(self[20:24]));
+ uint256 hookSignatureStartAt;
+ unchecked {
+ hookSignatureStartAt = 24 + validatorSignatureLength;
+ }
+ validatorSignature = self[24:hookSignatureStartAt];
+ hookSignature = self[hookSignatureStartAt:];
+ */
+ assembly ("memory-safe") {
+ if lt(self.length, 24) { revert(0, 0) }
+
+ {
+ // validator
+ let _validator := calldataload(self.offset)
+ // _validator >> ((32-20)*8)
+ validator := shr(96, _validator)
+ }
+ {
+ // validatorSignature
+ let _validatorSignatureLength := calldataload(add(20, self.offset))
+ // _validatorSignatureLength >> ((32-4)*8)
+ let validatorSignatureLength := shr(224, _validatorSignatureLength)
+
+ if gt(add(24, validatorSignatureLength), self.length) { revert(0, 0) }
+ validatorSignature.offset := add(24, self.offset)
+ validatorSignature.length := validatorSignatureLength
+ }
+ {
+ // hookSignature
+ hookSignature.offset := add(validatorSignature.offset, validatorSignature.length)
+ hookSignature.length := sub(sub(self.length, validatorSignature.length), 24)
+ }
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/utils/UserOperationLib.sol b/lib/SoulWalletCore/contracts/utils/UserOperationLib.sol
new file mode 100644
index 00000000..561b846b
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/utils/UserOperationLib.sol
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.20;
+
+import {UserOperation} from "../interface/IAccount.sol";
+
+library UserOperationLib {
+ /*
+ In calldata, the data structure of the UserOperation is always:
+ refer to:https://docs.soliditylang.org/en/develop/abi-spec.html
+ offset: 0x00 000000000000000000000000aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # sender
+ offset: 0x20 000000000000000000000000000000000000000000000000000b0b0b0b0b0b0b # nonce
+ offset: 0x40 0000000000000000000000000000000000000000000000000000000000000160 # initCode offset
+ offset: 0x60 00000000000000000000000000000000000000000000000000000000000001a0 # callData offset
+ offset: 0x80 000000000000000000000000000000000000000000000000000e0e0e0e0e0e0e # callGasLimit
+ offset: 0xa0 000000000000000000000000000000000000000000000000000f0f0f0f0f0f0f # verificationGasLimit
+ offset: 0xc0 0000000000000000000000000000000000000000000000000010101010101010 # preVerificationGas
+ offset: 0xe0 0000000000000000000000000000000000000000000000000011111111111111 # maxFeePerGas
+ offset:0x100 0000000000000000000000000000000000000000000000000012121212121212 # maxPriorityFeePerGas
+ offset:0x120 00000000000000000000000000000000000000000000000000000000000001e0 # paymasterAndData offset
+ offset:0x140 0000000000000000000000000000000000000000000000000000000000000220 # signature offset
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ──┐
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx │ dynamic data
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx │
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ──┘
+ */
+ function getSignature(UserOperation calldata userOp) internal pure returns (bytes calldata signature) {
+ assembly ("memory-safe") {
+ let userOpOffset := userOp
+ let signatureOffset := add(userOpOffset, calldataload(add(userOpOffset, 0x140)))
+ signature.length := calldataload(signatureOffset)
+ signature.offset := add(signatureOffset, 0x20)
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/contracts/validators/EOAValidator.sol b/lib/SoulWalletCore/contracts/validators/EOAValidator.sol
new file mode 100644
index 00000000..e5af654f
--- /dev/null
+++ b/lib/SoulWalletCore/contracts/validators/EOAValidator.sol
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IValidator} from "../interface/IValidator.sol";
+import {UserOperation} from "../interface/IAccount.sol";
+import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
+import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
+import {IOwnable} from "../interface/IOwnable.sol";
+import {SIG_VALIDATION_FAILED, SIG_VALIDATION_SUCCESS} from "../utils/Constants.sol";
+
+contract EOAValidator is IValidator {
+ using ECDSA for bytes32;
+ using MessageHashUtils for bytes32;
+
+ // Magic value indicating a valid signature for ERC-1271 contracts
+ bytes4 private constant MAGICVALUE = bytes4(keccak256("isValidSignature(bytes32,bytes)"));
+
+ bytes4 private constant INTERFACE_ID_VALIDATOR = type(IValidator).interfaceId;
+
+ function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
+ return interfaceId == INTERFACE_ID_VALIDATOR;
+ }
+
+ function Init(bytes calldata data) external pure override {}
+
+ function DeInit() external pure override {}
+
+ function _packHash(bytes32 hash) internal view returns (bytes32) {
+ /*
+ must pack the hash with the chainId and the address of the wallet contract to prevent replay attacks
+ */
+ return keccak256(abi.encode(hash, msg.sender, block.chainid));
+ }
+
+ function _isOwner(address addr) private view returns (bool isOwner) {
+ bytes memory callData = abi.encodeWithSelector(IOwnable.isOwner.selector, bytes32(uint256(uint160(addr))));
+ assembly ("memory-safe") {
+ // memorySafe: The scratch space between memory offset 0 and 64.
+
+ // IOwnable(msg.sender).isOwner(bytes32(uint256(uint160(addr)))) returns (bool result)
+ let result := staticcall(gas(), caller(), add(callData, 0x20), mload(callData), 0x00, 0x20)
+ if result { isOwner := mload(0x00) }
+ }
+ }
+
+ function validateSignature(address sender, bytes32 hash, bytes calldata validatorSignature)
+ external
+ view
+ override
+ returns (bytes4 magicValue)
+ {
+ (sender);
+ if (validatorSignature.length != 65) {
+ return bytes4(0);
+ }
+ bytes32 r = bytes32(validatorSignature[0:0x20]);
+ bytes32 s = bytes32(validatorSignature[0x20:0x40]);
+ uint8 v = uint8(bytes1(validatorSignature[0x40:0x41]));
+
+ (address recoveredAddr, ECDSA.RecoverError error,) =
+ ECDSA.tryRecover(_packHash(hash).toEthSignedMessageHash(), v, r, s);
+ if (error != ECDSA.RecoverError.NoError) {
+ return bytes4(0);
+ }
+ return _isOwner(recoveredAddr) ? MAGICVALUE : bytes4(0);
+ }
+
+ function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, bytes calldata validatorSignature)
+ external
+ view
+ override
+ returns (uint256 validationData)
+ {
+ (userOp);
+
+ if (validatorSignature.length != 65) {
+ return SIG_VALIDATION_FAILED;
+ }
+ bytes32 r = bytes32(validatorSignature[0x00:0x20]);
+ bytes32 s = bytes32(validatorSignature[0x20:0x40]);
+ uint8 v = uint8(bytes1(validatorSignature[0x40:0x41]));
+ (address recoveredAddr, ECDSA.RecoverError error,) =
+ ECDSA.tryRecover(_packHash(userOpHash).toEthSignedMessageHash(), v, r, s);
+ if (error != ECDSA.RecoverError.NoError) {
+ return SIG_VALIDATION_FAILED;
+ }
+ return _isOwner(recoveredAddr) ? SIG_VALIDATION_SUCCESS : SIG_VALIDATION_FAILED;
+ }
+}
diff --git a/lib/SoulWalletCore/examples/AddFunctionDemo/AddFunctionDemo.sol b/lib/SoulWalletCore/examples/AddFunctionDemo/AddFunctionDemo.sol
new file mode 100644
index 00000000..a73c6fbb
--- /dev/null
+++ b/lib/SoulWalletCore/examples/AddFunctionDemo/AddFunctionDemo.sol
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {SoulWalletCore} from "../../contracts/SoulWalletCore.sol";
+import {OwnerManager} from "./base/OwnerManager.sol";
+
+import {ModuleInstaller} from "../../contracts/extensions/ModuleInstaller.sol";
+import {HookInstaller} from "../../contracts/extensions/HookInstaller.sol";
+import {ValidatorInstaller} from "../../contracts/extensions/ValidatorInstaller.sol";
+
+contract AddFunctionDemo is SoulWalletCore, OwnerManager, ValidatorInstaller, HookInstaller, ModuleInstaller {
+ uint256 private _initialized;
+
+ modifier initializer() {
+ require(_initialized == 0);
+ _initialized = 1;
+ _;
+ }
+
+ constructor(address _entryPoint) SoulWalletCore(_entryPoint) initializer {}
+
+ function initialize(bytes32 owner, bytes calldata validatorAndData, address defaultFallback) external initializer {
+ _addOwner(owner);
+ _installValidator(address(bytes20(validatorAndData[:20])), validatorAndData[20:]);
+ _setFallbackHandler(defaultFallback);
+ }
+}
diff --git a/lib/SoulWalletCore/examples/AddFunctionDemo/base/OwnerManager.sol b/lib/SoulWalletCore/examples/AddFunctionDemo/base/OwnerManager.sol
new file mode 100644
index 00000000..c5671186
--- /dev/null
+++ b/lib/SoulWalletCore/examples/AddFunctionDemo/base/OwnerManager.sol
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {IOwnerManager} from "../interface/IOwnerManager.sol";
+import {AuthoritySnippet} from "../../../contracts/snippets/Authority.sol";
+import {OwnerManagerSnippet} from "../../../contracts/snippets/OwnerManager.sol";
+
+abstract contract OwnerManager is IOwnerManager, AuthoritySnippet, OwnerManagerSnippet {
+ function addOwners(bytes32[] calldata owner) external override {
+ ownerManagementAccess();
+
+ for (uint256 i = 0; i < owner.length; i++) {
+ _addOwner(owner[i]);
+ }
+ }
+
+ function removeOwners(bytes32[] calldata owner) external override {
+ ownerManagementAccess();
+
+ for (uint256 i = 0; i < owner.length; i++) {
+ _removeOwner(owner[i]);
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/examples/AddFunctionDemo/interface/IOwnerManager.sol b/lib/SoulWalletCore/examples/AddFunctionDemo/interface/IOwnerManager.sol
new file mode 100644
index 00000000..a93210e5
--- /dev/null
+++ b/lib/SoulWalletCore/examples/AddFunctionDemo/interface/IOwnerManager.sol
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+interface IOwnerManager {
+ function addOwners(bytes32[] calldata owner) external;
+ function removeOwners(bytes32[] calldata owner) external;
+}
diff --git a/lib/SoulWalletCore/examples/BasicModularAccount.sol b/lib/SoulWalletCore/examples/BasicModularAccount.sol
new file mode 100644
index 00000000..ad22d499
--- /dev/null
+++ b/lib/SoulWalletCore/examples/BasicModularAccount.sol
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {SoulWalletCore} from "../contracts/SoulWalletCore.sol";
+import {ModuleInstaller} from "../contracts/extensions/ModuleInstaller.sol";
+import {HookInstaller} from "../contracts/extensions/HookInstaller.sol";
+import {ValidatorInstaller} from "../contracts/extensions/ValidatorInstaller.sol";
+
+contract BasicModularAccount is SoulWalletCore, ValidatorInstaller, HookInstaller, ModuleInstaller {
+ uint256 private _initialized;
+
+ modifier initializer() {
+ require(_initialized == 0);
+ _initialized = 1;
+ _;
+ }
+
+ constructor(address _entryPoint) SoulWalletCore(_entryPoint) initializer {}
+
+ function initialize(bytes32 owner, bytes calldata validatorAndData, address defaultFallback) external initializer {
+ _addOwner(owner);
+ _installValidator(address(bytes20(validatorAndData[:20])), validatorAndData[20:]);
+ _setFallbackHandler(defaultFallback);
+ }
+}
diff --git a/lib/SoulWalletCore/examples/CustomAccessModularAccount.sol b/lib/SoulWalletCore/examples/CustomAccessModularAccount.sol
new file mode 100644
index 00000000..7aa4b2a8
--- /dev/null
+++ b/lib/SoulWalletCore/examples/CustomAccessModularAccount.sol
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {SoulWalletCore} from "../contracts/SoulWalletCore.sol";
+import {ModuleInstaller} from "../contracts/extensions/ModuleInstaller.sol";
+import {HookInstaller} from "../contracts/extensions/HookInstaller.sol";
+import {ValidatorInstaller} from "../contracts/extensions/ValidatorInstaller.sol";
+
+contract BasicModularAccount is SoulWalletCore, ValidatorInstaller, HookInstaller, ModuleInstaller {
+ uint256 private _initialized;
+
+ modifier initializer() {
+ require(_initialized == 0);
+ _initialized = 1;
+ _;
+ }
+
+ constructor(address _entryPoint) SoulWalletCore(_entryPoint) initializer {}
+
+ function initialize(
+ bytes32 owner,
+ bytes calldata validatorAndData,
+ address defaultFallback,
+ address[] calldata modules
+ ) external initializer {
+ _addOwner(owner);
+ _installValidator(address(bytes20(validatorAndData[:20])), validatorAndData[20:]);
+ _setFallbackHandler(defaultFallback);
+ for (uint256 i = 0; i < modules.length; i++) {
+ _installModule(modules[i]);
+ }
+ }
+
+ /**
+ * Only authorized modules can manage hooks and modules.
+ */
+ function pluginManagementAccess() internal view override {
+ _onlyModule();
+ }
+}
diff --git a/lib/SoulWalletCore/examples/ModularAccountWithBuildinEOAValidator.sol b/lib/SoulWalletCore/examples/ModularAccountWithBuildinEOAValidator.sol
new file mode 100644
index 00000000..233109d1
--- /dev/null
+++ b/lib/SoulWalletCore/examples/ModularAccountWithBuildinEOAValidator.sol
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {UserOperation} from "../contracts/interface/IAccount.sol";
+import {SoulWalletCore} from "../contracts/SoulWalletCore.sol";
+import {UserOperation} from "../contracts/interface/IAccount.sol";
+import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
+import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
+import {OwnerManagerSnippet} from "../contracts/snippets/OwnerManager.sol";
+import {SIG_VALIDATION_FAILED, SIG_VALIDATION_SUCCESS} from "../contracts/utils/Constants.sol";
+import {ModuleInstaller} from "../contracts/extensions/ModuleInstaller.sol";
+import {HookInstaller} from "../contracts/extensions/HookInstaller.sol";
+import {ValidatorInstaller} from "../contracts/extensions/ValidatorInstaller.sol";
+import {ValidatorManager} from "../contracts/base/ValidatorManager.sol";
+import {ValidatorManagerSnippet} from "../contracts/snippets/ValidatorManager.sol";
+
+abstract contract BuildinEOAValidator is OwnerManagerSnippet {
+ using ECDSA for bytes32;
+ using MessageHashUtils for bytes32;
+
+ // Magic value indicating a valid signature for ERC-1271 contracts
+ bytes4 private constant __MAGICVALUE = bytes4(keccak256("isValidSignature(bytes32,bytes)"));
+
+ function __packHash(bytes32 hash) internal view returns (bytes32) {
+ return keccak256(abi.encode(hash, address(this), block.chainid));
+ }
+
+ function __validateSignature(bytes32 hash, bytes calldata validatorSignature)
+ internal
+ view
+ returns (bytes4 magicValue)
+ {
+ if (validatorSignature.length != 65) {
+ return bytes4(0);
+ }
+
+ bytes32 r = bytes32(validatorSignature[0:0x20]);
+ bytes32 s = bytes32(validatorSignature[0x20:0x40]);
+ uint8 v = uint8(bytes1(validatorSignature[0x40:0x41]));
+
+ (address recoveredAddr, ECDSA.RecoverError error,) =
+ ECDSA.tryRecover(__packHash(hash).toEthSignedMessageHash(), v, r, s);
+ if (error != ECDSA.RecoverError.NoError) {
+ return bytes4(0);
+ }
+ return _isOwner(bytes32(uint256(uint160(recoveredAddr)))) ? __MAGICVALUE : bytes4(0);
+ }
+
+ function __validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, bytes calldata validatorSignature)
+ internal
+ view
+ returns (uint256 validationData)
+ {
+ (userOp);
+
+ if (validatorSignature.length != 65) {
+ return SIG_VALIDATION_FAILED;
+ }
+ bytes32 r = bytes32(validatorSignature[0x00:0x20]);
+ bytes32 s = bytes32(validatorSignature[0x20:0x40]);
+ uint8 v = uint8(bytes1(validatorSignature[0x40:0x41]));
+
+ (address recoveredAddr, ECDSA.RecoverError error,) =
+ ECDSA.tryRecover(__packHash(userOpHash).toEthSignedMessageHash(), v, r, s);
+ if (error != ECDSA.RecoverError.NoError) {
+ return SIG_VALIDATION_FAILED;
+ }
+
+ return _isOwner(bytes32(uint256(uint160(recoveredAddr)))) ? SIG_VALIDATION_SUCCESS : SIG_VALIDATION_FAILED;
+ }
+}
+
+contract ModularAccountWithBuildinEOAValidator is
+ ValidatorInstaller,
+ HookInstaller,
+ ModuleInstaller,
+ SoulWalletCore,
+ BuildinEOAValidator
+{
+ uint256 private _initialized;
+
+ modifier initializer() {
+ require(_initialized == 0);
+ _initialized = 1;
+ _;
+ }
+
+ constructor(address _entryPoint) SoulWalletCore(_entryPoint) initializer {}
+
+ function initialize(bytes32 owner) external initializer {
+ _addOwner(owner);
+ }
+
+ /**
+ * @dev EIP-1271
+ * @param hash hash of the data to be signed
+ * @param validator validator address
+ * @param validatorSignature Signature byte array associated with _data
+ * @return magicValue Magic value 0x1626ba7e if the validator is registered and signature is valid
+ */
+ function _isValidSignature(bytes32 hash, address validator, bytes calldata validatorSignature)
+ internal
+ view
+ override(ValidatorManagerSnippet, ValidatorManager)
+ returns (bytes4 magicValue)
+ {
+ if (validator == address(0)) {
+ return __validateSignature(hash, validatorSignature);
+ }
+ return super._isValidSignature(hash, validator, validatorSignature);
+ }
+
+ /**
+ * @dev validate UserOperation
+ * @param userOp UserOperation
+ * @param userOpHash UserOperation hash
+ * @param validator validator address
+ * @param validatorSignature validator signature
+ * @return validationData refer to https://github.com/eth-infinitism/account-abstraction/blob/v0.6.0/contracts/interfaces/IAccount.sol#L24-L30
+ */
+ function _validateUserOp(
+ UserOperation calldata userOp,
+ bytes32 userOpHash,
+ address validator,
+ bytes calldata validatorSignature
+ ) internal override(ValidatorManagerSnippet, ValidatorManager) returns (uint256 validationData) {
+ if (validator == address(0)) {
+ return __validateUserOp(userOp, userOpHash, validatorSignature);
+ }
+ return super._validateUserOp(userOp, userOpHash, validator, validatorSignature);
+ }
+}
diff --git a/lib/SoulWalletCore/examples/UpgradableModularAccount.sol b/lib/SoulWalletCore/examples/UpgradableModularAccount.sol
new file mode 100644
index 00000000..02a6a48a
--- /dev/null
+++ b/lib/SoulWalletCore/examples/UpgradableModularAccount.sol
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.20;
+
+import {BasicModularAccount} from "./BasicModularAccount.sol";
+import {ModuleInstaller} from "../contracts/extensions/ModuleInstaller.sol";
+import {HookInstaller} from "../contracts/extensions/HookInstaller.sol";
+import {ValidatorInstaller} from "../contracts/extensions/ValidatorInstaller.sol";
+
+contract UpgradableModularAccount is BasicModularAccount, ValidatorInstaller, HookInstaller, ModuleInstaller {
+ //
+ event Upgraded(address indexed oldImplementation, address indexed newImplementation);
+
+ /**
+ * @dev Storage slot with the address of the current implementation:
+ * https://github.com/SoulWallet/SoulWalletCore/blob/main/test/dev/SoulWalletProxy.sol
+ * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1
+ */
+ bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
+
+ function upgradeTo(address newImplementation) external {
+ _onlySelfOrModule();
+
+ bool isContract;
+ assembly ("memory-safe") {
+ isContract := gt(extcodesize(newImplementation), 0)
+ }
+ if (!isContract) {
+ revert("new implementation is not a contract");
+ }
+ address oldImplementation;
+ assembly ("memory-safe") {
+ oldImplementation := and(sload(_IMPLEMENTATION_SLOT), 0xffffffffffffffffffffffffffffffffffffffff)
+ }
+ if (oldImplementation == newImplementation) {
+ revert("new implementation is the same as old one");
+ }
+ assembly ("memory-safe") {
+ sstore(_IMPLEMENTATION_SLOT, newImplementation)
+ }
+
+ emit Upgraded(oldImplementation, newImplementation);
+ }
+}
diff --git a/lib/SoulWalletCore/foundry.toml b/lib/SoulWalletCore/foundry.toml
new file mode 100644
index 00000000..b9085415
--- /dev/null
+++ b/lib/SoulWalletCore/foundry.toml
@@ -0,0 +1,17 @@
+[profile.default]
+src = "contracts"
+out = "out"
+libs = ["lib"]
+
+solc = "0.8.23"
+optimizer = true
+optimizer_runs = 100000
+via_ir = true
+evm_version = "paris"
+
+# [profile.default.model_checker]
+# contracts = { './contracts/SoulWalletCore.sol' = ['Contract'] }
+# engine = 'all'
+# timeout = 10000
+
+# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
diff --git a/lib/SoulWalletCore/gas.md b/lib/SoulWalletCore/gas.md
new file mode 100644
index 00000000..b9389b6e
--- /dev/null
+++ b/lib/SoulWalletCore/gas.md
@@ -0,0 +1,9 @@
+# Gas Checker
+
+| Name | Gas Used |
+| ---- | -------- |
+| ERC20 batch transfer | 46810 |
+| ETH batch transfer | 56558 |
+| Deploy Account | 360863 |
+| ERC20 transfer | 91855 |
+| ETH transfer | 103380 |
diff --git a/lib/SoulWalletCore/lib/account-abstraction/.eslintrc.js b/lib/SoulWalletCore/lib/account-abstraction/.eslintrc.js
new file mode 100644
index 00000000..fde1d6d6
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/.eslintrc.js
@@ -0,0 +1,79 @@
+module.exports = {
+ env: {
+ browser: true,
+ es6: true,
+ jest: true,
+ mocha: true,
+ node: true
+ },
+ globals: {
+ artifacts: false,
+ assert: false,
+ contract: false,
+ web3: false
+ },
+ extends:
+ [
+ 'standard-with-typescript'
+ ],
+ // This is needed to add configuration to rules with type information
+ parser: '@typescript-eslint/parser',
+ parserOptions: {
+ project: ['./tsconfig.json']
+ },
+ ignorePatterns: [
+ '.eslintrc.js',
+ '**/types/truffle-contracts',
+ 'coverage',
+ 'dist/'
+ ],
+ rules: {
+ 'no-console': 'off',
+ '@typescript-eslint/no-var-requires': 'off',
+ '@typescript-eslint/return-await': 'off',
+ '@typescript-eslint/no-unnecessary-type-assertion': 'off',
+ '@typescript-eslint/require-array-sort-compare': ['error',
+ {
+ ignoreStringArrays: true
+ }
+ ]
+ },
+ overrides: [
+ {
+ files: '*',
+ rules: {
+ '@typescript-eslint/naming-convention': 'off',
+ '@typescript-eslint/no-non-null-assertion': 'off',
+ '@typescript-eslint/restrict-template-expressions': 'off'
+ }
+ },
+ {
+ files: [
+ '**/test/**/*.ts'
+ ],
+ rules: {
+ 'no-unused-expressions': 'off',
+ // chai assertions trigger this rule
+ '@typescript-eslint/no-unused-expressions': 'off',
+ '@typescript-eslint/no-non-null-assertion': 'off'
+ }
+ },
+ {
+ // otherwise it will raise an error in every JavaScript file
+ files: ['*.ts'],
+ rules: {
+ '@typescript-eslint/prefer-ts-expect-error': 'off',
+ // allow using '${val}' with numbers, bool and null types
+ '@typescript-eslint/restrict-template-expressions': [
+ 'error',
+ {
+ allowNumber: true,
+ allowBoolean: true,
+ allowNullish: true,
+ allowNullable: true
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/.github/workflows/build.yml b/lib/SoulWalletCore/lib/account-abstraction/.github/workflows/build.yml
new file mode 100644
index 00000000..308b4cb3
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/.github/workflows/build.yml
@@ -0,0 +1,88 @@
+name: Build
+on:
+ push:
+ branches:
+ - '*'
+ pull_request:
+ types: [opened, reopened, synchronize]
+
+env:
+ TS_NODE_TRANSPILE_ONLY: 1
+ FORCE_COLORS: 1
+
+# todo: extract shared seto/checkout/install/compile, instead of repeat in each job.
+jobs:
+
+ test:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/setup-node@v1
+ with:
+ node-version: '14'
+ - uses: actions/checkout@v1
+ - uses: actions/cache@v2
+ with:
+ path: node_modules
+ key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
+ - run: yarn install
+ - run: yarn compile
+
+ - run: yarn run ci
+
+ gas-checks:
+ runs-on: ubuntu-latest
+ services:
+ localgeth:
+ image: dtr22/geth-dev
+
+ steps:
+ - uses: actions/setup-node@v1
+ with:
+ node-version: '14'
+ - uses: actions/checkout@v1
+ - uses: actions/cache@v2
+ with:
+ path: node_modules
+ key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
+ - run: yarn install
+ - run: yarn compile
+ - run: yarn ci-gas-calc
+
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/setup-node@v1
+ with:
+ node-version: '14'
+ - uses: actions/checkout@v1
+ - uses: actions/cache@v2
+ with:
+ path: node_modules
+ key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
+ - run: yarn install
+ - run: yarn lint
+
+ coverage:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/setup-node@v1
+ with:
+ node-version: '14'
+ - uses: actions/checkout@v1
+ - uses: actions/cache@v2
+ with:
+ path: node_modules
+ key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
+ - run: yarn install
+
+ - run: yarn compile
+
+ - run: FORCE_COLOR=1 yarn coverage
+ - uses: actions/upload-artifact@v2
+ with:
+ name: solidity-coverage
+ path: |
+ coverage/
+ coverage.json
+
diff --git a/lib/SoulWalletCore/lib/account-abstraction/.gitignore b/lib/SoulWalletCore/lib/account-abstraction/.gitignore
new file mode 100644
index 00000000..f6a4ff52
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/.gitignore
@@ -0,0 +1,20 @@
+node_modules
+
+#Hardhat files
+cache
+artifacts
+/.idea/
+/typechain/
+/dist/
+/yarn-error.log
+/deployments/dev/
+/deployments/localhost/
+/deployments/proxy/
+/typechain-types/
+/reports/gas-used-output.color
+/coverage
+/coverage.json
+/.DS_Store
+.DS_Store
+/contracts/dist/
+/contracts/types/
diff --git a/lib/SoulWalletCore/lib/account-abstraction/.solcover.js b/lib/SoulWalletCore/lib/account-abstraction/.solcover.js
new file mode 100644
index 00000000..186efeaf
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/.solcover.js
@@ -0,0 +1,10 @@
+module.exports = {
+ skipFiles: [
+ "test",
+ "samples/bls/lib",
+ //solc-coverage fails to compile our Manager module.
+ "samples/gnosis",
+ "utils/Exec.sol"
+ ],
+ configureYulOptimizer: true,
+};
diff --git a/lib/SoulWalletCore/lib/account-abstraction/.solhint.json b/lib/SoulWalletCore/lib/account-abstraction/.solhint.json
new file mode 100644
index 00000000..e00f27b5
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/.solhint.json
@@ -0,0 +1,8 @@
+{
+ "extends": "solhint:recommended",
+ "rules": {
+ "compiler-version": ["error",">=0.7.5"],
+ "func-visibility": ["off",{"ignoreConstructors":true}],
+ "mark-callable-contracts": ["off"]
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/.solhintignore b/lib/SoulWalletCore/lib/account-abstraction/.solhintignore
new file mode 100644
index 00000000..4972aa1b
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/.solhintignore
@@ -0,0 +1 @@
+contracts/samples/bls/lib/
diff --git a/lib/SoulWalletCore/lib/account-abstraction/README.md b/lib/SoulWalletCore/lib/account-abstraction/README.md
new file mode 100644
index 00000000..57216f82
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/README.md
@@ -0,0 +1,11 @@
+Implementation of contracts for [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337) account abstraction via alternative mempool.
+
+# Resources
+
+[Vitalik's post on account abstraction without Ethereum protocol changes](https://medium.com/infinitism/erc-4337-account-abstraction-without-ethereum-protocol-changes-d75c9d94dc4a)
+
+[Discord server](http://discord.gg/fbDyENb6Y9)
+
+[Bundler reference implementation](https://github.com/eth-infinitism/bundler)
+
+[Bundler specification test suite](https://github.com/eth-infinitism/bundler-spec-tests)
diff --git "a/lib/SoulWalletCore/lib/account-abstraction/audits/EIP_4337_\342\200\223_Ethereum_Account_Abstraction_Incremental_Audit_Feb_2023.pdf" "b/lib/SoulWalletCore/lib/account-abstraction/audits/EIP_4337_\342\200\223_Ethereum_Account_Abstraction_Incremental_Audit_Feb_2023.pdf"
new file mode 100644
index 00000000..7050f47a
Binary files /dev/null and "b/lib/SoulWalletCore/lib/account-abstraction/audits/EIP_4337_\342\200\223_Ethereum_Account_Abstraction_Incremental_Audit_Feb_2023.pdf" differ
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/.npmignore b/lib/SoulWalletCore/lib/account-abstraction/contracts/.npmignore
new file mode 100644
index 00000000..b6abf238
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/.npmignore
@@ -0,0 +1,2 @@
+**/*Test*
+yarn*
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/core/BaseAccount.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/BaseAccount.sol
new file mode 100644
index 00000000..95b26399
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/BaseAccount.sol
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+/* solhint-disable avoid-low-level-calls */
+/* solhint-disable no-empty-blocks */
+
+import "../interfaces/IAccount.sol";
+import "../interfaces/IEntryPoint.sol";
+import "./Helpers.sol";
+
+/**
+ * Basic account implementation.
+ * this contract provides the basic logic for implementing the IAccount interface - validateUserOp
+ * specific account implementation should inherit it and provide the account-specific logic
+ */
+abstract contract BaseAccount is IAccount {
+ using UserOperationLib for UserOperation;
+
+ //return value in case of signature failure, with no time-range.
+ // equivalent to _packValidationData(true,0,0);
+ uint256 constant internal SIG_VALIDATION_FAILED = 1;
+
+ /**
+ * Return the account nonce.
+ * This method returns the next sequential nonce.
+ * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`
+ */
+ function getNonce() public view virtual returns (uint256) {
+ return entryPoint().getNonce(address(this), 0);
+ }
+
+ /**
+ * return the entryPoint used by this account.
+ * subclass should return the current entryPoint used by this account.
+ */
+ function entryPoint() public view virtual returns (IEntryPoint);
+
+ /**
+ * Validate user's signature and nonce.
+ * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.
+ */
+ function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)
+ external override virtual returns (uint256 validationData) {
+ _requireFromEntryPoint();
+ validationData = _validateSignature(userOp, userOpHash);
+ _validateNonce(userOp.nonce);
+ _payPrefund(missingAccountFunds);
+ }
+
+ /**
+ * ensure the request comes from the known entrypoint.
+ */
+ function _requireFromEntryPoint() internal virtual view {
+ require(msg.sender == address(entryPoint()), "account: not from EntryPoint");
+ }
+
+ /**
+ * validate the signature is valid for this message.
+ * @param userOp validate the userOp.signature field
+ * @param userOpHash convenient field: the hash of the request, to check the signature against
+ * (also hashes the entrypoint and chain id)
+ * @return validationData signature and time-range of this operation
+ * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,
+ * otherwise, an address of an "authorizer" contract.
+ * <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite"
+ * <6-byte> validAfter - first timestamp this operation is valid
+ * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.
+ * Note that the validation code cannot use block.timestamp (or block.number) directly.
+ */
+ function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)
+ internal virtual returns (uint256 validationData);
+
+ /**
+ * Validate the nonce of the UserOperation.
+ * This method may validate the nonce requirement of this account.
+ * e.g.
+ * To limit the nonce to use sequenced UserOps only (no "out of order" UserOps):
+ * `require(nonce < type(uint64).max)`
+ * For a hypothetical account that *requires* the nonce to be out-of-order:
+ * `require(nonce & type(uint64).max == 0)`
+ *
+ * The actual nonce uniqueness is managed by the EntryPoint, and thus no other
+ * action is needed by the account itself.
+ *
+ * @param nonce to validate
+ *
+ * solhint-disable-next-line no-empty-blocks
+ */
+ function _validateNonce(uint256 nonce) internal view virtual {
+ }
+
+ /**
+ * sends to the entrypoint (msg.sender) the missing funds for this transaction.
+ * subclass MAY override this method for better funds management
+ * (e.g. send to the entryPoint more than the minimum required, so that in future transactions
+ * it will not be required to send again)
+ * @param missingAccountFunds the minimum value this method should send the entrypoint.
+ * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.
+ */
+ function _payPrefund(uint256 missingAccountFunds) internal virtual {
+ if (missingAccountFunds != 0) {
+ (bool success,) = payable(msg.sender).call{value : missingAccountFunds, gas : type(uint256).max}("");
+ (success);
+ //ignore failure (its EntryPoint's job to verify, not account.)
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/core/BasePaymaster.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/BasePaymaster.sol
new file mode 100644
index 00000000..74f2a792
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/BasePaymaster.sol
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+
+/* solhint-disable reason-string */
+
+import "@openzeppelin/contracts/access/Ownable.sol";
+import "../interfaces/IPaymaster.sol";
+import "../interfaces/IEntryPoint.sol";
+import "./Helpers.sol";
+
+/**
+ * Helper class for creating a paymaster.
+ * provides helper methods for staking.
+ * validates that the postOp is called only by the entryPoint
+ */
+abstract contract BasePaymaster is IPaymaster, Ownable {
+
+ IEntryPoint immutable public entryPoint;
+
+ constructor(IEntryPoint _entryPoint, address _owner) Ownable(_owner) {
+ entryPoint = _entryPoint;
+ }
+
+ /// @inheritdoc IPaymaster
+ function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
+ external override returns (bytes memory context, uint256 validationData) {
+ _requireFromEntryPoint();
+ return _validatePaymasterUserOp(userOp, userOpHash, maxCost);
+ }
+
+ function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
+ internal virtual returns (bytes memory context, uint256 validationData);
+
+ /// @inheritdoc IPaymaster
+ function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external override {
+ _requireFromEntryPoint();
+ _postOp(mode, context, actualGasCost);
+ }
+
+ /**
+ * post-operation handler.
+ * (verified to be called only through the entryPoint)
+ * @dev if subclass returns a non-empty context from validatePaymasterUserOp, it must also implement this method.
+ * @param mode enum with the following options:
+ * opSucceeded - user operation succeeded.
+ * opReverted - user op reverted. still has to pay for gas.
+ * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.
+ * Now this is the 2nd call, after user's op was deliberately reverted.
+ * @param context - the context value returned by validatePaymasterUserOp
+ * @param actualGasCost - actual gas used so far (without this postOp call).
+ */
+ function _postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) internal virtual {
+
+ (mode,context,actualGasCost); // unused params
+ // subclass must override this method if validatePaymasterUserOp returns a context
+ revert("must override");
+ }
+
+ /**
+ * add a deposit for this paymaster, used for paying for transaction fees
+ */
+ function deposit() public payable {
+ entryPoint.depositTo{value : msg.value}(address(this));
+ }
+
+ /**
+ * withdraw value from the deposit
+ * @param withdrawAddress target to send to
+ * @param amount to withdraw
+ */
+ function withdrawTo(address payable withdrawAddress, uint256 amount) public onlyOwner {
+ entryPoint.withdrawTo(withdrawAddress, amount);
+ }
+ /**
+ * add stake for this paymaster.
+ * This method can also carry eth value to add to the current stake.
+ * @param unstakeDelaySec - the unstake delay for this paymaster. Can only be increased.
+ */
+ function addStake(uint32 unstakeDelaySec) external payable onlyOwner {
+ entryPoint.addStake{value : msg.value}(unstakeDelaySec);
+ }
+
+ /**
+ * return current paymaster's deposit on the entryPoint.
+ */
+ function getDeposit() public view returns (uint256) {
+ return entryPoint.balanceOf(address(this));
+ }
+
+ /**
+ * unlock the stake, in order to withdraw it.
+ * The paymaster can't serve requests once unlocked, until it calls addStake again
+ */
+ function unlockStake() external onlyOwner {
+ entryPoint.unlockStake();
+ }
+
+ /**
+ * withdraw the entire paymaster's stake.
+ * stake must be unlocked first (and then wait for the unstakeDelay to be over)
+ * @param withdrawAddress the address to send withdrawn value.
+ */
+ function withdrawStake(address payable withdrawAddress) external onlyOwner {
+ entryPoint.withdrawStake(withdrawAddress);
+ }
+
+ /// validate the call is made from a valid entrypoint
+ function _requireFromEntryPoint() internal virtual {
+ require(msg.sender == address(entryPoint), "Sender not EntryPoint");
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/core/EntryPoint.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/EntryPoint.sol
new file mode 100644
index 00000000..5b0b619d
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/EntryPoint.sol
@@ -0,0 +1,631 @@
+/**
+ ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.
+ ** Only one instance required on each chain.
+ **/
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+/* solhint-disable avoid-low-level-calls */
+/* solhint-disable no-inline-assembly */
+
+import "../interfaces/IAccount.sol";
+import "../interfaces/IPaymaster.sol";
+import "../interfaces/IEntryPoint.sol";
+
+import "../utils/Exec.sol";
+import "./StakeManager.sol";
+import "./SenderCreator.sol";
+import "./Helpers.sol";
+import "./NonceManager.sol";
+import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
+
+contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard {
+
+ using UserOperationLib for UserOperation;
+
+ SenderCreator private immutable senderCreator = new SenderCreator();
+
+ // internal value used during simulation: need to query aggregator.
+ address private constant SIMULATE_FIND_AGGREGATOR = address(1);
+
+ // marker for inner call revert on out of gas
+ bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';
+
+ uint256 private constant REVERT_REASON_MAX_LEN = 2048;
+
+ /**
+ * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value
+ * in case of signature failure, instead of revert.
+ */
+ uint256 public constant SIG_VALIDATION_FAILED = 1;
+
+ /**
+ * compensate the caller's beneficiary address with the collected fees of all UserOperations.
+ * @param beneficiary the address to receive the fees
+ * @param amount amount to transfer.
+ */
+ function _compensate(address payable beneficiary, uint256 amount) internal {
+ require(beneficiary != address(0), "AA90 invalid beneficiary");
+ (bool success,) = beneficiary.call{value : amount}("");
+ require(success, "AA91 failed send to beneficiary");
+ }
+
+ /**
+ * execute a user op
+ * @param opIndex index into the opInfo array
+ * @param userOp the userOp to execute
+ * @param opInfo the opInfo filled by validatePrepayment for this userOp.
+ * @return collected the total amount this userOp paid.
+ */
+ function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {
+ uint256 preGas = gasleft();
+ bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);
+
+ try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {
+ collected = _actualGasCost;
+ } catch {
+ bytes32 innerRevertCode;
+ assembly {
+ returndatacopy(0, 0, 32)
+ innerRevertCode := mload(0)
+ }
+ // handleOps was called with gas limit too low. abort entire bundle.
+ if (innerRevertCode == INNER_OUT_OF_GAS) {
+ //report paymaster, since if it is not deliberately caused by the bundler,
+ // it must be a revert caused by paymaster.
+ revert FailedOp(opIndex, "AA95 out of gas");
+ }
+
+ uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;
+ collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);
+ }
+ }
+
+ /**
+ * Execute a batch of UserOperations.
+ * no signature aggregator is used.
+ * if any account requires an aggregator (that is, it returned an aggregator when
+ * performing simulateValidation), then handleAggregatedOps() must be used instead.
+ * @param ops the operations to execute
+ * @param beneficiary the address to receive the fees
+ */
+ function handleOps(UserOperation[] calldata ops, address payable beneficiary) public nonReentrant {
+
+ uint256 opslen = ops.length;
+ UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);
+
+ unchecked {
+ for (uint256 i = 0; i < opslen; i++) {
+ UserOpInfo memory opInfo = opInfos[i];
+ (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);
+ _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));
+ }
+
+ uint256 collected = 0;
+ emit BeforeExecution();
+
+ for (uint256 i = 0; i < opslen; i++) {
+ collected += _executeUserOp(i, ops[i], opInfos[i]);
+ }
+
+ _compensate(beneficiary, collected);
+ } //unchecked
+ }
+
+ /**
+ * Execute a batch of UserOperation with Aggregators
+ * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)
+ * @param beneficiary the address to receive the fees
+ */
+ function handleAggregatedOps(
+ UserOpsPerAggregator[] calldata opsPerAggregator,
+ address payable beneficiary
+ ) public nonReentrant {
+
+ uint256 opasLen = opsPerAggregator.length;
+ uint256 totalOps = 0;
+ for (uint256 i = 0; i < opasLen; i++) {
+ UserOpsPerAggregator calldata opa = opsPerAggregator[i];
+ UserOperation[] calldata ops = opa.userOps;
+ IAggregator aggregator = opa.aggregator;
+
+ //address(1) is special marker of "signature error"
+ require(address(aggregator) != address(1), "AA96 invalid aggregator");
+
+ if (address(aggregator) != address(0)) {
+ // solhint-disable-next-line no-empty-blocks
+ try aggregator.validateSignatures(ops, opa.signature) {}
+ catch {
+ revert SignatureValidationFailed(address(aggregator));
+ }
+ }
+
+ totalOps += ops.length;
+ }
+
+ UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);
+
+ emit BeforeExecution();
+
+ uint256 opIndex = 0;
+ for (uint256 a = 0; a < opasLen; a++) {
+ UserOpsPerAggregator calldata opa = opsPerAggregator[a];
+ UserOperation[] calldata ops = opa.userOps;
+ IAggregator aggregator = opa.aggregator;
+
+ uint256 opslen = ops.length;
+ for (uint256 i = 0; i < opslen; i++) {
+ UserOpInfo memory opInfo = opInfos[opIndex];
+ (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);
+ _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));
+ opIndex++;
+ }
+ }
+
+ uint256 collected = 0;
+ opIndex = 0;
+ for (uint256 a = 0; a < opasLen; a++) {
+ UserOpsPerAggregator calldata opa = opsPerAggregator[a];
+ emit SignatureAggregatorChanged(address(opa.aggregator));
+ UserOperation[] calldata ops = opa.userOps;
+ uint256 opslen = ops.length;
+
+ for (uint256 i = 0; i < opslen; i++) {
+ collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);
+ opIndex++;
+ }
+ }
+ emit SignatureAggregatorChanged(address(0));
+
+ _compensate(beneficiary, collected);
+ }
+
+ /// @inheritdoc IEntryPoint
+ function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {
+
+ UserOpInfo memory opInfo;
+ _simulationOnlyValidations(op);
+ (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);
+ ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);
+
+ numberMarker();
+ uint256 paid = _executeUserOp(0, op, opInfo);
+ numberMarker();
+ bool targetSuccess;
+ bytes memory targetResult;
+ if (target != address(0)) {
+ (targetSuccess, targetResult) = target.call(targetCallData);
+ }
+ revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);
+ }
+
+
+ // A memory copy of UserOp static fields only.
+ // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.
+ struct MemoryUserOp {
+ address sender;
+ uint256 nonce;
+ uint256 callGasLimit;
+ uint256 verificationGasLimit;
+ uint256 preVerificationGas;
+ address paymaster;
+ uint256 maxFeePerGas;
+ uint256 maxPriorityFeePerGas;
+ }
+
+ struct UserOpInfo {
+ MemoryUserOp mUserOp;
+ bytes32 userOpHash;
+ uint256 prefund;
+ uint256 contextOffset;
+ uint256 preOpGas;
+ }
+
+ /**
+ * inner function to handle a UserOperation.
+ * Must be declared "external" to open a call context, but it can only be called by handleOps.
+ */
+ function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {
+ uint256 preGas = gasleft();
+ require(msg.sender == address(this), "AA92 internal call only");
+ MemoryUserOp memory mUserOp = opInfo.mUserOp;
+
+ uint callGasLimit = mUserOp.callGasLimit;
+ unchecked {
+ // handleOps was called with gas limit too low. abort entire bundle.
+ if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {
+ assembly {
+ mstore(0, INNER_OUT_OF_GAS)
+ revert(0, 32)
+ }
+ }
+ }
+
+ IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;
+ if (callData.length > 0) {
+ bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);
+ if (!success) {
+ bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);
+ if (result.length > 0) {
+ emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);
+ }
+ mode = IPaymaster.PostOpMode.opReverted;
+ }
+ }
+
+ unchecked {
+ uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;
+ //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)
+ return _handlePostOp(0, mode, opInfo, context, actualGas);
+ }
+ }
+
+ /**
+ * generate a request Id - unique identifier for this request.
+ * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.
+ */
+ function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {
+ return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));
+ }
+
+ /**
+ * copy general fields from userOp into the memory opInfo structure.
+ */
+ function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {
+ mUserOp.sender = userOp.sender;
+ mUserOp.nonce = userOp.nonce;
+ mUserOp.callGasLimit = userOp.callGasLimit;
+ mUserOp.verificationGasLimit = userOp.verificationGasLimit;
+ mUserOp.preVerificationGas = userOp.preVerificationGas;
+ mUserOp.maxFeePerGas = userOp.maxFeePerGas;
+ mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;
+ bytes calldata paymasterAndData = userOp.paymasterAndData;
+ if (paymasterAndData.length > 0) {
+ require(paymasterAndData.length >= 20, "AA93 invalid paymasterAndData");
+ mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));
+ } else {
+ mUserOp.paymaster = address(0);
+ }
+ }
+
+ /**
+ * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.
+ * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.
+ * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.
+ * @param userOp the user operation to validate.
+ */
+ function simulateValidation(UserOperation calldata userOp) external {
+ UserOpInfo memory outOpInfo;
+
+ _simulationOnlyValidations(userOp);
+ (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);
+ StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);
+ StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);
+ StakeInfo memory factoryInfo;
+ {
+ bytes calldata initCode = userOp.initCode;
+ address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);
+ factoryInfo = _getStakeInfo(factory);
+ }
+
+ ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);
+ address aggregator = data.aggregator;
+ bool sigFailed = aggregator == address(1);
+ ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,
+ sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));
+
+ if (aggregator != address(0) && aggregator != address(1)) {
+ AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));
+ revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);
+ }
+ revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);
+
+ }
+
+ function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {
+ unchecked {
+ //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.
+ // our security model might call postOp eventually twice
+ uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;
+ uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;
+
+ requiredPrefund = requiredGas * mUserOp.maxFeePerGas;
+ }
+ }
+
+ // create the sender's contract if needed.
+ function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {
+ if (initCode.length != 0) {
+ address sender = opInfo.mUserOp.sender;
+ if (sender.code.length != 0) revert FailedOp(opIndex, "AA10 sender already constructed");
+ address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);
+ if (sender1 == address(0)) revert FailedOp(opIndex, "AA13 initCode failed or OOG");
+ if (sender1 != sender) revert FailedOp(opIndex, "AA14 initCode must return sender");
+ if (sender1.code.length == 0) revert FailedOp(opIndex, "AA15 initCode must create sender");
+ address factory = address(bytes20(initCode[0 : 20]));
+ emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);
+ }
+ }
+
+ /**
+ * Get counterfactual sender address.
+ * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.
+ * this method always revert, and returns the address in SenderAddressResult error
+ * @param initCode the constructor code to be passed into the UserOperation.
+ */
+ function getSenderAddress(bytes calldata initCode) public {
+ address sender = senderCreator.createSender(initCode);
+ revert SenderAddressResult(sender);
+ }
+
+ function _simulationOnlyValidations(UserOperation calldata userOp) internal view {
+ // solhint-disable-next-line no-empty-blocks
+ try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}
+ catch Error(string memory revertReason) {
+ if (bytes(revertReason).length != 0) {
+ revert FailedOp(0, revertReason);
+ }
+ }
+ }
+
+ /**
+ * Called only during simulation.
+ * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.
+ */
+ function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {
+ if (initCode.length == 0 && sender.code.length == 0) {
+ // it would revert anyway. but give a meaningful message
+ revert("AA20 account not deployed");
+ }
+ if (paymasterAndData.length >= 20) {
+ address paymaster = address(bytes20(paymasterAndData[0 : 20]));
+ if (paymaster.code.length == 0) {
+ // it would revert anyway. but give a meaningful message
+ revert("AA30 paymaster not deployed");
+ }
+ }
+ // always revert
+ revert("");
+ }
+
+ /**
+ * call account.validateUserOp.
+ * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.
+ * decrement account's deposit if needed
+ */
+ function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)
+ internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {
+ unchecked {
+ uint256 preGas = gasleft();
+ MemoryUserOp memory mUserOp = opInfo.mUserOp;
+ address sender = mUserOp.sender;
+ _createSenderIfNeeded(opIndex, opInfo, op.initCode);
+ address paymaster = mUserOp.paymaster;
+ numberMarker();
+ uint256 missingAccountFunds = 0;
+ if (paymaster == address(0)) {
+ uint256 bal = balanceOf(sender);
+ missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;
+ }
+ try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)
+ returns (uint256 _validationData) {
+ validationData = _validationData;
+ } catch Error(string memory revertReason) {
+ revert FailedOp(opIndex, string.concat("AA23 reverted: ", revertReason));
+ } catch {
+ revert FailedOp(opIndex, "AA23 reverted (or OOG)");
+ }
+ if (paymaster == address(0)) {
+ DepositInfo storage senderInfo = deposits[sender];
+ uint256 deposit = senderInfo.deposit;
+ if (requiredPrefund > deposit) {
+ revert FailedOp(opIndex, "AA21 didn't pay prefund");
+ }
+ senderInfo.deposit = uint112(deposit - requiredPrefund);
+ }
+ gasUsedByValidateAccountPrepayment = preGas - gasleft();
+ }
+ }
+
+ /**
+ * In case the request has a paymaster:
+ * Validate paymaster has enough deposit.
+ * Call paymaster.validatePaymasterUserOp.
+ * Revert with proper FailedOp in case paymaster reverts.
+ * Decrement paymaster's deposit
+ */
+ function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)
+ internal returns (bytes memory context, uint256 validationData) {
+ unchecked {
+ MemoryUserOp memory mUserOp = opInfo.mUserOp;
+ uint256 verificationGasLimit = mUserOp.verificationGasLimit;
+ require(verificationGasLimit > gasUsedByValidateAccountPrepayment, "AA41 too little verificationGas");
+ uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;
+
+ address paymaster = mUserOp.paymaster;
+ DepositInfo storage paymasterInfo = deposits[paymaster];
+ uint256 deposit = paymasterInfo.deposit;
+ if (deposit < requiredPreFund) {
+ revert FailedOp(opIndex, "AA31 paymaster deposit too low");
+ }
+ paymasterInfo.deposit = uint112(deposit - requiredPreFund);
+ try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){
+ context = _context;
+ validationData = _validationData;
+ } catch Error(string memory revertReason) {
+ revert FailedOp(opIndex, string.concat("AA33 reverted: ", revertReason));
+ } catch {
+ revert FailedOp(opIndex, "AA33 reverted (or OOG)");
+ }
+ }
+ }
+
+ /**
+ * revert if either account validationData or paymaster validationData is expired
+ */
+ function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {
+ (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);
+ if (expectedAggregator != aggregator) {
+ revert FailedOp(opIndex, "AA24 signature error");
+ }
+ if (outOfTimeRange) {
+ revert FailedOp(opIndex, "AA22 expired or not due");
+ }
+ //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.
+ // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)
+ address pmAggregator;
+ (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);
+ if (pmAggregator != address(0)) {
+ revert FailedOp(opIndex, "AA34 signature error");
+ }
+ if (outOfTimeRange) {
+ revert FailedOp(opIndex, "AA32 paymaster expired or not due");
+ }
+ }
+
+ function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {
+ if (validationData == 0) {
+ return (address(0), false);
+ }
+ ValidationData memory data = _parseValidationData(validationData);
+ // solhint-disable-next-line not-rely-on-time
+ outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;
+ aggregator = data.aggregator;
+ }
+
+ /**
+ * validate account and paymaster (if defined).
+ * also make sure total validation doesn't exceed verificationGasLimit
+ * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)
+ * @param opIndex the index of this userOp into the "opInfos" array
+ * @param userOp the userOp to validate
+ */
+ function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)
+ private returns (uint256 validationData, uint256 paymasterValidationData) {
+
+ uint256 preGas = gasleft();
+ MemoryUserOp memory mUserOp = outOpInfo.mUserOp;
+ _copyUserOpToMemory(userOp, mUserOp);
+ outOpInfo.userOpHash = getUserOpHash(userOp);
+
+ // validate all numeric values in userOp are well below 128 bit, so they can safely be added
+ // and multiplied without causing overflow
+ uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |
+ userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;
+ require(maxGasValues <= type(uint120).max, "AA94 gas values overflow");
+
+ uint256 gasUsedByValidateAccountPrepayment;
+ (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);
+ (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);
+
+ if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {
+ revert FailedOp(opIndex, "AA25 invalid account nonce");
+ }
+
+ //a "marker" where account opcode validation is done and paymaster opcode validation is about to start
+ // (used only by off-chain simulateValidation)
+ numberMarker();
+
+ bytes memory context;
+ if (mUserOp.paymaster != address(0)) {
+ (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);
+ }
+ unchecked {
+ uint256 gasUsed = preGas - gasleft();
+
+ if (userOp.verificationGasLimit < gasUsed) {
+ revert FailedOp(opIndex, "AA40 over verificationGasLimit");
+ }
+ outOpInfo.prefund = requiredPreFund;
+ outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);
+ outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;
+ }
+ }
+
+ /**
+ * process post-operation.
+ * called just after the callData is executed.
+ * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.
+ * the excess amount is refunded to the account (or paymaster - if it was used in the request)
+ * @param opIndex index in the batch
+ * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)
+ * @param opInfo userOp fields and info collected during validation
+ * @param context the context returned in validatePaymasterUserOp
+ * @param actualGas the gas used so far by this user operation
+ */
+ function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {
+ uint256 preGas = gasleft();
+ unchecked {
+ address refundAddress;
+ MemoryUserOp memory mUserOp = opInfo.mUserOp;
+ uint256 gasPrice = getUserOpGasPrice(mUserOp);
+
+ address paymaster = mUserOp.paymaster;
+ if (paymaster == address(0)) {
+ refundAddress = mUserOp.sender;
+ } else {
+ refundAddress = paymaster;
+ if (context.length > 0) {
+ actualGasCost = actualGas * gasPrice;
+ if (mode != IPaymaster.PostOpMode.postOpReverted) {
+ IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);
+ } else {
+ // solhint-disable-next-line no-empty-blocks
+ try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}
+ catch Error(string memory reason) {
+ revert FailedOp(opIndex, string.concat("AA50 postOp reverted: ", reason));
+ }
+ catch {
+ revert FailedOp(opIndex, "AA50 postOp revert");
+ }
+ }
+ }
+ }
+ actualGas += preGas - gasleft();
+ actualGasCost = actualGas * gasPrice;
+ if (opInfo.prefund < actualGasCost) {
+ revert FailedOp(opIndex, "AA51 prefund below actualGasCost");
+ }
+ uint256 refund = opInfo.prefund - actualGasCost;
+ _incrementDeposit(refundAddress, refund);
+ bool success = mode == IPaymaster.PostOpMode.opSucceeded;
+ emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);
+ } // unchecked
+ }
+
+ /**
+ * the gas price this UserOp agrees to pay.
+ * relayer/block builder might submit the TX with higher priorityFee, but the user should not
+ */
+ function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {
+ unchecked {
+ uint256 maxFeePerGas = mUserOp.maxFeePerGas;
+ uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;
+ if (maxFeePerGas == maxPriorityFeePerGas) {
+ //legacy mode (for networks that don't support basefee opcode)
+ return maxFeePerGas;
+ }
+ return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);
+ }
+ }
+
+ function min(uint256 a, uint256 b) internal pure returns (uint256) {
+ return a < b ? a : b;
+ }
+
+ function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {
+ assembly {offset := data}
+ }
+
+ function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {
+ assembly {data := offset}
+ }
+
+ //place the NUMBER opcode in the code.
+ // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the
+ // account and paymaster.
+ function numberMarker() internal view {
+ assembly {mstore(0, number())}
+ }
+}
+
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/core/Helpers.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/Helpers.sol
new file mode 100644
index 00000000..6767fd66
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/Helpers.sol
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+/* solhint-disable no-inline-assembly */
+
+/**
+ * returned data from validateUserOp.
+ * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`
+ * @param aggregator - address(0) - the account validated the signature by itself.
+ * address(1) - the account failed to validate the signature.
+ * otherwise - this is an address of a signature aggregator that must be used to validate the signature.
+ * @param validAfter - this UserOp is valid only after this timestamp.
+ * @param validaUntil - this UserOp is valid only up to this timestamp.
+ */
+ struct ValidationData {
+ address aggregator;
+ uint48 validAfter;
+ uint48 validUntil;
+ }
+
+//extract sigFailed, validAfter, validUntil.
+// also convert zero validUntil to type(uint48).max
+ function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {
+ address aggregator = address(uint160(validationData));
+ uint48 validUntil = uint48(validationData >> 160);
+ if (validUntil == 0) {
+ validUntil = type(uint48).max;
+ }
+ uint48 validAfter = uint48(validationData >> (48 + 160));
+ return ValidationData(aggregator, validAfter, validUntil);
+ }
+
+// intersect account and paymaster ranges.
+ function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {
+ ValidationData memory accountValidationData = _parseValidationData(validationData);
+ ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);
+ address aggregator = accountValidationData.aggregator;
+ if (aggregator == address(0)) {
+ aggregator = pmValidationData.aggregator;
+ }
+ uint48 validAfter = accountValidationData.validAfter;
+ uint48 validUntil = accountValidationData.validUntil;
+ uint48 pmValidAfter = pmValidationData.validAfter;
+ uint48 pmValidUntil = pmValidationData.validUntil;
+
+ if (validAfter < pmValidAfter) validAfter = pmValidAfter;
+ if (validUntil > pmValidUntil) validUntil = pmValidUntil;
+ return ValidationData(aggregator, validAfter, validUntil);
+ }
+
+/**
+ * helper to pack the return value for validateUserOp
+ * @param data - the ValidationData to pack
+ */
+ function _packValidationData(ValidationData memory data) pure returns (uint256) {
+ return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));
+ }
+
+/**
+ * helper to pack the return value for validateUserOp, when not using an aggregator
+ * @param sigFailed - true for signature failure, false for success
+ * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)
+ * @param validAfter first timestamp this UserOperation is valid
+ */
+ function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {
+ return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));
+ }
+
+/**
+ * keccak function over calldata.
+ * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.
+ */
+ function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {
+ assembly {
+ let mem := mload(0x40)
+ let len := data.length
+ calldatacopy(mem, data.offset, len)
+ ret := keccak256(mem, len)
+ }
+ }
+
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/core/NonceManager.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/NonceManager.sol
new file mode 100644
index 00000000..f0bc20db
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/NonceManager.sol
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "../interfaces/IEntryPoint.sol";
+
+/**
+ * nonce management functionality
+ */
+contract NonceManager is INonceManager {
+
+ /**
+ * The next valid sequence number for a given nonce key.
+ */
+ mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;
+
+ function getNonce(address sender, uint192 key)
+ public view override returns (uint256 nonce) {
+ return nonceSequenceNumber[sender][key] | (uint256(key) << 64);
+ }
+
+ // allow an account to manually increment its own nonce.
+ // (mainly so that during construction nonce can be made non-zero,
+ // to "absorb" the gas cost of first nonce increment to 1st transaction (construction),
+ // not to 2nd transaction)
+ function incrementNonce(uint192 key) public override {
+ nonceSequenceNumber[msg.sender][key]++;
+ }
+
+ /**
+ * validate nonce uniqueness for this account.
+ * called just after validateUserOp()
+ */
+ function _validateAndUpdateNonce(address sender, uint256 nonce) internal returns (bool) {
+
+ uint192 key = uint192(nonce >> 64);
+ uint64 seq = uint64(nonce);
+ return nonceSequenceNumber[sender][key]++ == seq;
+ }
+
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/core/SenderCreator.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/SenderCreator.sol
new file mode 100644
index 00000000..36fad7b9
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/SenderCreator.sol
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+/**
+ * helper contract for EntryPoint, to call userOp.initCode from a "neutral" address,
+ * which is explicitly not the entryPoint itself.
+ */
+contract SenderCreator {
+
+ /**
+ * call the "initCode" factory to create and return the sender account address
+ * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata
+ * @return sender the returned address of the created account, or zero address on failure.
+ */
+ function createSender(bytes calldata initCode) external returns (address sender) {
+ address factory = address(bytes20(initCode[0 : 20]));
+ bytes memory initCallData = initCode[20 :];
+ bool success;
+ /* solhint-disable no-inline-assembly */
+ assembly {
+ success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)
+ sender := mload(0)
+ }
+ if (!success) {
+ sender = address(0);
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/core/StakeManager.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/StakeManager.sol
new file mode 100644
index 00000000..e5ca2b97
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/core/StakeManager.sol
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-3.0-only
+pragma solidity ^0.8.12;
+
+import "../interfaces/IStakeManager.sol";
+
+/* solhint-disable avoid-low-level-calls */
+/* solhint-disable not-rely-on-time */
+/**
+ * manage deposits and stakes.
+ * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)
+ * stake is value locked for at least "unstakeDelay" by a paymaster.
+ */
+abstract contract StakeManager is IStakeManager {
+
+ /// maps paymaster to their deposits and stakes
+ mapping(address => DepositInfo) public deposits;
+
+ /// @inheritdoc IStakeManager
+ function getDepositInfo(address account) public view returns (DepositInfo memory info) {
+ return deposits[account];
+ }
+
+ // internal method to return just the stake info
+ function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {
+ DepositInfo storage depositInfo = deposits[addr];
+ info.stake = depositInfo.stake;
+ info.unstakeDelaySec = depositInfo.unstakeDelaySec;
+ }
+
+ /// return the deposit (for gas payment) of the account
+ function balanceOf(address account) public view returns (uint256) {
+ return deposits[account].deposit;
+ }
+
+ receive() external payable {
+ depositTo(msg.sender);
+ }
+
+ function _incrementDeposit(address account, uint256 amount) internal {
+ DepositInfo storage info = deposits[account];
+ uint256 newAmount = info.deposit + amount;
+ require(newAmount <= type(uint112).max, "deposit overflow");
+ info.deposit = uint112(newAmount);
+ }
+
+ /**
+ * add to the deposit of the given account
+ */
+ function depositTo(address account) public payable {
+ _incrementDeposit(account, msg.value);
+ DepositInfo storage info = deposits[account];
+ emit Deposited(account, info.deposit);
+ }
+
+ /**
+ * add to the account's stake - amount and delay
+ * any pending unstake is first cancelled.
+ * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.
+ */
+ function addStake(uint32 unstakeDelaySec) public payable {
+ DepositInfo storage info = deposits[msg.sender];
+ require(unstakeDelaySec > 0, "must specify unstake delay");
+ require(unstakeDelaySec >= info.unstakeDelaySec, "cannot decrease unstake time");
+ uint256 stake = info.stake + msg.value;
+ require(stake > 0, "no stake specified");
+ require(stake <= type(uint112).max, "stake overflow");
+ deposits[msg.sender] = DepositInfo(
+ info.deposit,
+ true,
+ uint112(stake),
+ unstakeDelaySec,
+ 0
+ );
+ emit StakeLocked(msg.sender, stake, unstakeDelaySec);
+ }
+
+ /**
+ * attempt to unlock the stake.
+ * the value can be withdrawn (using withdrawStake) after the unstake delay.
+ */
+ function unlockStake() external {
+ DepositInfo storage info = deposits[msg.sender];
+ require(info.unstakeDelaySec != 0, "not staked");
+ require(info.staked, "already unstaking");
+ uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;
+ info.withdrawTime = withdrawTime;
+ info.staked = false;
+ emit StakeUnlocked(msg.sender, withdrawTime);
+ }
+
+
+ /**
+ * withdraw from the (unlocked) stake.
+ * must first call unlockStake and wait for the unstakeDelay to pass
+ * @param withdrawAddress the address to send withdrawn value.
+ */
+ function withdrawStake(address payable withdrawAddress) external {
+ DepositInfo storage info = deposits[msg.sender];
+ uint256 stake = info.stake;
+ require(stake > 0, "No stake to withdraw");
+ require(info.withdrawTime > 0, "must call unlockStake() first");
+ require(info.withdrawTime <= block.timestamp, "Stake withdrawal is not due");
+ info.unstakeDelaySec = 0;
+ info.withdrawTime = 0;
+ info.stake = 0;
+ emit StakeWithdrawn(msg.sender, withdrawAddress, stake);
+ (bool success,) = withdrawAddress.call{value : stake}("");
+ require(success, "failed to withdraw stake");
+ }
+
+ /**
+ * withdraw from the deposit.
+ * @param withdrawAddress the address to send withdrawn value.
+ * @param withdrawAmount the amount to withdraw.
+ */
+ function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {
+ DepositInfo storage info = deposits[msg.sender];
+ require(withdrawAmount <= info.deposit, "Withdraw amount too large");
+ info.deposit = uint112(info.deposit - withdrawAmount);
+ emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);
+ (bool success,) = withdrawAddress.call{value : withdrawAmount}("");
+ require(success, "failed to withdraw");
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/index.ts b/lib/SoulWalletCore/lib/account-abstraction/contracts/index.ts
new file mode 100644
index 00000000..bf6cff8a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/index.ts
@@ -0,0 +1,2 @@
+export { UserOperationStruct } from './types/EntryPoint'
+export * from './types'
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IAccount.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IAccount.sol
new file mode 100644
index 00000000..1600de3d
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IAccount.sol
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "./UserOperation.sol";
+
+interface IAccount {
+
+ /**
+ * Validate user's signature and nonce
+ * the entryPoint will make the call to the recipient only if this validation call returns successfully.
+ * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).
+ * This allows making a "simulation call" without a valid signature
+ * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.
+ *
+ * @dev Must validate caller is the entryPoint.
+ * Must validate the signature and nonce
+ * @param userOp the operation that is about to be executed.
+ * @param userOpHash hash of the user's request data. can be used as the basis for signature.
+ * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.
+ * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.
+ * The excess is left as a deposit in the entrypoint, for future calls.
+ * can be withdrawn anytime using "entryPoint.withdrawTo()"
+ * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.
+ * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode
+ * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,
+ * otherwise, an address of an "authorizer" contract.
+ * <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite"
+ * <6-byte> validAfter - first timestamp this operation is valid
+ * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.
+ * Note that the validation code cannot use block.timestamp (or block.number) directly.
+ */
+ function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)
+ external returns (uint256 validationData);
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IAggregator.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IAggregator.sol
new file mode 100644
index 00000000..086c6f32
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IAggregator.sol
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "./UserOperation.sol";
+
+/**
+ * Aggregated Signatures validator.
+ */
+interface IAggregator {
+
+ /**
+ * validate aggregated signature.
+ * revert if the aggregated signature does not match the given list of operations.
+ */
+ function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;
+
+ /**
+ * validate signature of a single userOp
+ * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation
+ * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.
+ * @param userOp the userOperation received from the user.
+ * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.
+ * (usually empty, unless account and aggregator support some kind of "multisig"
+ */
+ function validateUserOpSignature(UserOperation calldata userOp)
+ external view returns (bytes memory sigForUserOp);
+
+ /**
+ * aggregate multiple signatures into a single value.
+ * This method is called off-chain to calculate the signature to pass with handleOps()
+ * bundler MAY use optimized custom code perform this aggregation
+ * @param userOps array of UserOperations to collect the signatures from.
+ * @return aggregatedSignature the aggregated signature
+ */
+ function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IEntryPoint.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IEntryPoint.sol
new file mode 100644
index 00000000..69ce75c8
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IEntryPoint.sol
@@ -0,0 +1,205 @@
+/**
+ ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.
+ ** Only one instance required on each chain.
+ **/
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+/* solhint-disable avoid-low-level-calls */
+/* solhint-disable no-inline-assembly */
+/* solhint-disable reason-string */
+
+import "./UserOperation.sol";
+import "./IStakeManager.sol";
+import "./IAggregator.sol";
+import "./INonceManager.sol";
+
+interface IEntryPoint is IStakeManager, INonceManager {
+
+ /***
+ * An event emitted after each successful request
+ * @param userOpHash - unique identifier for the request (hash its entire content, except signature).
+ * @param sender - the account that generates this request.
+ * @param paymaster - if non-null, the paymaster that pays for this request.
+ * @param nonce - the nonce value from the request.
+ * @param success - true if the sender transaction succeeded, false if reverted.
+ * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.
+ * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).
+ */
+ event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);
+
+ /**
+ * account "sender" was deployed.
+ * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.
+ * @param sender the account that is deployed
+ * @param factory the factory used to deploy this account (in the initCode)
+ * @param paymaster the paymaster used by this UserOp
+ */
+ event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);
+
+ /**
+ * An event emitted if the UserOperation "callData" reverted with non-zero length
+ * @param userOpHash the request unique identifier.
+ * @param sender the sender of this request
+ * @param nonce the nonce used in the request
+ * @param revertReason - the return bytes from the (reverted) call to "callData".
+ */
+ event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);
+
+ /**
+ * an event emitted by handleOps(), before starting the execution loop.
+ * any event emitted before this event, is part of the validation.
+ */
+ event BeforeExecution();
+
+ /**
+ * signature aggregator used by the following UserOperationEvents within this bundle.
+ */
+ event SignatureAggregatorChanged(address indexed aggregator);
+
+ /**
+ * a custom revert error of handleOps, to identify the offending op.
+ * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.
+ * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)
+ * @param reason - revert reason
+ * The string starts with a unique code "AAmn", where "m" is "1" for factory, "2" for account and "3" for paymaster issues,
+ * so a failure can be attributed to the correct entity.
+ * Should be caught in off-chain handleOps simulation and not happen on-chain.
+ * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.
+ */
+ error FailedOp(uint256 opIndex, string reason);
+
+ /**
+ * error case when a signature aggregator fails to verify the aggregated signature it had created.
+ */
+ error SignatureValidationFailed(address aggregator);
+
+ /**
+ * Successful result from simulateValidation.
+ * @param returnInfo gas and time-range returned values
+ * @param senderInfo stake information about the sender
+ * @param factoryInfo stake information about the factory (if any)
+ * @param paymasterInfo stake information about the paymaster (if any)
+ */
+ error ValidationResult(ReturnInfo returnInfo,
+ StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);
+
+ /**
+ * Successful result from simulateValidation, if the account returns a signature aggregator
+ * @param returnInfo gas and time-range returned values
+ * @param senderInfo stake information about the sender
+ * @param factoryInfo stake information about the factory (if any)
+ * @param paymasterInfo stake information about the paymaster (if any)
+ * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)
+ * bundler MUST use it to verify the signature, or reject the UserOperation
+ */
+ error ValidationResultWithAggregation(ReturnInfo returnInfo,
+ StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,
+ AggregatorStakeInfo aggregatorInfo);
+
+ /**
+ * return value of getSenderAddress
+ */
+ error SenderAddressResult(address sender);
+
+ /**
+ * return value of simulateHandleOp
+ */
+ error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);
+
+ //UserOps handled, per aggregator
+ struct UserOpsPerAggregator {
+ UserOperation[] userOps;
+
+ // aggregator address
+ IAggregator aggregator;
+ // aggregated signature
+ bytes signature;
+ }
+
+ /**
+ * Execute a batch of UserOperation.
+ * no signature aggregator is used.
+ * if any account requires an aggregator (that is, it returned an aggregator when
+ * performing simulateValidation), then handleAggregatedOps() must be used instead.
+ * @param ops the operations to execute
+ * @param beneficiary the address to receive the fees
+ */
+ function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;
+
+ /**
+ * Execute a batch of UserOperation with Aggregators
+ * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)
+ * @param beneficiary the address to receive the fees
+ */
+ function handleAggregatedOps(
+ UserOpsPerAggregator[] calldata opsPerAggregator,
+ address payable beneficiary
+ ) external;
+
+ /**
+ * generate a request Id - unique identifier for this request.
+ * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.
+ */
+ function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);
+
+ /**
+ * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.
+ * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.
+ * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.
+ * @param userOp the user operation to validate.
+ */
+ function simulateValidation(UserOperation calldata userOp) external;
+
+ /**
+ * gas and return values during simulation
+ * @param preOpGas the gas used for validation (including preValidationGas)
+ * @param prefund the required prefund for this operation
+ * @param sigFailed validateUserOp's (or paymaster's) signature check failed
+ * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)
+ * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)
+ * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)
+ */
+ struct ReturnInfo {
+ uint256 preOpGas;
+ uint256 prefund;
+ bool sigFailed;
+ uint48 validAfter;
+ uint48 validUntil;
+ bytes paymasterContext;
+ }
+
+ /**
+ * returned aggregated signature info.
+ * the aggregator returned by the account, and its current stake.
+ */
+ struct AggregatorStakeInfo {
+ address aggregator;
+ StakeInfo stakeInfo;
+ }
+
+ /**
+ * Get counterfactual sender address.
+ * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.
+ * this method always revert, and returns the address in SenderAddressResult error
+ * @param initCode the constructor code to be passed into the UserOperation.
+ */
+ function getSenderAddress(bytes memory initCode) external;
+
+
+ /**
+ * simulate full execution of a UserOperation (including both validation and target execution)
+ * this method will always revert with "ExecutionResult".
+ * it performs full validation of the UserOperation, but ignores signature error.
+ * an optional target address is called after the userop succeeds, and its value is returned
+ * (before the entire call is reverted)
+ * Note that in order to collect the the success/failure of the target call, it must be executed
+ * with trace enabled to track the emitted events.
+ * @param op the UserOperation to simulate
+ * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult
+ * are set to the return from that call.
+ * @param targetCallData callData to pass to target address
+ */
+ function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;
+}
+
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/INonceManager.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/INonceManager.sol
new file mode 100644
index 00000000..fe649130
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/INonceManager.sol
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+interface INonceManager {
+
+ /**
+ * Return the next nonce for this sender.
+ * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)
+ * But UserOp with different keys can come with arbitrary order.
+ *
+ * @param sender the account address
+ * @param key the high 192 bit of the nonce
+ * @return nonce a full nonce to pass for next UserOp with this sender.
+ */
+ function getNonce(address sender, uint192 key)
+ external view returns (uint256 nonce);
+
+ /**
+ * Manually increment the nonce of the sender.
+ * This method is exposed just for completeness..
+ * Account does NOT need to call it, neither during validation, nor elsewhere,
+ * as the EntryPoint will update the nonce regardless.
+ * Possible use-case is call it with various keys to "initialize" their nonces to one, so that future
+ * UserOperations will not pay extra for the first transaction with a given key.
+ */
+ function incrementNonce(uint192 key) external;
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IPaymaster.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IPaymaster.sol
new file mode 100644
index 00000000..af50367a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IPaymaster.sol
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "./UserOperation.sol";
+
+/**
+ * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.
+ * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.
+ */
+interface IPaymaster {
+
+ enum PostOpMode {
+ opSucceeded, // user op succeeded
+ opReverted, // user op reverted. still has to pay for gas.
+ postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.
+ }
+
+ /**
+ * payment validation: check if paymaster agrees to pay.
+ * Must verify sender is the entryPoint.
+ * Revert to reject this request.
+ * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)
+ * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.
+ * @param userOp the user operation
+ * @param userOpHash hash of the user's request data.
+ * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)
+ * @return context value to send to a postOp
+ * zero length to signify postOp is not required.
+ * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation
+ * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,
+ * otherwise, an address of an "authorizer" contract.
+ * <6-byte> validUntil - last timestamp this operation is valid. 0 for "indefinite"
+ * <6-byte> validAfter - first timestamp this operation is valid
+ * Note that the validation code cannot use block.timestamp (or block.number) directly.
+ */
+ function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
+ external returns (bytes memory context, uint256 validationData);
+
+ /**
+ * post-operation handler.
+ * Must verify sender is the entryPoint
+ * @param mode enum with the following options:
+ * opSucceeded - user operation succeeded.
+ * opReverted - user op reverted. still has to pay for gas.
+ * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.
+ * Now this is the 2nd call, after user's op was deliberately reverted.
+ * @param context - the context value returned by validatePaymasterUserOp
+ * @param actualGasCost - actual gas used so far (without this postOp call).
+ */
+ function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IStakeManager.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IStakeManager.sol
new file mode 100644
index 00000000..c19c1bab
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/IStakeManager.sol
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-3.0-only
+pragma solidity ^0.8.12;
+
+/**
+ * manage deposits and stakes.
+ * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)
+ * stake is value locked for at least "unstakeDelay" by the staked entity.
+ */
+interface IStakeManager {
+
+ event Deposited(
+ address indexed account,
+ uint256 totalDeposit
+ );
+
+ event Withdrawn(
+ address indexed account,
+ address withdrawAddress,
+ uint256 amount
+ );
+
+ /// Emitted when stake or unstake delay are modified
+ event StakeLocked(
+ address indexed account,
+ uint256 totalStaked,
+ uint256 unstakeDelaySec
+ );
+
+ /// Emitted once a stake is scheduled for withdrawal
+ event StakeUnlocked(
+ address indexed account,
+ uint256 withdrawTime
+ );
+
+ event StakeWithdrawn(
+ address indexed account,
+ address withdrawAddress,
+ uint256 amount
+ );
+
+ /**
+ * @param deposit the entity's deposit
+ * @param staked true if this entity is staked.
+ * @param stake actual amount of ether staked for this entity.
+ * @param unstakeDelaySec minimum delay to withdraw the stake.
+ * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked
+ * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)
+ * and the rest fit into a 2nd cell.
+ * 112 bit allows for 10^15 eth
+ * 48 bit for full timestamp
+ * 32 bit allows 150 years for unstake delay
+ */
+ struct DepositInfo {
+ uint112 deposit;
+ bool staked;
+ uint112 stake;
+ uint32 unstakeDelaySec;
+ uint48 withdrawTime;
+ }
+
+ //API struct used by getStakeInfo and simulateValidation
+ struct StakeInfo {
+ uint256 stake;
+ uint256 unstakeDelaySec;
+ }
+
+ /// @return info - full deposit information of given account
+ function getDepositInfo(address account) external view returns (DepositInfo memory info);
+
+ /// @return the deposit (for gas payment) of the account
+ function balanceOf(address account) external view returns (uint256);
+
+ /**
+ * add to the deposit of the given account
+ */
+ function depositTo(address account) external payable;
+
+ /**
+ * add to the account's stake - amount and delay
+ * any pending unstake is first cancelled.
+ * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.
+ */
+ function addStake(uint32 _unstakeDelaySec) external payable;
+
+ /**
+ * attempt to unlock the stake.
+ * the value can be withdrawn (using withdrawStake) after the unstake delay.
+ */
+ function unlockStake() external;
+
+ /**
+ * withdraw from the (unlocked) stake.
+ * must first call unlockStake and wait for the unstakeDelay to pass
+ * @param withdrawAddress the address to send withdrawn value.
+ */
+ function withdrawStake(address payable withdrawAddress) external;
+
+ /**
+ * withdraw from the deposit.
+ * @param withdrawAddress the address to send withdrawn value.
+ * @param withdrawAmount the amount to withdraw.
+ */
+ function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/UserOperation.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/UserOperation.sol
new file mode 100644
index 00000000..46ca75c6
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/interfaces/UserOperation.sol
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+/* solhint-disable no-inline-assembly */
+
+import {calldataKeccak} from "../core/Helpers.sol";
+
+/**
+ * User Operation struct
+ * @param sender the sender account of this request.
+ * @param nonce unique value the sender uses to verify it is not a replay.
+ * @param initCode if set, the account contract will be created by this constructor/
+ * @param callData the method call to execute on this account.
+ * @param callGasLimit the gas limit passed to the callData method call.
+ * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.
+ * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.
+ * @param maxFeePerGas same as EIP-1559 gas parameter.
+ * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.
+ * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.
+ * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.
+ */
+ struct UserOperation {
+
+ address sender;
+ uint256 nonce;
+ bytes initCode;
+ bytes callData;
+ uint256 callGasLimit;
+ uint256 verificationGasLimit;
+ uint256 preVerificationGas;
+ uint256 maxFeePerGas;
+ uint256 maxPriorityFeePerGas;
+ bytes paymasterAndData;
+ bytes signature;
+ }
+
+/**
+ * Utility functions helpful when working with UserOperation structs.
+ */
+library UserOperationLib {
+
+ function getSender(UserOperation calldata userOp) internal pure returns (address) {
+ address data;
+ //read sender from userOp, which is first userOp member (saves 800 gas...)
+ assembly {data := calldataload(userOp)}
+ return address(uint160(data));
+ }
+
+ //relayer/block builder might submit the TX with higher priorityFee, but the user should not
+ // pay above what he signed for.
+ function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {
+ unchecked {
+ uint256 maxFeePerGas = userOp.maxFeePerGas;
+ uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;
+ if (maxFeePerGas == maxPriorityFeePerGas) {
+ //legacy mode (for networks that don't support basefee opcode)
+ return maxFeePerGas;
+ }
+ return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);
+ }
+ }
+
+ function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {
+ address sender = getSender(userOp);
+ uint256 nonce = userOp.nonce;
+ bytes32 hashInitCode = calldataKeccak(userOp.initCode);
+ bytes32 hashCallData = calldataKeccak(userOp.callData);
+ uint256 callGasLimit = userOp.callGasLimit;
+ uint256 verificationGasLimit = userOp.verificationGasLimit;
+ uint256 preVerificationGas = userOp.preVerificationGas;
+ uint256 maxFeePerGas = userOp.maxFeePerGas;
+ uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;
+ bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);
+
+ return abi.encode(
+ sender, nonce,
+ hashInitCode, hashCallData,
+ callGasLimit, verificationGasLimit, preVerificationGas,
+ maxFeePerGas, maxPriorityFeePerGas,
+ hashPaymasterAndData
+ );
+ }
+
+ function hash(UserOperation calldata userOp) internal pure returns (bytes32) {
+ return keccak256(pack(userOp));
+ }
+
+ function min(uint256 a, uint256 b) internal pure returns (uint256) {
+ return a < b ? a : b;
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/package.json b/lib/SoulWalletCore/lib/account-abstraction/contracts/package.json
new file mode 100644
index 00000000..adc7a51c
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "@account-abstraction/contracts",
+ "description": "Account Abstraction (EIP 4337) contracts",
+ "version": "0.6.0",
+ "main": "./dist/index.js",
+ "scripts": {
+ "prepack": "../scripts/prepack-contracts-package.sh",
+ "postpack": "../scripts/postpack-contracts-package.sh"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/eth-infinitism/account-abstraction"
+ },
+ "keywords": [
+ "solidity",
+ "ethereum",
+ "smart",
+ "contracts",
+ "accipt-abstraction",
+ "eip-4337"
+ ],
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/eth-infinitism/account-abstraction/issues"
+ },
+ "devDependencies": {
+ "@gnosis.pm/safe-contracts": "^1.3.0",
+ "@nomiclabs/hardhat-ethers": "^2.0.2",
+ "@nomiclabs/hardhat-waffle": "^2.0.1"
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/DepositPaymaster.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/DepositPaymaster.sol
new file mode 100644
index 00000000..7ac92a36
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/DepositPaymaster.sol
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+/* solhint-disable reason-string */
+
+import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
+
+import "../core/BasePaymaster.sol";
+import "./IOracle.sol";
+
+/**
+ * A token-based paymaster that accepts token deposits
+ * The deposit is only a safeguard: the user pays with his token balance.
+ * only if the user didn't approve() the paymaster, or if the token balance is not enough, the deposit will be used.
+ * thus the required deposit is to cover just one method call.
+ * The deposit is locked for the current block: the user must issue unlockTokenDeposit() to be allowed to withdraw
+ * (but can't use the deposit for this or further operations)
+ *
+ * paymasterAndData holds the paymaster address followed by the token address to use.
+ * @notice This paymaster will be rejected by the standard rules of EIP4337, as it uses an external oracle.
+ * (the standard rules ban accessing data of an external contract)
+ * It can only be used if it is "whitelisted" by the bundler.
+ * (technically, it can be used by an "oracle" which returns a static value, without accessing any storage)
+ */
+contract DepositPaymaster is BasePaymaster {
+
+ using UserOperationLib for UserOperation;
+ using SafeERC20 for IERC20;
+
+ //calculated cost of the postOp
+ uint256 constant public COST_OF_POST = 35000;
+
+ IOracle private constant NULL_ORACLE = IOracle(address(0));
+ mapping(IERC20 => IOracle) public oracles;
+ mapping(IERC20 => mapping(address => uint256)) public balances;
+ mapping(address => uint256) public unlockBlock;
+
+ constructor(IEntryPoint _entryPoint) BasePaymaster(_entryPoint, msg.sender) {
+ //owner account is unblocked, to allow withdraw of paid tokens;
+ unlockTokenDeposit();
+ }
+
+ /**
+ * owner of the paymaster should add supported tokens
+ */
+ function addToken(IERC20 token, IOracle tokenPriceOracle) external onlyOwner {
+ require(oracles[token] == NULL_ORACLE, "Token already set");
+ oracles[token] = tokenPriceOracle;
+ }
+
+ /**
+ * deposit tokens that a specific account can use to pay for gas.
+ * The sender must first approve this paymaster to withdraw these tokens (they are only withdrawn in this method).
+ * Note depositing the tokens is equivalent to transferring them to the "account" - only the account can later
+ * use them - either as gas, or using withdrawTo()
+ *
+ * @param token the token to deposit.
+ * @param account the account to deposit for.
+ * @param amount the amount of token to deposit.
+ */
+ function addDepositFor(IERC20 token, address account, uint256 amount) external {
+ //(sender must have approval for the paymaster)
+ token.safeTransferFrom(msg.sender, address(this), amount);
+ require(oracles[token] != NULL_ORACLE, "unsupported token");
+ balances[token][account] += amount;
+ if (msg.sender == account) {
+ lockTokenDeposit();
+ }
+ }
+
+ /**
+ * @return amount - the amount of given token deposited to the Paymaster.
+ * @return _unlockBlock - the block height at which the deposit can be withdrawn.
+ */
+ function depositInfo(IERC20 token, address account) public view returns (uint256 amount, uint256 _unlockBlock) {
+ amount = balances[token][account];
+ _unlockBlock = unlockBlock[account];
+ }
+
+ /**
+ * unlock deposit, so that it can be withdrawn.
+ * can't be called in the same block as withdrawTo()
+ */
+ function unlockTokenDeposit() public {
+ unlockBlock[msg.sender] = block.number;
+ }
+
+ /**
+ * lock the tokens deposited for this account so they can be used to pay for gas.
+ * after calling unlockTokenDeposit(), the account can't use this paymaster until the deposit is locked.
+ */
+ function lockTokenDeposit() public {
+ unlockBlock[msg.sender] = 0;
+ }
+
+ /**
+ * withdraw tokens.
+ * can only be called after unlock() is called in a previous block.
+ * @param token the token deposit to withdraw
+ * @param target address to send to
+ * @param amount amount to withdraw
+ */
+ function withdrawTokensTo(IERC20 token, address target, uint256 amount) public {
+ require(unlockBlock[msg.sender] != 0 && block.number > unlockBlock[msg.sender], "DepositPaymaster: must unlockTokenDeposit");
+ balances[token][msg.sender] -= amount;
+ token.safeTransfer(target, amount);
+ }
+
+ /**
+ * translate the given eth value to token amount
+ * @param token the token to use
+ * @param ethBought the required eth value we want to "buy"
+ * @return requiredTokens the amount of tokens required to get this amount of eth
+ */
+ function getTokenValueOfEth(IERC20 token, uint256 ethBought) internal view virtual returns (uint256 requiredTokens) {
+ IOracle oracle = oracles[token];
+ require(oracle != NULL_ORACLE, "DepositPaymaster: unsupported token");
+ return oracle.getTokenValueOfEth(ethBought);
+ }
+
+ /**
+ * Validate the request:
+ * The sender should have enough deposit to pay the max possible cost.
+ * Note that the sender's balance is not checked. If it fails to pay from its balance,
+ * this deposit will be used to compensate the paymaster for the transaction.
+ */
+ function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
+ internal view override returns (bytes memory context, uint256 validationData) {
+
+ (userOpHash);
+ // verificationGasLimit is dual-purposed, as gas limit for postOp. make sure it is high enough
+ require(userOp.verificationGasLimit > COST_OF_POST, "DepositPaymaster: gas too low for postOp");
+
+ bytes calldata paymasterAndData = userOp.paymasterAndData;
+ require(paymasterAndData.length == 20+20, "DepositPaymaster: paymasterAndData must specify token");
+ IERC20 token = IERC20(address(bytes20(paymasterAndData[20:])));
+ address account = userOp.getSender();
+ uint256 maxTokenCost = getTokenValueOfEth(token, maxCost);
+ uint256 gasPriceUserOp = userOp.gasPrice();
+ require(unlockBlock[account] == 0, "DepositPaymaster: deposit not locked");
+ require(balances[token][account] >= maxTokenCost, "DepositPaymaster: deposit too low");
+ return (abi.encode(account, token, gasPriceUserOp, maxTokenCost, maxCost),0);
+ }
+
+ /**
+ * perform the post-operation to charge the sender for the gas.
+ * in normal mode, use transferFrom to withdraw enough tokens from the sender's balance.
+ * in case the transferFrom fails, the _postOp reverts and the entryPoint will call it again,
+ * this time in *postOpReverted* mode.
+ * In this mode, we use the deposit to pay (which we validated to be large enough)
+ */
+ function _postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) internal override {
+
+ (address account, IERC20 token, uint256 gasPricePostOp, uint256 maxTokenCost, uint256 maxCost) = abi.decode(context, (address, IERC20, uint256, uint256, uint256));
+ //use same conversion rate as used for validation.
+ uint256 actualTokenCost = (actualGasCost + COST_OF_POST * gasPricePostOp) * maxTokenCost / maxCost;
+ if (mode != PostOpMode.postOpReverted) {
+ // attempt to pay with tokens:
+ token.safeTransferFrom(account, address(this), actualTokenCost);
+ } else {
+ //in case above transferFrom failed, pay with deposit:
+ balances[token][account] -= actualTokenCost;
+ }
+ balances[token][owner()] += actualTokenCost;
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/IOracle.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/IOracle.sol
new file mode 100644
index 00000000..06fdf2a5
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/IOracle.sol
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+interface IOracle {
+
+ /**
+ * return amount of tokens that are required to receive that much eth.
+ */
+ function getTokenValueOfEth(uint256 ethOutput) external view returns (uint256 tokenInput);
+}
+
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/SimpleAccount.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/SimpleAccount.sol
new file mode 100644
index 00000000..c24ab671
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/SimpleAccount.sol
@@ -0,0 +1,140 @@
+// 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 "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
+import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
+import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
+import "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
+
+import "../core/BaseAccount.sol";
+import "./callback/TokenCallbackHandler.sol";
+
+/**
+ * minimal account.
+ * this is sample minimal account.
+ * has execute, eth handling methods
+ * has a single signer that can send requests through the entryPoint.
+ */
+contract SimpleAccount is BaseAccount, TokenCallbackHandler, UUPSUpgradeable, Initializable {
+ using ECDSA for bytes32;
+ using MessageHashUtils for bytes32;
+
+ address public owner;
+
+ IEntryPoint private immutable _entryPoint;
+
+ event SimpleAccountInitialized(IEntryPoint indexed entryPoint, address indexed owner);
+
+ modifier onlyOwner() {
+ _onlyOwner();
+ _;
+ }
+
+ /// @inheritdoc BaseAccount
+ function entryPoint() public view virtual override returns (IEntryPoint) {
+ return _entryPoint;
+ }
+
+
+ // solhint-disable-next-line no-empty-blocks
+ receive() external payable {}
+
+ constructor(IEntryPoint anEntryPoint) {
+ _entryPoint = anEntryPoint;
+ _disableInitializers();
+ }
+
+ function _onlyOwner() internal view {
+ //directly from EOA owner, or through the account itself (which gets redirected through execute())
+ require(msg.sender == owner || msg.sender == address(this), "only owner");
+ }
+
+ /**
+ * execute a transaction (called directly from owner, or by entryPoint)
+ */
+ function execute(address dest, uint256 value, bytes calldata func) external {
+ _requireFromEntryPointOrOwner();
+ _call(dest, value, func);
+ }
+
+ /**
+ * execute a sequence of transactions
+ */
+ function executeBatch(address[] calldata dest, bytes[] calldata func) external {
+ _requireFromEntryPointOrOwner();
+ require(dest.length == func.length, "wrong array lengths");
+ for (uint256 i = 0; i < dest.length; i++) {
+ _call(dest[i], 0, func[i]);
+ }
+ }
+
+ /**
+ * @dev The _entryPoint member is immutable, to reduce gas consumption. To upgrade EntryPoint,
+ * a new implementation of SimpleAccount must be deployed with the new EntryPoint address, then upgrading
+ * the implementation by calling `upgradeTo()`
+ */
+ function initialize(address anOwner) public virtual initializer {
+ _initialize(anOwner);
+ }
+
+ function _initialize(address anOwner) internal virtual {
+ owner = anOwner;
+ emit SimpleAccountInitialized(_entryPoint, owner);
+ }
+
+ // Require the function call went through EntryPoint or owner
+ function _requireFromEntryPointOrOwner() internal view {
+ require(msg.sender == address(entryPoint()) || msg.sender == owner, "account: not Owner or EntryPoint");
+ }
+
+ /// implement template method of BaseAccount
+ function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)
+ internal override virtual returns (uint256 validationData) {
+ bytes32 hash = userOpHash.toEthSignedMessageHash();
+ if (owner != hash.recover(userOp.signature))
+ return SIG_VALIDATION_FAILED;
+ return 0;
+ }
+
+ function _call(address target, uint256 value, bytes memory data) internal {
+ (bool success, bytes memory result) = target.call{value : value}(data);
+ if (!success) {
+ assembly {
+ revert(add(result, 32), mload(result))
+ }
+ }
+ }
+
+ /**
+ * check current account deposit in the entryPoint
+ */
+ function getDeposit() public view returns (uint256) {
+ return entryPoint().balanceOf(address(this));
+ }
+
+ /**
+ * deposit more funds for this account in the entryPoint
+ */
+ function addDeposit() public payable {
+ entryPoint().depositTo{value : msg.value}(address(this));
+ }
+
+ /**
+ * withdraw value from the account's deposit
+ * @param withdrawAddress target to send to
+ * @param amount to withdraw
+ */
+ function withdrawDepositTo(address payable withdrawAddress, uint256 amount) public onlyOwner {
+ entryPoint().withdrawTo(withdrawAddress, amount);
+ }
+
+ function _authorizeUpgrade(address newImplementation) internal view override {
+ (newImplementation);
+ _onlyOwner();
+ }
+}
+
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/SimpleAccountFactory.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/SimpleAccountFactory.sol
new file mode 100644
index 00000000..25f37f15
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/SimpleAccountFactory.sol
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "@openzeppelin/contracts/utils/Create2.sol";
+import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
+
+import "./SimpleAccount.sol";
+
+/**
+ * A sample factory contract for SimpleAccount
+ * A UserOperations "initCode" holds the address of the factory, and a method call (to createAccount, in this sample factory).
+ * The factory's createAccount returns the target account address even if it is already installed.
+ * This way, the entryPoint.getSenderAddress() can be called either before or after the account is created.
+ */
+contract SimpleAccountFactory {
+ SimpleAccount public immutable accountImplementation;
+
+ constructor(IEntryPoint _entryPoint) {
+ accountImplementation = new SimpleAccount(_entryPoint);
+ }
+
+ /**
+ * create an account, and return its address.
+ * returns the address even if the account is already deployed.
+ * Note that during UserOperation execution, this method is called only if the account is not deployed.
+ * This method returns an existing account address so that entryPoint.getSenderAddress() would work even after account creation
+ */
+ function createAccount(address owner,uint256 salt) public returns (SimpleAccount ret) {
+ address addr = getAddress(owner, salt);
+ uint codeSize = addr.code.length;
+ if (codeSize > 0) {
+ return SimpleAccount(payable(addr));
+ }
+ ret = SimpleAccount(payable(new ERC1967Proxy{salt : bytes32(salt)}(
+ address(accountImplementation),
+ abi.encodeCall(SimpleAccount.initialize, (owner))
+ )));
+ }
+
+ /**
+ * calculate the counterfactual address of this account as it would be returned by createAccount()
+ */
+ function getAddress(address owner,uint256 salt) public view returns (address) {
+ return Create2.computeAddress(bytes32(salt), keccak256(abi.encodePacked(
+ type(ERC1967Proxy).creationCode,
+ abi.encode(
+ address(accountImplementation),
+ abi.encodeCall(SimpleAccount.initialize, (owner))
+ )
+ )));
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/TokenPaymaster.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/TokenPaymaster.sol
new file mode 100644
index 00000000..703bff26
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/TokenPaymaster.sol
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+/* solhint-disable reason-string */
+
+import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
+import "../core/BasePaymaster.sol";
+
+/**
+ * A sample paymaster that defines itself as a token to pay for gas.
+ * The paymaster IS the token to use, since a paymaster cannot use an external contract.
+ * Also, the exchange rate has to be fixed, since it can't reference an external Uniswap or other exchange contract.
+ * subclass should override "getTokenValueOfEth" to provide actual token exchange rate, settable by the owner.
+ * Known Limitation: this paymaster is exploitable when put into a batch with multiple ops (of different accounts):
+ * - while a single op can't exploit the paymaster (if postOp fails to withdraw the tokens, the user's op is reverted,
+ * and then we know we can withdraw the tokens), multiple ops with different senders (all using this paymaster)
+ * in a batch can withdraw funds from 2nd and further ops, forcing the paymaster itself to pay (from its deposit)
+ * - Possible workarounds are either use a more complex paymaster scheme (e.g. the DepositPaymaster) or
+ * to whitelist the account and the called method ids.
+ */
+contract TokenPaymaster is BasePaymaster, ERC20 {
+
+ //calculated cost of the postOp
+ uint256 constant public COST_OF_POST = 15000;
+
+ address public immutable theFactory;
+
+ constructor(address accountFactory, string memory _symbol, IEntryPoint _entryPoint) ERC20(_symbol, _symbol) BasePaymaster(_entryPoint,msg.sender) {
+ theFactory = accountFactory;
+ //make it non-empty
+ _mint(address(this), 1);
+
+ //owner is allowed to withdraw tokens from the paymaster's balance
+ _approve(address(this), msg.sender, type(uint).max);
+ }
+
+
+ /**
+ * helpers for owner, to mint and withdraw tokens.
+ * @param recipient - the address that will receive the minted tokens.
+ * @param amount - the amount it will receive.
+ */
+ function mintTokens(address recipient, uint256 amount) external onlyOwner {
+ _mint(recipient, amount);
+ }
+
+ /**
+ * transfer paymaster ownership.
+ * owner of this paymaster is allowed to withdraw funds (tokens transferred to this paymaster's balance)
+ * when changing owner, the old owner's withdrawal rights are revoked.
+ */
+ function transferOwnership(address newOwner) public override virtual onlyOwner {
+ // remove allowance of current owner
+ _approve(address(this), owner(), 0);
+ super.transferOwnership(newOwner);
+ // new owner is allowed to withdraw tokens from the paymaster's balance
+ _approve(address(this), newOwner, type(uint).max);
+ }
+
+ //Note: this method assumes a fixed ratio of token-to-eth. subclass should override to supply oracle
+ // or a setter.
+ function getTokenValueOfEth(uint256 valueEth) internal view virtual returns (uint256 valueToken) {
+ return valueEth / 100;
+ }
+
+ /**
+ * validate the request:
+ * if this is a constructor call, make sure it is a known account.
+ * verify the sender has enough tokens.
+ * (since the paymaster is also the token, there is no notion of "approval")
+ */
+ function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 /*userOpHash*/, uint256 requiredPreFund)
+ internal view override returns (bytes memory context, uint256 validationData) {
+ uint256 tokenPrefund = getTokenValueOfEth(requiredPreFund);
+
+ // verificationGasLimit is dual-purposed, as gas limit for postOp. make sure it is high enough
+ // make sure that verificationGasLimit is high enough to handle postOp
+ require(userOp.verificationGasLimit > COST_OF_POST, "TokenPaymaster: gas too low for postOp");
+
+ if (userOp.initCode.length != 0) {
+ _validateConstructor(userOp);
+ require(balanceOf(userOp.sender) >= tokenPrefund, "TokenPaymaster: no balance (pre-create)");
+ } else {
+
+ require(balanceOf(userOp.sender) >= tokenPrefund, "TokenPaymaster: no balance");
+ }
+
+ return (abi.encode(userOp.sender), 0);
+ }
+
+ // when constructing an account, validate constructor code and parameters
+ // we trust our factory (and that it doesn't have any other public methods)
+ function _validateConstructor(UserOperation calldata userOp) internal virtual view {
+ address factory = address(bytes20(userOp.initCode[0 : 20]));
+ require(factory == theFactory, "TokenPaymaster: wrong account factory");
+ }
+
+ /**
+ * actual charge of user.
+ * this method will be called just after the user's TX with mode==OpSucceeded|OpReverted (account pays in both cases)
+ * BUT: if the user changed its balance in a way that will cause postOp to revert, then it gets called again, after reverting
+ * the user's TX , back to the state it was before the transaction started (before the validatePaymasterUserOp),
+ * and the transaction should succeed there.
+ */
+ function _postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) internal override {
+ //we don't really care about the mode, we just pay the gas with the user's tokens.
+ (mode);
+ address sender = abi.decode(context, (address));
+ uint256 charge = getTokenValueOfEth(actualGasCost + COST_OF_POST);
+ //actualGasCost is known to be no larger than the above requiredPreFund, so the transfer should succeed.
+ _transfer(sender, address(this), charge);
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/VerifyingPaymaster.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/VerifyingPaymaster.sol
new file mode 100644
index 00000000..0c13efdf
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/VerifyingPaymaster.sol
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+/* solhint-disable reason-string */
+/* solhint-disable no-inline-assembly */
+
+import "../core/BasePaymaster.sol";
+import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
+import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
+/**
+ * A sample paymaster that uses external service to decide whether to pay for the UserOp.
+ * The paymaster trusts an external signer to sign the transaction.
+ * The calling user must pass the UserOp to that external signer first, which performs
+ * whatever off-chain verification before signing the UserOp.
+ * Note that this signature is NOT a replacement for the account-specific signature:
+ * - the paymaster checks a signature to agree to PAY for GAS.
+ * - the account checks a signature to prove identity and account ownership.
+ */
+contract VerifyingPaymaster is BasePaymaster {
+
+ using ECDSA for bytes32;
+ using UserOperationLib for UserOperation;
+
+ address public immutable verifyingSigner;
+
+ uint256 private constant VALID_TIMESTAMP_OFFSET = 20;
+
+ uint256 private constant SIGNATURE_OFFSET = 84;
+
+ constructor(IEntryPoint _entryPoint, address _verifyingSigner) BasePaymaster(_entryPoint, msg.sender) {
+ verifyingSigner = _verifyingSigner;
+ }
+
+ mapping(address => uint256) public senderNonce;
+
+ function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {
+ // lighter signature scheme. must match UserOp.ts#packUserOp
+ bytes calldata pnd = userOp.paymasterAndData;
+ // copy directly the userOp from calldata up to (but not including) the paymasterAndData.
+ // 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(pnd.offset, ofs), 32)
+ ret := mload(0x40)
+ mstore(0x40, add(ret, add(len, 32)))
+ mstore(ret, len)
+ calldatacopy(add(ret, 32), ofs, len)
+ }
+ }
+
+ /**
+ * return the hash we're going to sign off-chain (and validate on-chain)
+ * this method is called by the off-chain service, to sign the request.
+ * it is called on-chain from the validatePaymasterUserOp, to validate the signature.
+ * note that this signature covers all fields of the UserOperation, except the "paymasterAndData",
+ * which will carry the signature itself.
+ */
+ function getHash(UserOperation calldata userOp, uint48 validUntil, uint48 validAfter)
+ public view returns (bytes32) {
+ //can't use userOp.hash(), since it contains also the paymasterAndData itself.
+
+ return keccak256(abi.encode(
+ pack(userOp),
+ block.chainid,
+ address(this),
+ senderNonce[userOp.getSender()],
+ validUntil,
+ validAfter
+ ));
+ }
+
+ /**
+ * verify our external signer signed this request.
+ * the "paymasterAndData" is expected to be the paymaster and a signature over the entire request params
+ * paymasterAndData[:20] : address(this)
+ * paymasterAndData[20:84] : abi.encode(validUntil, validAfter)
+ * paymasterAndData[84:] : signature
+ */
+ function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 /*userOpHash*/, uint256 requiredPreFund)
+ internal override returns (bytes memory context, uint256 validationData) {
+ (requiredPreFund);
+
+ (uint48 validUntil, uint48 validAfter, bytes calldata signature) = parsePaymasterAndData(userOp.paymasterAndData);
+ //ECDSA library supports both 64 and 65-byte long signatures.
+ // we only "require" it here so that the revert reason on invalid signature will be of "VerifyingPaymaster", and not "ECDSA"
+ require(signature.length == 64 || signature.length == 65, "VerifyingPaymaster: invalid signature length in paymasterAndData");
+ bytes32 hash = MessageHashUtils.toEthSignedMessageHash(getHash(userOp, validUntil, validAfter));
+ senderNonce[userOp.getSender()]++;
+
+ //don't revert on signature failure: return SIG_VALIDATION_FAILED
+ if (verifyingSigner != ECDSA.recover(hash, signature)) {
+ return ("",_packValidationData(true,validUntil,validAfter));
+ }
+
+ //no need for other on-chain validation: entire UserOp should have been checked
+ // by the external service prior to signing it.
+ return ("",_packValidationData(false,validUntil,validAfter));
+ }
+
+ function parsePaymasterAndData(bytes calldata paymasterAndData) public pure returns(uint48 validUntil, uint48 validAfter, bytes calldata signature) {
+ (validUntil, validAfter) = abi.decode(paymasterAndData[VALID_TIMESTAMP_OFFSET:SIGNATURE_OFFSET],(uint48, uint48));
+ signature = paymasterAndData[SIGNATURE_OFFSET:];
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSAccount.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSAccount.sol
new file mode 100644
index 00000000..efc64ce1
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSAccount.sol
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "../SimpleAccount.sol";
+import "./IBLSAccount.sol";
+
+/**
+ * Minimal BLS-based account that uses an aggregated signature.
+ * The account must maintain its own BLS public key, and expose its trusted signature aggregator.
+ * Note that unlike the "standard" SimpleAccount, this account can't be called directly
+ * (normal SimpleAccount uses its "signer" address as both the ecrecover signer, and as a legitimate
+ * Ethereum sender address. Obviously, a BLS public key is not a valid Ethereum sender address.)
+ */
+contract BLSAccount is SimpleAccount, IBLSAccount {
+ address public immutable aggregator;
+ uint256[4] private publicKey;
+
+ // The constructor is used only for the "implementation" and only sets immutable values.
+ // Mutable value slots for proxy accounts are set by the 'initialize' function.
+ constructor(IEntryPoint anEntryPoint, address anAggregator) SimpleAccount(anEntryPoint) {
+ aggregator = anAggregator;
+ }
+
+ /**
+ * The initializer for the BLSAccount instance.
+ * @param aPublicKey public key from a BLS keypair that will have a full ownership and control of this account.
+ */
+ function initialize(uint256[4] memory aPublicKey) public virtual initializer {
+ super._initialize(address(0));
+ _setBlsPublicKey(aPublicKey);
+ }
+
+ function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)
+ internal override view returns (uint256 validationData) {
+
+ (userOp, userOpHash);
+ if (userOp.initCode.length != 0) {
+ // BLSSignatureAggregator.getUserOpPublicKey() assumes that during account creation, the public key is
+ // the suffix of the initCode.
+ // The account MUST validate it
+ bytes32 pubKeyHash = keccak256(abi.encode(getBlsPublicKey()));
+ require(keccak256(userOp.initCode[userOp.initCode.length - 128 :]) == pubKeyHash, "wrong pubkey");
+ }
+ return _packValidationData(ValidationData(aggregator, 0,0));
+ }
+
+ /**
+ * Allows the owner to set or change the BLS key.
+ * @param newPublicKey public key from a BLS keypair that will have a full ownership and control of this account.
+ */
+ function setBlsPublicKey(uint256[4] memory newPublicKey) public onlyOwner {
+ _setBlsPublicKey(newPublicKey);
+ }
+
+ function _setBlsPublicKey(uint256[4] memory newPublicKey) internal {
+ emit PublicKeyChanged(publicKey, newPublicKey);
+ publicKey = newPublicKey;
+ }
+
+ /// @inheritdoc IBLSAccount
+ function getBlsPublicKey() public override view returns (uint256[4] memory) {
+ return publicKey;
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSAccountFactory.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSAccountFactory.sol
new file mode 100644
index 00000000..4096a383
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSAccountFactory.sol
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "@openzeppelin/contracts/utils/Create2.sol";
+import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
+
+import "../../interfaces/IEntryPoint.sol";
+import "./BLSAccount.sol";
+
+/* solhint-disable no-inline-assembly */
+
+/**
+ * Based on SimpleAccountFactory.
+ * Cannot be a subclass since both constructor and createAccount depend on the
+ * constructor and initializer of the actual account contract.
+ */
+contract BLSAccountFactory {
+ BLSAccount public immutable accountImplementation;
+
+ constructor(IEntryPoint entryPoint, address aggregator){
+ accountImplementation = new BLSAccount(entryPoint, aggregator);
+ }
+
+ /**
+ * create an account, and return its address.
+ * returns the address even if the account is already deployed.
+ * Note that during UserOperation execution, this method is called only if the account is not deployed.
+ * This method returns an existing account address so that entryPoint.getSenderAddress() would work even after account creation
+ * Also note that our BLSSignatureAggregator requires that the public key is the last parameter
+ */
+ function createAccount(uint256 salt, uint256[4] calldata aPublicKey) public returns (BLSAccount) {
+
+ // the BLSSignatureAggregator depends on the public-key being the last 4 uint256 of msg.data.
+ uint slot;
+ assembly {slot := aPublicKey}
+ require(slot == msg.data.length - 128, "wrong pubkey offset");
+
+ address addr = getAddress(salt, aPublicKey);
+ uint codeSize = addr.code.length;
+ if (codeSize > 0) {
+ return BLSAccount(payable(addr));
+ }
+ return BLSAccount(payable(new ERC1967Proxy{salt : bytes32(salt)}(
+ address(accountImplementation),
+ abi.encodeCall(BLSAccount.initialize, aPublicKey)
+ )));
+ }
+
+ /**
+ * calculate the counterfactual address of this account as it would be returned by createAccount()
+ */
+ function getAddress(uint256 salt, uint256[4] memory aPublicKey) public view returns (address) {
+ return Create2.computeAddress(bytes32(salt), keccak256(abi.encodePacked(
+ type(ERC1967Proxy).creationCode,
+ abi.encode(
+ address(accountImplementation),
+ abi.encodeCall(BLSAccount.initialize, (aPublicKey))
+ )
+ )));
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSHelper.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSHelper.sol
new file mode 100644
index 00000000..fdb60e0f
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSHelper.sol
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+// code taken from : https://github.com/witnet/elliptic-curve-solidity/blob/master/contracts/EllipticCurve.sol
+// missing core functions from "thehubbleproject/bls": jacAdd (and sum)
+library BLSHelper {
+
+ struct XY {
+ uint x;
+ uint y;
+ }
+ /**
+ * sum all the points in the array
+ * NOTE: the "ecAdd" (below) has a special case where x1==y2.
+ * @param points an array of bytes32[2], representing an (x,y) of a point
+ * @param _pp the modulus of the curve
+ * @return ret the sum of all points
+ */
+ function sum(XY[] memory points, uint256 _pp) internal pure returns (XY memory ret){
+ uint x = points[0].x;
+ uint y = points[0].y;
+ uint z = 1;
+
+ for (uint i = 1; i < points.length; i++) {
+ (x, y, z) = jacAdd(x, y, z, points[i].x, points[i].y, 1, _pp);
+ }
+ (x, y) = toAffine(x, y, z, _pp);
+ ret.x = x;
+ ret.y = y;
+ }
+
+ /// @dev Adds two points (x1, y1, z1) and (x2, y2, z2).
+ /// @param _x1 coordinate x of P1
+ /// @param _y1 coordinate y of P1
+ /// @param _z1 coordinate z of P1
+ /// @param _x2 coordinate x of square
+ /// @param _y2 coordinate y of square
+ /// @param _z2 coordinate z of square
+ /// @param _pp the modulus
+ /// @return (qx, qy, qz) P1+square in Jacobian
+ function jacAdd(
+ uint256 _x1,
+ uint256 _y1,
+ uint256 _z1,
+ uint256 _x2,
+ uint256 _y2,
+ uint256 _z2,
+ uint256 _pp)
+ internal pure returns (uint256, uint256, uint256)
+ {
+ if (_x1 == 0 && _y1 == 0)
+ return (_x2, _y2, _z2);
+ if (_x2 == 0 && _y2 == 0)
+ return (_x1, _y1, _z1);
+
+ // We follow the equations described in https://pdfs.semanticscholar.org/5c64/29952e08025a9649c2b0ba32518e9a7fb5c2.pdf Section 5
+ uint[4] memory zs;
+ // z1^2, z1^3, z2^2, z2^3
+ zs[0] = mulmod(_z1, _z1, _pp);
+ zs[1] = mulmod(_z1, zs[0], _pp);
+ zs[2] = mulmod(_z2, _z2, _pp);
+ zs[3] = mulmod(_z2, zs[2], _pp);
+
+ // u1, s1, u2, s2
+ zs = [
+ mulmod(_x1, zs[2], _pp),
+ mulmod(_y1, zs[3], _pp),
+ mulmod(_x2, zs[0], _pp),
+ mulmod(_y2, zs[1], _pp)
+ ];
+
+ // In case of zs[0] == zs[2] && zs[1] == zs[3], double function should be used
+ require(zs[0] != zs[2] || zs[1] != zs[3], "Use jacDouble function instead");
+
+ uint[4] memory hr;
+ //h
+ hr[0] = addmod(zs[2], _pp - zs[0], _pp);
+ //r
+ hr[1] = addmod(zs[3], _pp - zs[1], _pp);
+ //h^2
+ hr[2] = mulmod(hr[0], hr[0], _pp);
+ // h^3
+ hr[3] = mulmod(hr[2], hr[0], _pp);
+ // qx = -h^3 -2u1h^2+r^2
+ uint256 qx = addmod(mulmod(hr[1], hr[1], _pp), _pp - hr[3], _pp);
+ qx = addmod(qx, _pp - mulmod(2, mulmod(zs[0], hr[2], _pp), _pp), _pp);
+ // qy = -s1*z1*h^3+r(u1*h^2 -x^3)
+ uint256 qy = mulmod(hr[1], addmod(mulmod(zs[0], hr[2], _pp), _pp - qx, _pp), _pp);
+ qy = addmod(qy, _pp - mulmod(zs[1], hr[3], _pp), _pp);
+ // qz = h*z1*z2
+ uint256 qz = mulmod(hr[0], mulmod(_z1, _z2, _pp), _pp);
+ return (qx, qy, qz);
+ }
+
+
+ /// @dev Converts a point (x, y, z) expressed in Jacobian coordinates to affine coordinates (x', y', 1).
+ /// @param _x coordinate x
+ /// @param _y coordinate y
+ /// @param _z coordinate z
+ /// @param _pp the modulus
+ /// @return (x', y') affine coordinates
+ function toAffine(
+ uint256 _x,
+ uint256 _y,
+ uint256 _z,
+ uint256 _pp)
+ internal pure returns (uint256, uint256)
+ {
+ uint256 zInv = invMod(_z, _pp);
+ uint256 zInv2 = mulmod(zInv, zInv, _pp);
+ uint256 x2 = mulmod(_x, zInv2, _pp);
+ uint256 y2 = mulmod(_y, mulmod(zInv, zInv2, _pp), _pp);
+
+ return (x2, y2);
+ }
+
+
+ /// @dev Modular euclidean inverse of a number (mod p).
+ /// @param _x The number
+ /// @param _pp The modulus
+ /// @return q such that x*q = 1 (mod _pp)
+ function invMod(uint256 _x, uint256 _pp) internal pure returns (uint256) {
+ require(_x != 0 && _x != _pp && _pp != 0, "Invalid number");
+ uint256 q = 0;
+ uint256 newT = 1;
+ uint256 r = _pp;
+ uint256 t;
+ while (_x != 0) {
+ t = r / _x;
+ (q, newT) = (newT, addmod(q, (_pp - mulmod(t, newT, _pp)), _pp));
+ (r, _x) = (_x, r - t * _x);
+ }
+
+ return q;
+ }
+
+ /// @dev Doubles a point (x, y, z).
+ /// @param _x coordinate x of P1
+ /// @param _y coordinate y of P1
+ /// @param _z coordinate z of P1
+ /// @param _aa the a scalar in the curve equation
+ /// @param _pp the modulus
+ /// @return (qx, qy, qz) 2P in Jacobian
+ function jacDouble(
+ uint256 _x,
+ uint256 _y,
+ uint256 _z,
+ uint256 _aa,
+ uint256 _pp)
+ internal pure returns (uint256, uint256, uint256)
+ {
+ if (_z == 0)
+ return (_x, _y, _z);
+
+ // We follow the equations described in https://pdfs.semanticscholar.org/5c64/29952e08025a9649c2b0ba32518e9a7fb5c2.pdf Section 5
+ // Note: there is a bug in the paper regarding the m parameter, M=3*(x1^2)+a*(z1^4)
+ // x, y, z at this point represent the squares of _x, _y, _z
+ uint256 x = mulmod(_x, _x, _pp); //x1^2
+ uint256 y = mulmod(_y, _y, _pp); //y1^2
+ uint256 z = mulmod(_z, _z, _pp); //z1^2
+
+ // s
+ uint s = mulmod(4, mulmod(_x, y, _pp), _pp);
+ // m
+ uint m = addmod(mulmod(3, x, _pp), mulmod(_aa, mulmod(z, z, _pp), _pp), _pp);
+
+ // x, y, z at this point will be reassigned and rather represent qx, qy, qz from the paper
+ // This allows to reduce the gas cost and stack footprint of the algorithm
+ // qx
+ x = addmod(mulmod(m, m, _pp), _pp - addmod(s, s, _pp), _pp);
+ // qy = -8*y1^4 + M(S-T)
+ y = addmod(mulmod(m, addmod(s, _pp - x, _pp), _pp), _pp - mulmod(8, mulmod(y, y, _pp), _pp), _pp);
+ // qz = 2*y1*z1
+ z = mulmod(2, mulmod(_y, _z, _pp), _pp);
+
+ return (x, y, z);
+ }
+
+ /// @dev Add two points (x1, y1) and (x2, y2) in affine coordinates.
+ /// @param _x1 coordinate x of P1
+ /// @param _y1 coordinate y of P1
+ /// @param _x2 coordinate x of P2
+ /// @param _y2 coordinate y of P2
+ /// @param _aa constant of the curve
+ /// @param _pp the modulus
+ /// @return (qx, qy) = P1+P2 in affine coordinates
+ function ecAdd(
+ uint256 _x1,
+ uint256 _y1,
+ uint256 _x2,
+ uint256 _y2,
+ uint256 _aa,
+ uint256 _pp)
+ internal pure returns (uint256, uint256)
+ {
+ uint x = 0;
+ uint y = 0;
+ uint z = 0;
+
+ // Double if x1==x2 else add
+ if (_x1 == _x2) {
+ // y1 = -y2 mod p
+ if (addmod(_y1, _y2, _pp) == 0) {
+ return (0, 0);
+ } else {
+ // P1 = P2
+ (x, y, z) = jacDouble(
+ _x1,
+ _y1,
+ 1,
+ _aa,
+ _pp);
+ }
+ } else {
+ (x, y, z) = jacAdd(
+ _x1,
+ _y1,
+ 1,
+ _x2,
+ _y2,
+ 1,
+ _pp);
+ }
+ // Get back to affine
+ return toAffine(
+ x,
+ y,
+ z,
+ _pp);
+ }
+
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSSignatureAggregator.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSSignatureAggregator.sol
new file mode 100644
index 00000000..60ea291b
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/BLSSignatureAggregator.sol
@@ -0,0 +1,164 @@
+//SPDX-License-Identifier: Unlicense
+pragma solidity >=0.8.4 <0.9.0;
+pragma abicoder v2;
+
+import "../../interfaces/IAggregator.sol";
+import "../../interfaces/IEntryPoint.sol";
+import {BLSOpen} from "./lib/BLSOpen.sol";
+import "./IBLSAccount.sol";
+import "./BLSHelper.sol";
+
+/**
+ * A BLS-based signature aggregator, to validate aggregated signature of multiple UserOps if BLSAccount
+ */
+contract BLSSignatureAggregator is IAggregator {
+ using UserOperationLib for UserOperation;
+
+ bytes32 public constant BLS_DOMAIN = keccak256("eip4337.bls.domain");
+
+ //copied from BLS.sol
+ uint256 public constant N = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
+
+ /**
+ * @return publicKey - the public key from a BLS keypair the Aggregator will use to verify this UserOp;
+ * normally public key will be queried from the deployed BLSAccount itself;
+ * the public key will be read from the 'initCode' if the account is not deployed yet;
+ */
+ function getUserOpPublicKey(UserOperation memory userOp) public view returns (uint256[4] memory publicKey) {
+ bytes memory initCode = userOp.initCode;
+ if (initCode.length > 0) {
+ publicKey = getTrailingPublicKey(initCode);
+ } else {
+ return IBLSAccount(userOp.sender).getBlsPublicKey{gas : 50000}();
+ }
+ }
+
+ /**
+ * return the trailing 4 words of input data
+ */
+ function getTrailingPublicKey(bytes memory data) public pure returns (uint256[4] memory publicKey) {
+ uint len = data.length;
+ require(len > 32 * 4, "data too short for sig");
+
+ /* solhint-disable-next-line no-inline-assembly */
+ assembly {
+ // actual buffer starts at data+32, so last 128 bytes start at data+32+len-128 = data+len-96
+ let ofs := sub(add(data, len), 96)
+ mstore(publicKey, mload(ofs))
+ mstore(add(publicKey, 32), mload(add(ofs, 32)))
+ mstore(add(publicKey, 64), mload(add(ofs, 64)))
+ mstore(add(publicKey, 96), mload(add(ofs, 96)))
+ }
+ }
+
+ /// @inheritdoc IAggregator
+ function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature)
+ external view override {
+ require(signature.length == 64, "BLS: invalid signature");
+ (uint256[2] memory blsSignature) = abi.decode(signature, (uint256[2]));
+
+ uint userOpsLen = userOps.length;
+ uint256[4][] memory blsPublicKeys = new uint256[4][](userOpsLen);
+ uint256[2][] memory messages = new uint256[2][](userOpsLen);
+ for (uint256 i = 0; i < userOpsLen; i++) {
+
+ UserOperation memory userOp = userOps[i];
+ blsPublicKeys[i] = getUserOpPublicKey(userOp);
+
+ messages[i] = _userOpToMessage(userOp, _getPublicKeyHash(blsPublicKeys[i]));
+ }
+ require(BLSOpen.verifyMultiple(blsSignature, blsPublicKeys, messages), "BLS: validateSignatures failed");
+ }
+
+ /**
+ * get a hash of userOp
+ * NOTE: this hash is not the same as UserOperation.hash()
+ * (slightly less efficient, since it uses memory userOp)
+ */
+ function internalUserOpHash(UserOperation memory userOp) internal pure returns (bytes32) {
+ return keccak256(abi.encode(
+ userOp.sender,
+ userOp.nonce,
+ keccak256(userOp.initCode),
+ keccak256(userOp.callData),
+ userOp.callGasLimit,
+ userOp.verificationGasLimit,
+ userOp.preVerificationGas,
+ userOp.maxFeePerGas,
+ userOp.maxPriorityFeePerGas,
+ keccak256(userOp.paymasterAndData)
+ ));
+ }
+
+ /**
+ * return the BLS "message" for the given UserOp.
+ * the account checks the signature over this value using its public key
+ */
+ function userOpToMessage(UserOperation memory userOp) public view returns (uint256[2] memory) {
+ bytes32 publicKeyHash = _getPublicKeyHash(getUserOpPublicKey(userOp));
+ return _userOpToMessage(userOp, publicKeyHash);
+ }
+
+ function _userOpToMessage(UserOperation memory userOp, bytes32 publicKeyHash) internal view returns (uint256[2] memory) {
+ bytes32 userOpHash = _getUserOpHash(userOp, publicKeyHash);
+ return BLSOpen.hashToPoint(BLS_DOMAIN, abi.encodePacked(userOpHash));
+ }
+
+ // helper for test
+ function getUserOpHash(UserOperation memory userOp) public view returns (bytes32) {
+ bytes32 publicKeyHash = _getPublicKeyHash(getUserOpPublicKey(userOp));
+ return _getUserOpHash(userOp, publicKeyHash);
+ }
+
+ function _getUserOpHash(UserOperation memory userOp, bytes32 publicKeyHash) internal view returns (bytes32) {
+ return keccak256(abi.encode(internalUserOpHash(userOp), publicKeyHash, address(this), block.chainid));
+ }
+
+ function _getPublicKeyHash(uint256[4] memory publicKey) internal pure returns(bytes32) {
+ return keccak256(abi.encode(publicKey));
+ }
+ /**
+ * validate signature of a single userOp
+ * This method is called after EntryPoint.simulateValidation() returns 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.
+ * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.
+ * (usually empty, unless account and aggregator support some kind of "multisig"
+ */
+ function validateUserOpSignature(UserOperation calldata userOp)
+ external view returns (bytes memory sigForUserOp) {
+ uint256[2] memory signature = abi.decode(userOp.signature, (uint256[2]));
+ uint256[4] memory pubkey = getUserOpPublicKey(userOp);
+ uint256[2] memory message = _userOpToMessage(userOp, _getPublicKeyHash(pubkey));
+
+ require(BLSOpen.verifySingle(signature, pubkey, message), "BLS: wrong sig");
+ return "";
+ }
+
+
+ /**
+ * aggregate multiple signatures into a single value.
+ * This method is called off-chain to calculate the signature to pass with handleOps()
+ * bundler MAY use optimized custom code perform this aggregation
+ * @param userOps array of UserOperations to collect the signatures from.
+ * @return aggregatedSignature the aggregated signature
+ */
+ function aggregateSignatures(UserOperation[] calldata userOps) external pure returns (bytes memory aggregatedSignature) {
+ BLSHelper.XY[] memory points = new BLSHelper.XY[](userOps.length);
+ for (uint i = 0; i < points.length; i++) {
+ (uint256 x, uint256 y) = abi.decode(userOps[i].signature, (uint256, uint256));
+ points[i] = BLSHelper.XY(x, y);
+ }
+ BLSHelper.XY memory sum = BLSHelper.sum(points, N);
+ return abi.encode(sum.x, sum.y);
+ }
+
+ /**
+ * allow staking for this aggregator
+ * there is no limit on stake or delay, but it is not a problem, since it is a permissionless
+ * signature aggregator, which doesn't support unstaking.
+ */
+ function addStake(IEntryPoint entryPoint, uint32 delay) external payable {
+ entryPoint.addStake{value : msg.value}(delay);
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/IBLSAccount.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/IBLSAccount.sol
new file mode 100644
index 00000000..c34da4fb
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/IBLSAccount.sol
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-3.0-only
+pragma solidity >=0.7.6;
+
+import "../../interfaces/IAccount.sol";
+
+/**
+ * a BLS account should expose its own public key.
+ */
+interface IBLSAccount is IAccount {
+ event PublicKeyChanged(uint256[4] oldPublicKey, uint256[4] newPublicKey);
+
+ /**
+ * @return public key from a BLS keypair that is used to verify the BLS signature, both separately and aggregated.
+ */
+ function getBlsPublicKey() external view returns (uint256[4] memory);
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/BLSOpen.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/BLSOpen.sol
new file mode 100644
index 00000000..c6d0a98e
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/BLSOpen.sol
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: MIT
+pragma solidity >= 0.6.12;
+
+import { BLS } from "./hubble-contracts/contracts/libs/BLS.sol";
+
+library BLSOpen {
+ function verifySingle(
+ uint256[2] memory signature,
+ uint256[4] memory pubkey,
+ uint256[2] memory message
+ ) external view returns (bool) {
+ uint256[4][] memory pubkeys = new uint256[4][](1);
+ uint256[2][] memory messages = new uint256[2][](1);
+ pubkeys[0] = pubkey;
+ messages[0] = message;
+
+ (bool verified, bool callSuccess) = BLS.verifyMultiple(
+ signature,
+ pubkeys,
+ messages
+ );
+ return callSuccess && verified;
+
+ // // NB: (result, success) opposite of `call` convention (success, result).
+ // (bool verified, bool callSuccess) = BLS.verifySingle(
+ // signature,
+ // pubkey,
+ // message
+ // );
+ // return callSuccess && verified;
+ }
+
+ function verifyMultiple(
+ uint256[2] memory signature,
+ uint256[4][] memory pubkeys,
+ uint256[2][] memory messages
+ ) external view returns (bool) {
+ (bool verified, bool callSuccess) = BLS.verifyMultiple(
+ signature,
+ pubkeys,
+ messages
+ );
+ return callSuccess && verified;
+ }
+
+ function hashToPoint(
+ bytes32 domain,
+ bytes memory message
+ ) external view returns (uint256[2] memory) {
+ return BLS.hashToPoint(
+ domain,
+ message
+ );
+ }
+
+ function isZeroBLSKey(uint256[4] memory blsKey) public pure returns (bool) {
+ bool isZero = true;
+ for (uint256 i=0; isZero && i<4; i++) {
+ isZero = (blsKey[i] == 0);
+ }
+ return isZero;
+ }
+
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/hubble-contracts/contracts/libs/BLS.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/hubble-contracts/contracts/libs/BLS.sol
new file mode 100644
index 00000000..e02bc10c
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/hubble-contracts/contracts/libs/BLS.sol
@@ -0,0 +1,440 @@
+// SPDX-License-Identifier: MIT
+pragma solidity >= 0.6.12;
+
+import { ModexpInverse, ModexpSqrt } from "./ModExp.sol";
+import {
+ BNPairingPrecompileCostEstimator
+} from "./BNPairingPrecompileCostEstimator.sol";
+
+/**
+ @title Boneh–Lynn–Shacham (BLS) signature scheme on Barreto-Naehrig 254 bit curve (BN-254)
+ @notice We use BLS signature aggregation to reduce the size of signature data to store on chain.
+ @dev We use G1 points for signatures and messages, and G2 points for public keys
+ */
+library BLS {
+ // Field order
+ // prettier-ignore
+ uint256 private constant N = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
+
+ // Negated genarator of G2
+ // prettier-ignore
+ uint256 private constant N_G2_X1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
+ // prettier-ignore
+ uint256 private constant N_G2_X0 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
+ // prettier-ignore
+ uint256 private constant N_G2_Y1 = 17805874995975841540914202342111839520379459829704422454583296818431106115052;
+ // prettier-ignore
+ uint256 private constant N_G2_Y0 = 13392588948715843804641432497768002650278120570034223513918757245338268106653;
+
+ // sqrt(-3)
+ // prettier-ignore
+ uint256 private constant Z0 = 0x0000000000000000b3c4d79d41a91759a9e4c7e359b6b89eaec68e62effffffd;
+ // (sqrt(-3) - 1) / 2
+ // prettier-ignore
+ uint256 private constant Z1 = 0x000000000000000059e26bcea0d48bacd4f263f1acdb5c4f5763473177fffffe;
+
+ // prettier-ignore
+ uint256 private constant T24 = 0x1000000000000000000000000000000000000000000000000;
+ // prettier-ignore
+ uint256 private constant MASK24 = 0xffffffffffffffffffffffffffffffffffffffffffffffff;
+
+ // estimator address
+// address private constant COST_ESTIMATOR_ADDRESS = new 0x22E4a5251C1F02de8369Dd6f192033F6CB7531A4;
+
+ function verifySingle(
+ uint256[2] memory signature,
+ uint256[4] memory pubkey,
+ uint256[2] memory message
+ ) internal view returns (bool, bool) {
+ uint256[12] memory input =
+ [
+ signature[0],
+ signature[1],
+ N_G2_X1,
+ N_G2_X0,
+ N_G2_Y1,
+ N_G2_Y0,
+ message[0],
+ message[1],
+ pubkey[1],
+ pubkey[0],
+ pubkey[3],
+ pubkey[2]
+ ];
+ uint256[1] memory out;
+ uint256 precompileGasCost = gasleft();
+// BNPairingPrecompileCostEstimator(COST_ESTIMATOR_ADDRESS).getGasCost(
+// 2
+// );
+ bool callSuccess;
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ callSuccess := staticcall(
+ precompileGasCost,
+ 8,
+ input,
+ 384,
+ out,
+ 0x20
+ )
+ }
+ if (!callSuccess) {
+ return (false, false);
+ }
+ return (out[0] != 0, true);
+ }
+
+ function verifyMultiple(
+ uint256[2] memory signature,
+ uint256[4][] memory pubkeys,
+ uint256[2][] memory messages
+ ) internal view returns (bool checkResult, bool callSuccess) {
+ uint256 size = pubkeys.length;
+ require(size > 0, "BLS: number of public key is zero");
+ require(
+ size == messages.length,
+ "BLS: number of public keys and messages must be equal"
+ );
+ uint256 inputSize = (size + 1) * 6;
+ uint256[] memory input = new uint256[](inputSize);
+ input[0] = signature[0];
+ input[1] = signature[1];
+ input[2] = N_G2_X1;
+ input[3] = N_G2_X0;
+ input[4] = N_G2_Y1;
+ input[5] = N_G2_Y0;
+ for (uint256 i = 0; i < size; i++) {
+ input[i * 6 + 6] = messages[i][0];
+ input[i * 6 + 7] = messages[i][1];
+ input[i * 6 + 8] = pubkeys[i][1];
+ input[i * 6 + 9] = pubkeys[i][0];
+ input[i * 6 + 10] = pubkeys[i][3];
+ input[i * 6 + 11] = pubkeys[i][2];
+ }
+ uint256[1] memory out;
+
+ // prettier-ignore
+ uint256 precompileGasCost = gasleft();
+// uint256 precompileGasCost = BNPairingPrecompileCostEstimator(COST_ESTIMATOR_ADDRESS).getGasCost(size + 1);
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ callSuccess := staticcall(
+ precompileGasCost,
+ 8,
+ add(input, 0x20),
+ mul(inputSize, 0x20),
+ out,
+ 0x20
+ )
+ }
+ if (!callSuccess) {
+ return (false, false);
+ }
+ return (out[0] != 0, true);
+ }
+
+ /**
+ @notice Fouque-Tibouchi Hash to Curve
+ */
+ function hashToPoint(bytes32 domain, bytes memory message)
+ internal
+ view
+ returns (uint256[2] memory)
+ {
+ uint256[2] memory u = hashToField(domain, message);
+ uint256[2] memory p0 = mapToPoint(u[0]);
+ uint256[2] memory p1 = mapToPoint(u[1]);
+ uint256[4] memory bnAddInput;
+ bnAddInput[0] = p0[0];
+ bnAddInput[1] = p0[1];
+ bnAddInput[2] = p1[0];
+ bnAddInput[3] = p1[1];
+ bool success;
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ success := staticcall(sub(gas(), 2000), 6, bnAddInput, 128, p0, 64)
+ switch success
+ case 0 {
+ invalid()
+ }
+ }
+ require(success, "BLS: bn add call failed");
+ return p0;
+ }
+
+ function mapToPoint(uint256 _x)
+ internal
+ pure
+ returns (uint256[2] memory p)
+ {
+ require(_x < N, "mapToPointFT: invalid field element");
+ uint256 x = _x;
+
+ (, bool decision) = sqrt(x);
+
+ uint256 a0 = mulmod(x, x, N);
+ a0 = addmod(a0, 4, N);
+ uint256 a1 = mulmod(x, Z0, N);
+ uint256 a2 = mulmod(a1, a0, N);
+ a2 = inverse(a2);
+ a1 = mulmod(a1, a1, N);
+ a1 = mulmod(a1, a2, N);
+
+ // x1
+ a1 = mulmod(x, a1, N);
+ x = addmod(Z1, N - a1, N);
+ // check curve
+ a1 = mulmod(x, x, N);
+ a1 = mulmod(a1, x, N);
+ a1 = addmod(a1, 3, N);
+ bool found;
+ (a1, found) = sqrt(a1);
+ if (found) {
+ if (!decision) {
+ a1 = N - a1;
+ }
+ return [x, a1];
+ }
+
+ // x2
+ x = N - addmod(x, 1, N);
+ // check curve
+ a1 = mulmod(x, x, N);
+ a1 = mulmod(a1, x, N);
+ a1 = addmod(a1, 3, N);
+ (a1, found) = sqrt(a1);
+ if (found) {
+ if (!decision) {
+ a1 = N - a1;
+ }
+ return [x, a1];
+ }
+
+ // x3
+ x = mulmod(a0, a0, N);
+ x = mulmod(x, x, N);
+ x = mulmod(x, a2, N);
+ x = mulmod(x, a2, N);
+ x = addmod(x, 1, N);
+ // must be on curve
+ a1 = mulmod(x, x, N);
+ a1 = mulmod(a1, x, N);
+ a1 = addmod(a1, 3, N);
+ (a1, found) = sqrt(a1);
+ require(found, "BLS: bad ft mapping implementation");
+ if (!decision) {
+ a1 = N - a1;
+ }
+ return [x, a1];
+ }
+
+ function isValidSignature(uint256[2] memory signature)
+ internal
+ pure
+ returns (bool)
+ {
+ if ((signature[0] >= N) || (signature[1] >= N)) {
+ return false;
+ } else {
+ return isOnCurveG1(signature);
+ }
+ }
+
+ function isOnCurveG1(uint256[2] memory point)
+ internal
+ pure
+ returns (bool _isOnCurve)
+ {
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ let t0 := mload(point)
+ let t1 := mload(add(point, 32))
+ let t2 := mulmod(t0, t0, N)
+ t2 := mulmod(t2, t0, N)
+ t2 := addmod(t2, 3, N)
+ t1 := mulmod(t1, t1, N)
+ _isOnCurve := eq(t1, t2)
+ }
+ }
+
+ function isOnCurveG2(uint256[4] memory point)
+ internal
+ pure
+ returns (bool _isOnCurve)
+ {
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ // x0, x1
+ let t0 := mload(point)
+ let t1 := mload(add(point, 32))
+ // x0 ^ 2
+ let t2 := mulmod(t0, t0, N)
+ // x1 ^ 2
+ let t3 := mulmod(t1, t1, N)
+ // 3 * x0 ^ 2
+ let t4 := add(add(t2, t2), t2)
+ // 3 * x1 ^ 2
+ let t5 := addmod(add(t3, t3), t3, N)
+ // x0 * (x0 ^ 2 - 3 * x1 ^ 2)
+ t2 := mulmod(add(t2, sub(N, t5)), t0, N)
+ // x1 * (3 * x0 ^ 2 - x1 ^ 2)
+ t3 := mulmod(add(t4, sub(N, t3)), t1, N)
+
+ // x ^ 3 + b
+ t0 := addmod(
+ t2,
+ 0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5,
+ N
+ )
+ t1 := addmod(
+ t3,
+ 0x009713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2,
+ N
+ )
+
+ // y0, y1
+ t2 := mload(add(point, 64))
+ t3 := mload(add(point, 96))
+ // y ^ 2
+ t4 := mulmod(addmod(t2, t3, N), addmod(t2, sub(N, t3), N), N)
+ t3 := mulmod(shl(1, t2), t3, N)
+
+ // y ^ 2 == x ^ 3 + b
+ _isOnCurve := and(eq(t0, t4), eq(t1, t3))
+ }
+ }
+
+ function sqrt(uint256 xx) internal pure returns (uint256 x, bool hasRoot) {
+ x = ModexpSqrt.run(xx);
+ hasRoot = mulmod(x, x, N) == xx;
+ }
+
+ function inverse(uint256 a) internal pure returns (uint256) {
+ return ModexpInverse.run(a);
+ }
+
+ function hashToField(bytes32 domain, bytes memory messages)
+ internal
+ pure
+ returns (uint256[2] memory)
+ {
+ bytes memory _msg = expandMsgTo96(domain, messages);
+ uint256 u0;
+ uint256 u1;
+ uint256 a0;
+ uint256 a1;
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ let p := add(_msg, 24)
+ u1 := and(mload(p), MASK24)
+ p := add(_msg, 48)
+ u0 := and(mload(p), MASK24)
+ a0 := addmod(mulmod(u1, T24, N), u0, N)
+ p := add(_msg, 72)
+ u1 := and(mload(p), MASK24)
+ p := add(_msg, 96)
+ u0 := and(mload(p), MASK24)
+ a1 := addmod(mulmod(u1, T24, N), u0, N)
+ }
+ return [a0, a1];
+ }
+
+ function expandMsgTo96(bytes32 domain, bytes memory message)
+ internal
+ pure
+ returns (bytes memory)
+ {
+ // zero<64>|msg|lib_str<2>|I2OSP(0, 1)<1>|dst|dst_len<1>
+ uint256 t0 = message.length;
+ bytes memory msg0 = new bytes(32 + t0 + 64 + 4);
+ bytes memory out = new bytes(96);
+ // b0
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ let p := add(msg0, 96)
+ for {
+ let z := 0
+ } lt(z, t0) {
+ z := add(z, 32)
+ } {
+ mstore(add(p, z), mload(add(message, add(z, 32))))
+ }
+ p := add(p, t0)
+
+ mstore8(p, 0)
+ p := add(p, 1)
+ mstore8(p, 96)
+ p := add(p, 1)
+ mstore8(p, 0)
+ p := add(p, 1)
+
+ mstore(p, domain)
+ p := add(p, 32)
+ mstore8(p, 32)
+ }
+ bytes32 b0 = sha256(msg0);
+ bytes32 bi;
+ t0 = 32 + 34;
+
+ // resize intermediate message
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ mstore(msg0, t0)
+ }
+
+ // b1
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ mstore(add(msg0, 32), b0)
+ mstore8(add(msg0, 64), 1)
+ mstore(add(msg0, 65), domain)
+ mstore8(add(msg0, add(32, 65)), 32)
+ }
+
+ bi = sha256(msg0);
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ mstore(add(out, 32), bi)
+ }
+
+ // b2
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ let t := xor(b0, bi)
+ mstore(add(msg0, 32), t)
+ mstore8(add(msg0, 64), 2)
+ mstore(add(msg0, 65), domain)
+ mstore8(add(msg0, add(32, 65)), 32)
+ }
+
+ bi = sha256(msg0);
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ mstore(add(out, 64), bi)
+ }
+
+ // b3
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ let t := xor(b0, bi)
+ mstore(add(msg0, 32), t)
+ mstore8(add(msg0, 64), 3)
+ mstore(add(msg0, 65), domain)
+ mstore8(add(msg0, add(32, 65)), 32)
+ }
+
+ bi = sha256(msg0);
+
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ mstore(add(out, 96), bi)
+ }
+
+ return out;
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/hubble-contracts/contracts/libs/BNPairingPrecompileCostEstimator.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/hubble-contracts/contracts/libs/BNPairingPrecompileCostEstimator.sol
new file mode 100644
index 00000000..30d04a40
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/hubble-contracts/contracts/libs/BNPairingPrecompileCostEstimator.sol
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: MIT
+pragma solidity >=0.6.12;
+
+contract BNPairingPrecompileCostEstimator {
+ uint256 public baseCost;
+ uint256 public perPairCost;
+
+ // G1 Generator
+ uint256 private constant G1_X = 1;
+ uint256 private constant G1_Y = 2;
+
+ // G2 genarator
+ // prettier-ignore
+ uint256 private constant G2_X0 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
+ // prettier-ignore
+ uint256 private constant G2_X1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
+ // prettier-ignore
+ uint256 private constant G2_Y0 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
+ // prettier-ignore
+ uint256 private constant G2_Y1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
+
+ // G2 negated genarator y coordinates
+ // prettier-ignore
+ uint256 private constant N_G2_Y0 = 13392588948715843804641432497768002650278120570034223513918757245338268106653;
+ // prettier-ignore
+ uint256 private constant N_G2_Y1 = 17805874995975841540914202342111839520379459829704422454583296818431106115052;
+
+ function run() external {
+ _run();
+ }
+
+ function getGasCost(uint256 pairCount) external view returns (uint256) {
+ return pairCount * perPairCost + baseCost;
+ }
+
+ function _run() internal {
+ uint256 gasCost1Pair = _gasCost1Pair();
+ uint256 gasCost2Pair = _gasCost2Pair();
+ perPairCost = gasCost2Pair - gasCost1Pair;
+ baseCost = gasCost1Pair - perPairCost;
+ }
+
+ function _gasCost1Pair() internal view returns (uint256) {
+ uint256[6] memory input = [G1_X, G1_Y, G2_X1, G2_X0, G2_Y1, G2_Y0];
+ uint256[1] memory out;
+ bool callSuccess;
+ uint256 suppliedGas = gasleft() - 2000;
+ require(
+ gasleft() > 2000,
+ "BNPairingPrecompileCostEstimator: not enough gas, single pair"
+ );
+ uint256 gasT0 = gasleft();
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ callSuccess := staticcall(suppliedGas, 8, input, 192, out, 0x20)
+ }
+ uint256 gasCost = gasT0 - gasleft();
+ require(
+ callSuccess,
+ "BNPairingPrecompileCostEstimator: single pair call is failed"
+ );
+ require(
+ out[0] == 0,
+ "BNPairingPrecompileCostEstimator: single pair call result must be 0"
+ );
+ return gasCost;
+ }
+
+ function _gasCost2Pair() internal view returns (uint256) {
+ uint256[12] memory input =
+ [
+ G1_X,
+ G1_Y,
+ G2_X1,
+ G2_X0,
+ G2_Y1,
+ G2_Y0,
+ G1_X,
+ G1_Y,
+ G2_X1,
+ G2_X0,
+ N_G2_Y1,
+ N_G2_Y0
+ ];
+ uint256[1] memory out;
+ bool callSuccess;
+ uint256 suppliedGas = gasleft() - 2000;
+ require(
+ gasleft() > 2000,
+ "BNPairingPrecompileCostEstimator: not enough gas, couple pair"
+ );
+ uint256 gasT0 = gasleft();
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ callSuccess := staticcall(suppliedGas, 8, input, 384, out, 0x20)
+ }
+ uint256 gasCost = gasT0 - gasleft();
+ require(
+ callSuccess,
+ "BNPairingPrecompileCostEstimator: couple pair call is failed"
+ );
+ require(
+ out[0] == 1,
+ "BNPairingPrecompileCostEstimator: couple pair call result must be 1"
+ );
+ return gasCost;
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/hubble-contracts/contracts/libs/ModExp.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/hubble-contracts/contracts/libs/ModExp.sol
new file mode 100644
index 00000000..6fd08f11
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/bls/lib/hubble-contracts/contracts/libs/ModExp.sol
@@ -0,0 +1,652 @@
+// SPDX-License-Identifier: MIT
+pragma solidity >= 0.6.12;
+
+/**
+ @title Compute Inverse by Modular Exponentiation
+ @notice Compute $input^(N - 2) mod N$ using Addition Chain method.
+ Where N = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
+ and N - 2 = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45
+ @dev the function body is generated with the modified addchain script
+ see https://github.com/kobigurk/addchain/commit/2c37a2ace567a9bdc680b4e929c94aaaa3ec700f
+ */
+library ModexpInverse {
+ function run(uint256 t2) internal pure returns (uint256 t0) {
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ let
+ n
+ := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
+ t0 := mulmod(t2, t2, n)
+ let t5 := mulmod(t0, t2, n)
+ let t1 := mulmod(t5, t0, n)
+ let t3 := mulmod(t5, t5, n)
+ let t8 := mulmod(t1, t0, n)
+ let t4 := mulmod(t3, t5, n)
+ let t6 := mulmod(t3, t1, n)
+ t0 := mulmod(t3, t3, n)
+ let t7 := mulmod(t8, t3, n)
+ t3 := mulmod(t4, t3, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t7, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t7, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t4, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t7, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t3, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t3, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t4, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t3, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ }
+ }
+}
+
+/**
+ @title Compute Squre Root by Modular Exponentiation
+ @notice Compute $input^{(N + 1) / 4} mod N$ using Addition Chain method.
+ Where N = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
+ and (N + 1) / 4 = 0xc19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52
+ */
+library ModexpSqrt {
+ function run(uint256 t6) internal pure returns (uint256 t0) {
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ let
+ n
+ := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
+
+ t0 := mulmod(t6, t6, n)
+ let t4 := mulmod(t0, t6, n)
+ let t2 := mulmod(t4, t0, n)
+ let t3 := mulmod(t4, t4, n)
+ let t8 := mulmod(t2, t0, n)
+ let t1 := mulmod(t3, t4, n)
+ let t5 := mulmod(t3, t2, n)
+ t0 := mulmod(t3, t3, n)
+ let t7 := mulmod(t8, t3, n)
+ t3 := mulmod(t1, t3, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t4, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t4, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t7, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t4, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t7, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t4, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t4, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t8, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t7, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t3, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t6, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t4, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t5, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t4, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t4, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t3, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t3, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t2, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t0, n)
+ t0 := mulmod(t0, t1, n)
+ t0 := mulmod(t0, t0, n)
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/callback/TokenCallbackHandler.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/callback/TokenCallbackHandler.sol
new file mode 100644
index 00000000..2da98ae8
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/callback/TokenCallbackHandler.sol
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+/* solhint-disable no-empty-blocks */
+
+import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
+import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
+import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
+
+/**
+ * Token callback handler.
+ * Handles supported tokens' callbacks, allowing account receiving these tokens.
+ */
+contract TokenCallbackHandler is IERC721Receiver, IERC1155Receiver {
+ function tokensReceived(
+ address,
+ address,
+ address,
+ uint256,
+ bytes calldata,
+ bytes calldata
+ ) external pure {
+ }
+
+ function onERC721Received(
+ address,
+ address,
+ uint256,
+ bytes calldata
+ ) external pure override returns (bytes4) {
+ return IERC721Receiver.onERC721Received.selector;
+ }
+
+ function onERC1155Received(
+ address,
+ address,
+ uint256,
+ uint256,
+ bytes calldata
+ ) external pure override returns (bytes4) {
+ return IERC1155Receiver.onERC1155Received.selector;
+ }
+
+ function onERC1155BatchReceived(
+ address,
+ address,
+ uint256[] calldata,
+ uint256[] calldata,
+ bytes calldata
+ ) external pure override returns (bytes4) {
+ return IERC1155Receiver.onERC1155BatchReceived.selector;
+ }
+
+ function supportsInterface(bytes4 interfaceId) external view virtual override returns (bool) {
+ return
+ interfaceId == type(IERC721Receiver).interfaceId ||
+ interfaceId == type(IERC1155Receiver).interfaceId ||
+ interfaceId == type(IERC165).interfaceId;
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/gnosis/EIP4337Fallback.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/gnosis/EIP4337Fallback.sol
new file mode 100644
index 00000000..622cc438
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/gnosis/EIP4337Fallback.sol
@@ -0,0 +1,91 @@
+//SPDX-License-Identifier: GPL
+pragma solidity ^0.8.7;
+
+/* solhint-disable no-inline-assembly */
+
+import "@gnosis.pm/safe-contracts/contracts/handler/DefaultCallbackHandler.sol";
+import "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol";
+import "@openzeppelin/contracts/interfaces/IERC1271.sol";
+import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
+import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
+import "../../interfaces/IAccount.sol";
+import "./EIP4337Manager.sol";
+
+using ECDSA for bytes32;
+using MessageHashUtils for bytes32;
+
+/**
+ * The GnosisSafe enables adding custom functions implementation to the Safe by setting a 'fallbackHandler'.
+ * This 'fallbackHandler' adds an implementation of 'validateUserOp' to the GnosisSafe.
+ * Note that the implementation of the 'validateUserOp' method is located in the EIP4337Manager.
+ * Upon receiving the 'validateUserOp', a Safe with EIP4337Fallback enabled makes a 'delegatecall' to EIP4337Manager.
+ */
+contract EIP4337Fallback is DefaultCallbackHandler, IAccount, IERC1271 {
+ bytes4 internal constant ERC1271_MAGIC_VALUE = 0x1626ba7e;
+
+ address immutable public eip4337manager;
+ constructor(address _eip4337manager) {
+ eip4337manager = _eip4337manager;
+ }
+
+ /**
+ * delegate the contract call to the EIP4337Manager
+ */
+ function delegateToManager() internal returns (bytes memory) {
+ // delegate entire msg.data (including the appended "msg.sender") to the EIP4337Manager
+ // will work only for GnosisSafe contracts
+ GnosisSafe safe = GnosisSafe(payable(msg.sender));
+ (bool success, bytes memory ret) = safe.execTransactionFromModuleReturnData(eip4337manager, 0, msg.data, Enum.Operation.DelegateCall);
+ if (!success) {
+ assembly {
+ revert(add(ret, 32), mload(ret))
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * called from the Safe. delegate actual work to EIP4337Manager
+ */
+ function validateUserOp(UserOperation calldata, bytes32, uint256) override external returns (uint256 deadline){
+ bytes memory ret = delegateToManager();
+ return abi.decode(ret, (uint256));
+ }
+
+ /**
+ * Helper for wallet to get the next nonce.
+ */
+ function getNonce() public returns (uint256 nonce) {
+ bytes memory ret = delegateToManager();
+ (nonce) = abi.decode(ret, (uint256));
+ }
+
+ /**
+ * called from the Safe. delegate actual work to EIP4337Manager
+ */
+ function executeAndRevert(
+ address,
+ uint256,
+ bytes memory,
+ Enum.Operation
+ ) external {
+ delegateToManager();
+ }
+
+ function isValidSignature(
+ bytes32 _hash,
+ bytes memory _signature
+ ) external override view returns (bytes4) {
+ bytes32 hash = _hash.toEthSignedMessageHash();
+ address recovered = hash.recover(_signature);
+
+ GnosisSafe safe = GnosisSafe(payable(address(msg.sender)));
+
+ // Validate signatures
+ if (safe.isOwner(recovered)) {
+ return ERC1271_MAGIC_VALUE;
+ } else {
+ return 0xffffffff;
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/gnosis/EIP4337Manager.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/gnosis/EIP4337Manager.sol
new file mode 100644
index 00000000..c1880437
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/gnosis/EIP4337Manager.sol
@@ -0,0 +1,199 @@
+//SPDX-License-Identifier: GPL
+pragma solidity ^0.8.7;
+
+/* solhint-disable avoid-low-level-calls */
+/* solhint-disable no-inline-assembly */
+/* solhint-disable reason-string */
+
+import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
+import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";
+import "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol";
+import "@gnosis.pm/safe-contracts/contracts/base/Executor.sol";
+import "@gnosis.pm/safe-contracts/contracts/examples/libraries/GnosisSafeStorage.sol";
+import "./EIP4337Fallback.sol";
+import "../../interfaces/IAccount.sol";
+import "../../interfaces/IEntryPoint.sol";
+import "../../utils/Exec.sol";
+
+ using ECDSA for bytes32;
+ using MessageHashUtils for bytes32;
+
+/**
+ * Main EIP4337 module.
+ * Called (through the fallback module) using "delegate" from the GnosisSafe as an "IAccount",
+ * so must implement validateUserOp
+ * holds an immutable reference to the EntryPoint
+ * Inherits GnosisSafe so that it can reference the memory storage
+ */
+contract EIP4337Manager is IAccount, GnosisSafeStorage, Executor {
+
+ address public immutable eip4337Fallback;
+ address public immutable entryPoint;
+
+ // return value in case of signature failure, with no time-range.
+ // equivalent to _packValidationData(true,0,0);
+ uint256 constant internal SIG_VALIDATION_FAILED = 1;
+
+ address internal constant SENTINEL_MODULES = address(0x1);
+
+ constructor(address anEntryPoint) {
+ entryPoint = anEntryPoint;
+ eip4337Fallback = address(new EIP4337Fallback(address(this)));
+ }
+
+ /**
+ * delegate-called (using execFromModule) through the fallback, so "real" msg.sender is attached as last 20 bytes
+ */
+ function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)
+ external override returns (uint256 validationData) {
+ address msgSender = address(bytes20(msg.data[msg.data.length - 20 :]));
+ require(msgSender == entryPoint, "account: not from entrypoint");
+
+ GnosisSafe pThis = GnosisSafe(payable(address(this)));
+ bytes32 hash = userOpHash.toEthSignedMessageHash();
+ address recovered = hash.recover(userOp.signature);
+ require(threshold == 1, "account: only threshold 1");
+ if (!pThis.isOwner(recovered)) {
+ validationData = SIG_VALIDATION_FAILED;
+ }
+
+ // mimic normal Safe nonce behaviour: prevent parallel nonces
+ require(userOp.nonce < type(uint64).max, "account: nonsequential nonce");
+
+ if (missingAccountFunds > 0) {
+ //Note: MAY pay more than the minimum, to deposit for future transactions
+ (bool success,) = payable(msgSender).call{value : missingAccountFunds}("");
+ (success);
+ //ignore failure (its EntryPoint's job to verify, not account.)
+ }
+ }
+
+ /**
+ * Execute a call but also revert if the execution fails.
+ * The default behavior of the Safe is to not revert if the call fails,
+ * which is challenging for integrating with ERC4337 because then the
+ * EntryPoint wouldn't know to emit the UserOperationRevertReason event,
+ * which the frontend/client uses to capture the reason for the failure.
+ */
+ function executeAndRevert(
+ address to,
+ uint256 value,
+ bytes memory data,
+ Enum.Operation operation
+ ) external {
+ address msgSender = address(bytes20(msg.data[msg.data.length - 20 :]));
+ require(msgSender == entryPoint, "account: not from entrypoint");
+ require(msg.sender == eip4337Fallback, "account: not from EIP4337Fallback");
+
+ bool success = execute(
+ to,
+ value,
+ data,
+ operation,
+ type(uint256).max
+ );
+
+ bytes memory returnData = Exec.getReturnData(type(uint256).max);
+ // Revert with the actual reason string
+ // Adopted from: https://github.com/Uniswap/v3-periphery/blob/464a8a49611272f7349c970e0fadb7ec1d3c1086/contracts/base/Multicall.sol#L16-L23
+ if (!success) {
+ if (returnData.length < 68) revert();
+ assembly {
+ returnData := add(returnData, 0x04)
+ }
+ revert(abi.decode(returnData, (string)));
+ }
+ }
+
+ /**
+ * Helper for wallet to get the next nonce.
+ */
+ function getNonce() public view returns (uint256) {
+ return IEntryPoint(entryPoint).getNonce(address(this), 0);
+ }
+
+ /**
+ * set up a safe as EIP-4337 enabled.
+ * called from the GnosisSafeAccountFactory during construction time
+ * - enable 3 modules (this module, fallback and the entrypoint)
+ * - this method is called with delegateCall, so the module (usually itself) is passed as parameter, and "this" is the safe itself
+ */
+ function setup4337Modules(
+ EIP4337Manager manager //the manager (this contract)
+ ) external {
+ GnosisSafe safe = GnosisSafe(payable(address(this)));
+ require(!safe.isModuleEnabled(manager.entryPoint()), "setup4337Modules: entrypoint already enabled");
+ require(!safe.isModuleEnabled(manager.eip4337Fallback()), "setup4337Modules: eip4337Fallback already enabled");
+ safe.enableModule(manager.entryPoint());
+ safe.enableModule(manager.eip4337Fallback());
+ }
+
+ /**
+ * replace EIP4337 module, to support a new EntryPoint.
+ * must be called using execTransaction and Enum.Operation.DelegateCall
+ * @param prevModule returned by getCurrentEIP4337Manager
+ * @param oldManager the old EIP4337 manager to remove, returned by getCurrentEIP4337Manager
+ * @param newManager the new EIP4337Manager, usually with a new EntryPoint
+ */
+ function replaceEIP4337Manager(address prevModule, EIP4337Manager oldManager, EIP4337Manager newManager) public {
+ GnosisSafe pThis = GnosisSafe(payable(address(this)));
+ address oldFallback = oldManager.eip4337Fallback();
+ require(pThis.isModuleEnabled(oldFallback), "replaceEIP4337Manager: oldManager is not active");
+ pThis.disableModule(oldFallback, oldManager.entryPoint());
+ pThis.disableModule(prevModule, oldFallback);
+
+ address eip4337fallback = newManager.eip4337Fallback();
+
+ pThis.enableModule(newManager.entryPoint());
+ pThis.enableModule(eip4337fallback);
+ pThis.setFallbackHandler(eip4337fallback);
+
+ validateEip4337(pThis, newManager);
+ }
+
+ /**
+ * Validate this gnosisSafe is callable through the EntryPoint.
+ * the test is might be incomplete: we check that we reach our validateUserOp and fail on signature.
+ * we don't test full transaction
+ */
+ function validateEip4337(GnosisSafe safe, EIP4337Manager manager) public {
+
+ // this prevents mistaken replaceEIP4337Manager to disable the module completely.
+ // minimal signature that pass "recover"
+ bytes memory sig = new bytes(65);
+ sig[64] = bytes1(uint8(27));
+ sig[2] = bytes1(uint8(1));
+ sig[35] = bytes1(uint8(1));
+ uint256 nonce = uint256(IEntryPoint(manager.entryPoint()).getNonce(address(safe), 0));
+ UserOperation memory userOp = UserOperation(address(safe), nonce, "", "", 0, 1000000, 0, 0, 0, "", sig);
+ UserOperation[] memory userOps = new UserOperation[](1);
+ userOps[0] = userOp;
+ IEntryPoint _entryPoint = IEntryPoint(payable(manager.entryPoint()));
+ try _entryPoint.handleOps(userOps, payable(msg.sender)) {
+ revert("validateEip4337: handleOps must fail");
+ } catch (bytes memory error) {
+ if (keccak256(error) != keccak256(abi.encodeWithSignature("FailedOp(uint256,string)", 0, "AA24 signature error"))) {
+ revert(string(error));
+ }
+ }
+ }
+ /**
+ * enumerate modules, and find the currently active EIP4337 manager (and previous module)
+ * @return prev prev module, needed by replaceEIP4337Manager
+ * @return manager the current active EIP4337Manager
+ */
+ function getCurrentEIP4337Manager(GnosisSafe safe) public view returns (address prev, address manager) {
+ prev = address(SENTINEL_MODULES);
+ (address[] memory modules,) = safe.getModulesPaginated(SENTINEL_MODULES, 100);
+ for (uint i = 0; i < modules.length; i++) {
+ address module = modules[i];
+ try EIP4337Fallback(module).eip4337manager() returns (address _manager) {
+ return (prev, _manager);
+ }
+ // solhint-disable-next-line no-empty-blocks
+ catch {}
+ prev = module;
+ }
+ return (address(0), address(0));
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/gnosis/GnosisAccountFactory.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/gnosis/GnosisAccountFactory.sol
new file mode 100644
index 00000000..459846a7
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/samples/gnosis/GnosisAccountFactory.sol
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "@openzeppelin/contracts/utils/Create2.sol";
+import "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol";
+import "./EIP4337Manager.sol";
+
+/**
+ * A wrapper factory contract to deploy GnosisSafe as an ERC-4337 account contract.
+ */
+contract GnosisSafeAccountFactory {
+
+ GnosisSafeProxyFactory public immutable proxyFactory;
+ address public immutable safeSingleton;
+ EIP4337Manager public immutable eip4337Manager;
+
+ constructor(GnosisSafeProxyFactory _proxyFactory, address _safeSingleton, EIP4337Manager _eip4337Manager) {
+ proxyFactory = _proxyFactory;
+ safeSingleton = _safeSingleton;
+ eip4337Manager = _eip4337Manager;
+ }
+
+ function createAccount(address owner,uint256 salt) public returns (address) {
+ address addr = getAddress(owner, salt);
+ uint codeSize = addr.code.length;
+ if (codeSize > 0) {
+ return addr;
+ }
+ return address(proxyFactory.createProxyWithNonce(
+ safeSingleton, getInitializer(owner), salt));
+ }
+
+ function getInitializer(address owner) internal view returns (bytes memory) {
+ address[] memory owners = new address[](1);
+ owners[0] = owner;
+ uint threshold = 1;
+ address eip4337fallback = eip4337Manager.eip4337Fallback();
+
+ bytes memory setup4337Modules = abi.encodeCall(
+ EIP4337Manager.setup4337Modules, (eip4337Manager));
+
+ return abi.encodeCall(GnosisSafe.setup, (
+ owners, threshold,
+ address (eip4337Manager), setup4337Modules,
+ eip4337fallback,
+ address(0), 0, payable(0) //no payment receiver
+ ));
+ }
+
+ /**
+ * calculate the counterfactual address of this account as it would be returned by createAccount()
+ * (uses the same "create2 signature" used by GnosisSafeProxyFactory.createProxyWithNonce)
+ */
+ function getAddress(address owner,uint256 salt) public view returns (address) {
+ bytes memory initializer = getInitializer(owner);
+ //copied from deployProxyWithNonce
+ bytes32 salt2 = keccak256(abi.encodePacked(keccak256(initializer), salt));
+ bytes memory deploymentData = abi.encodePacked(proxyFactory.proxyCreationCode(), uint256(uint160(safeSingleton)));
+ return Create2.computeAddress(bytes32(salt2), keccak256(deploymentData), address (proxyFactory));
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/BrokenBlsAccount.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/BrokenBlsAccount.sol
new file mode 100644
index 00000000..2e3cf2bc
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/BrokenBlsAccount.sol
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "@openzeppelin/contracts/utils/Create2.sol";
+import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
+
+import "../samples/SimpleAccount.sol";
+import "../samples/bls/IBLSAccount.sol";
+
+/**
+ * for testing: a BLS account that fails to return its public-key (completely ignores its publickey)
+ * this is a copy of the normal bls account, but it returns a public-key unrelated to the one it is constructed with.
+ */
+contract BrokenBLSAccount is SimpleAccount, IBLSAccount {
+ address public immutable aggregator;
+
+ // The constructor is used only for the "implementation" and only sets immutable values.
+ // Mutable values slots for proxy accounts are set by the 'initialize' function.
+ constructor(IEntryPoint anEntryPoint, address anAggregator) SimpleAccount(anEntryPoint) {
+ aggregator = anAggregator;
+ }
+
+ function initialize(uint256[4] memory aPublicKey) public virtual initializer {
+ (aPublicKey);
+ super._initialize(address(0));
+ }
+
+ function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)
+ internal override view returns (uint256 validationData) {
+
+ (userOp, userOpHash);
+ return _packValidationData(ValidationData(aggregator, 0,0));
+ }
+
+ function getBlsPublicKey() external override pure returns (uint256[4] memory) {
+ uint256[4] memory pubkey;
+ return pubkey;
+ }
+}
+
+
+/**
+ * Based n SimpleAccountFactory
+ * can't be a subclass, since both constructor and createAccount depend on the
+ * actual wallet contract constructor and initializer
+ */
+contract BrokenBLSAccountFactory {
+ BrokenBLSAccount public immutable accountImplementation;
+
+ constructor(IEntryPoint entryPoint, address aggregator){
+ accountImplementation = new BrokenBLSAccount(entryPoint, aggregator);
+ }
+
+ /**
+ * create an account, and return its address.
+ * returns the address even if the account is already deployed.
+ * Note that during UserOperation execution, this method is called only if the account is not deployed.
+ * This method returns an existing account address so that entryPoint.getSenderAddress() would work even after account creation
+ * Also note that out BLSSignatureAggregator requires that the public-key is the last parameter
+ */
+ function createAccount(uint salt, uint256[4] memory aPublicKey) public returns (BrokenBLSAccount) {
+
+ address addr = getAddress(salt, aPublicKey);
+ uint codeSize = addr.code.length;
+ if (codeSize > 0) {
+ return BrokenBLSAccount(payable(addr));
+ }
+ return BrokenBLSAccount(payable(new ERC1967Proxy{salt : bytes32(salt)}(
+ address(accountImplementation),
+ abi.encodeCall(BrokenBLSAccount.initialize, aPublicKey)
+ )));
+ }
+
+ /**
+ * calculate the counterfactual address of this account as it would be returned by createAccount()
+ */
+ function getAddress(uint salt, uint256[4] memory aPublicKey) public view returns (address) {
+ return Create2.computeAddress(bytes32(salt), keccak256(abi.encodePacked(
+ type(ERC1967Proxy).creationCode,
+ abi.encode(
+ address(accountImplementation),
+ abi.encodeCall(BrokenBLSAccount.initialize, (aPublicKey))
+ )
+ )));
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/MaliciousAccount.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/MaliciousAccount.sol
new file mode 100644
index 00000000..5b840e4f
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/MaliciousAccount.sol
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+import "../interfaces/IAccount.sol";
+import "../interfaces/IEntryPoint.sol";
+import "../core/EntryPoint.sol";
+
+contract MaliciousAccount is IAccount {
+ IEntryPoint private ep;
+ constructor(IEntryPoint _ep) payable {
+ ep = _ep;
+ }
+ function validateUserOp(UserOperation calldata userOp, bytes32, uint256 missingAccountFunds)
+ external returns (uint256 validationData) {
+ ep.depositTo{value : missingAccountFunds}(address(this));
+ // Now calculate basefee per EntryPoint.getUserOpGasPrice() and compare it to the basefe we pass off-chain in the signature
+ uint256 externalBaseFee = abi.decode(userOp.signature, (uint256));
+ uint256 requiredGas = userOp.callGasLimit + userOp.verificationGasLimit + userOp.preVerificationGas;
+ uint256 gasPrice = missingAccountFunds / requiredGas;
+ uint256 basefee = gasPrice - userOp.maxPriorityFeePerGas;
+ require (basefee == externalBaseFee, "Revert after first validation");
+ return 0;
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestAggregatedAccount.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestAggregatedAccount.sol
new file mode 100644
index 00000000..23bf2954
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestAggregatedAccount.sol
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "../samples/SimpleAccount.sol";
+
+/**
+ * test aggregated-signature account.
+ * works only with TestAggregatedSignature, which doesn't really check signature, but nonce sum
+ * a true aggregated account should expose data (e.g. its public key) to the aggregator.
+ */
+contract TestAggregatedAccount is SimpleAccount {
+ address public immutable aggregator;
+
+ // The constructor is used only for the "implementation" and only sets immutable values.
+ // Mutable value slots for proxy accounts are set by the 'initialize' function.
+ constructor(IEntryPoint anEntryPoint, address anAggregator) SimpleAccount(anEntryPoint) {
+ aggregator = anAggregator;
+ }
+
+ /// @inheritdoc SimpleAccount
+ function initialize(address) public virtual override initializer {
+ super._initialize(address(0));
+ }
+
+ function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)
+ internal override view returns (uint256 validationData) {
+ (userOp, userOpHash);
+ return _packValidationData(ValidationData(aggregator, 0, 0));
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestAggregatedAccountFactory.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestAggregatedAccountFactory.sol
new file mode 100644
index 00000000..edaba58c
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestAggregatedAccountFactory.sol
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "@openzeppelin/contracts/utils/Create2.sol";
+import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
+
+import "./TestAggregatedAccount.sol";
+
+/**
+ * Based on SimpleAccountFactory.
+ * Cannot be a subclass since both constructor and createAccount depend on the
+ * constructor and initializer of the actual account contract.
+ */
+contract TestAggregatedAccountFactory {
+ TestAggregatedAccount public immutable accountImplementation;
+
+ constructor(IEntryPoint anEntryPoint, address anAggregator){
+ accountImplementation = new TestAggregatedAccount(anEntryPoint, anAggregator);
+ }
+
+ /**
+ * create an account, and return its address.
+ * returns the address even if the account is already deployed.
+ * Note that during UserOperation execution, this method is called only if the account is not deployed.
+ * This method returns an existing account address so that entryPoint.getSenderAddress() would work even after account creation
+ */
+ function createAccount(address owner,uint256 salt) public returns (TestAggregatedAccount ret) {
+ address addr = getAddress(owner, salt);
+ uint codeSize = addr.code.length;
+ if (codeSize > 0) {
+ return TestAggregatedAccount(payable(addr));
+ }
+ ret = TestAggregatedAccount(payable(new ERC1967Proxy{salt : bytes32(salt)}(
+ address(accountImplementation),
+ abi.encodeCall(TestAggregatedAccount.initialize, (owner))
+ )));
+ }
+
+ /**
+ * calculate the counterfactual address of this account as it would be returned by createAccount()
+ */
+ function getAddress(address owner,uint256 salt) public view returns (address) {
+ return Create2.computeAddress(bytes32(salt), keccak256(abi.encodePacked(
+ type(ERC1967Proxy).creationCode,
+ abi.encode(
+ address(accountImplementation),
+ abi.encodeCall(TestAggregatedAccount.initialize, (owner))
+ )
+ )));
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestCounter.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestCounter.sol
new file mode 100644
index 00000000..0ac2c888
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestCounter.sol
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+//sample "receiver" contract, for testing "exec" from account.
+contract TestCounter {
+ mapping(address => uint256) public counters;
+
+ function count() public {
+ counters[msg.sender] = counters[msg.sender] + 1;
+ }
+
+ function countFail() public pure {
+ revert("count failed");
+ }
+
+ function justemit() public {
+ emit CalledFrom(msg.sender);
+ }
+
+ event CalledFrom(address sender);
+
+ //helper method to waste gas
+ // repeat - waste gas on writing storage in a loop
+ // junk - dynamic buffer to stress the function size.
+ mapping(uint256 => uint256) public xxx;
+ uint256 public offset;
+
+ function gasWaster(uint256 repeat, string calldata /*junk*/) external {
+ for (uint256 i = 1; i <= repeat; i++) {
+ offset++;
+ xxx[offset] = i;
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestExpirePaymaster.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestExpirePaymaster.sol
new file mode 100644
index 00000000..e7166b20
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestExpirePaymaster.sol
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-3.0-only
+pragma solidity ^0.8.12;
+
+import "../core/BasePaymaster.sol";
+
+/**
+ * test expiry mechanism: paymasterData encodes the "validUntil" and validAfter" times
+ */
+contract TestExpirePaymaster is BasePaymaster {
+ // solhint-disable no-empty-blocks
+ constructor(IEntryPoint _entryPoint) BasePaymaster(_entryPoint, msg.sender)
+ {}
+
+ function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
+ internal virtual override view
+ returns (bytes memory context, uint256 validationData) {
+ (userOp, userOpHash, maxCost);
+ (uint48 validAfter, uint48 validUntil) = abi.decode(userOp.paymasterAndData[20 :], (uint48, uint48));
+ validationData = _packValidationData(false, validUntil, validAfter);
+ context = "";
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestExpiryAccount.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestExpiryAccount.sol
new file mode 100644
index 00000000..4228bfeb
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestExpiryAccount.sol
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-3.0-only
+pragma solidity ^0.8.12;
+
+import "../samples/SimpleAccount.sol";
+
+/**
+ * A test account, for testing expiry.
+ * add "temporary" owners, each with a time range (since..till) times for each.
+ * NOTE: this is not a full "session key" implementation: a real session key should probably limit
+ * other things, like target contracts and methods to be called.
+ * also, the "since" value is not really useful, only for testing the entrypoint.
+ */
+contract TestExpiryAccount is SimpleAccount {
+ using ECDSA for bytes32;
+ using MessageHashUtils for bytes32;
+
+ mapping(address => uint48) public ownerAfter;
+ mapping(address => uint48) public ownerUntil;
+
+ // solhint-disable-next-line no-empty-blocks
+ constructor(IEntryPoint anEntryPoint) SimpleAccount(anEntryPoint) {}
+
+ function initialize(address anOwner) public virtual override initializer {
+ super._initialize(anOwner);
+ addTemporaryOwner(anOwner, 0, type(uint48).max);
+ }
+
+ // As this is a test contract, no need for proxy, so no need to disable init
+ // solhint-disable-next-line no-empty-blocks
+ function _disableInitializers() internal override {}
+
+ function addTemporaryOwner(address owner, uint48 _after, uint48 _until) public onlyOwner {
+ require(_until > _after, "wrong until/after");
+ ownerAfter[owner] = _after;
+ ownerUntil[owner] = _until;
+ }
+
+ /// implement template method of BaseAccount
+ function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)
+ internal override view returns (uint256 validationData) {
+ bytes32 hash = userOpHash.toEthSignedMessageHash();
+ address signer = hash.recover(userOp.signature);
+ uint48 _until = ownerUntil[signer];
+ uint48 _after = ownerAfter[signer];
+
+ //we have "until" value for all valid owners. so zero means "invalid signature"
+ bool sigFailed = _until == 0;
+ return _packValidationData(sigFailed, _until, _after);
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestHelpers.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestHelpers.sol
new file mode 100644
index 00000000..2ddb83c7
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestHelpers.sol
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "../core/Helpers.sol";
+
+contract TestHelpers {
+
+ function parseValidationData(uint validationData) public pure returns (ValidationData memory) {
+ return _parseValidationData(validationData);
+ }
+
+ function intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) public pure returns (ValidationData memory) {
+ return _intersectTimeRange(validationData, paymasterValidationData);
+ }
+
+ function packValidationDataStruct(ValidationData memory data) public pure returns (uint256) {
+ return _packValidationData(data);
+ }
+
+ function packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) public pure returns (uint256) {
+ return _packValidationData(sigFailed, validUntil, validAfter);
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestOracle.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestOracle.sol
new file mode 100644
index 00000000..e7d11f16
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestOracle.sol
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "../samples/IOracle.sol";
+
+contract TestOracle is IOracle {
+ function getTokenValueOfEth(uint256 ethOutput) external pure override returns (uint256 tokenInput) {
+ return ethOutput * 2;
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestPaymasterAcceptAll.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestPaymasterAcceptAll.sol
new file mode 100644
index 00000000..1b1e825a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestPaymasterAcceptAll.sol
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-3.0-only
+pragma solidity ^0.8.12;
+
+import "../core/BasePaymaster.sol";
+
+/**
+ * test paymaster, that pays for everything, without any check.
+ */
+contract TestPaymasterAcceptAll is BasePaymaster {
+
+ constructor(IEntryPoint _entryPoint) BasePaymaster(_entryPoint, msg.sender) {
+ // to support "deterministic address" factory
+ // solhint-disable avoid-tx-origin
+ if (tx.origin != msg.sender) {
+ _transferOwnership(tx.origin);
+ }
+
+ }
+
+ function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
+ internal virtual override view
+ returns (bytes memory context, uint256 validationData) {
+ (userOp, userOpHash, maxCost);
+ return ("", maxCost == 12345 ? 1 : 0);
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestRevertAccount.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestRevertAccount.sol
new file mode 100644
index 00000000..d7c376c4
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestRevertAccount.sol
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-3.0-only
+pragma solidity ^0.8.12;
+/* solhint-disable no-inline-assembly */
+
+import "../samples/SimpleAccount.sol";
+contract TestRevertAccount is IAccount {
+ IEntryPoint private ep;
+ constructor(IEntryPoint _ep) payable {
+ ep = _ep;
+ }
+
+ function validateUserOp(UserOperation calldata, bytes32, uint256 missingAccountFunds)
+ external override returns (uint256 validationData) {
+ ep.depositTo{value : missingAccountFunds}(address(this));
+ return 0;
+ }
+
+ function revertLong(uint256 length) public pure{
+ assembly {
+ revert(0, length)
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestSignatureAggregator.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestSignatureAggregator.sol
new file mode 100644
index 00000000..97b9eb5f
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestSignatureAggregator.sol
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+/* solhint-disable reason-string */
+
+import "../interfaces/IAggregator.sol";
+import "../interfaces/IEntryPoint.sol";
+import "../samples/SimpleAccount.sol";
+
+/**
+ * test signature aggregator.
+ * the aggregated signature is the SUM of the nonce fields..
+ */
+contract TestSignatureAggregator is IAggregator {
+
+ /// @inheritdoc IAggregator
+ function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external pure override {
+ uint sum = 0;
+ for (uint i = 0; i < userOps.length; i++) {
+ uint nonce = userOps[i].nonce;
+ sum += nonce;
+ }
+ require(signature.length == 32, "TestSignatureValidator: sig must be uint");
+ (uint sig) = abi.decode(signature, (uint));
+ require(sig == sum, "TestSignatureValidator: aggregated signature mismatch (nonce sum)");
+ }
+
+ /// @inheritdoc IAggregator
+ function validateUserOpSignature(UserOperation calldata)
+ external pure returns (bytes memory) {
+ return "";
+ }
+
+ /**
+ * dummy test aggregator: sum all nonce values of UserOps.
+ */
+ function aggregateSignatures(UserOperation[] calldata userOps) external pure returns (bytes memory aggregatedSignature) {
+ uint sum = 0;
+ for (uint i = 0; i < userOps.length; i++) {
+ sum += userOps[i].nonce;
+ }
+ return abi.encode(sum);
+ }
+
+ /**
+ * Calls the 'addStake' method of the EntryPoint. Forwards the entire msg.value to this call.
+ * @param entryPoint - the EntryPoint to send the stake to.
+ * @param delay - the new lock duration before the deposit can be withdrawn.
+ */
+ function addStake(IEntryPoint entryPoint, uint32 delay) external payable {
+ entryPoint.addStake{value: msg.value}(delay);
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestToken.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestToken.sol
new file mode 100644
index 00000000..41997b71
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestToken.sol
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
+
+contract TestToken is ERC20 {
+ constructor ()
+ // solhint-disable-next-line no-empty-blocks
+ ERC20("TST", "TestToken") {
+ }
+
+ function mint(address sender, uint256 amount) external {
+ _mint(sender, amount);
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestUtil.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestUtil.sol
new file mode 100644
index 00000000..0372ee8e
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestUtil.sol
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-3.0
+pragma solidity ^0.8.12;
+
+import "../interfaces/UserOperation.sol";
+
+contract TestUtil {
+ using UserOperationLib for UserOperation;
+
+ function packUserOp(UserOperation calldata op) external pure returns (bytes memory){
+ return op.pack();
+ }
+
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestWarmColdAccount.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestWarmColdAccount.sol
new file mode 100644
index 00000000..76f35bc8
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/test/TestWarmColdAccount.sol
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-3.0-only
+pragma solidity ^0.8.12;
+/* solhint-disable no-inline-assembly */
+
+import "../interfaces/IEntryPoint.sol";
+import "../interfaces/IAccount.sol";
+
+// Using eip-2929 (https://eips.ethereum.org/EIPS/eip-2929) warm/cold storage access gas costs to detect simulation vs execution
+// COLD_ACCOUNT_ACCESS_COST == 2600, COLD_SLOAD_COST == 2100, WARM_STORAGE_READ_COST == 100
+contract TestWarmColdAccount is IAccount {
+ IEntryPoint private ep;
+ uint public state = 1;
+ constructor(IEntryPoint _ep) payable {
+ ep = _ep;
+ }
+
+ function validateUserOp(UserOperation calldata userOp, bytes32, uint256 missingAccountFunds)
+ external override returns (uint256 validationData) {
+ ep.depositTo{value : missingAccountFunds}(address(this));
+ if (userOp.nonce == 1) {
+ // can only succeed if storage is already warm
+ this.touchStorage{gas: 1000}();
+ } else if (userOp.nonce == 2) {
+ address paymaster = address(bytes20(userOp.paymasterAndData[: 20]));
+ // can only succeed if storage is already warm
+ this.touchPaymaster{gas: 1000}(paymaster);
+ }
+ return 0;
+ }
+
+ function touchStorage() public view returns (uint256) {
+ return state;
+ }
+
+ function touchPaymaster(address paymaster) public view returns (uint256) {
+ return paymaster.code.length;
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/contracts/utils/Exec.sol b/lib/SoulWalletCore/lib/account-abstraction/contracts/utils/Exec.sol
new file mode 100644
index 00000000..69d653d9
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/contracts/utils/Exec.sol
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: LGPL-3.0-only
+pragma solidity >=0.7.5 <0.9.0;
+
+// solhint-disable no-inline-assembly
+
+/**
+ * Utility functions helpful when making different kinds of contract calls in Solidity.
+ */
+library Exec {
+
+ function call(
+ address to,
+ uint256 value,
+ bytes memory data,
+ uint256 txGas
+ ) internal returns (bool success) {
+ assembly {
+ success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)
+ }
+ }
+
+ function staticcall(
+ address to,
+ bytes memory data,
+ uint256 txGas
+ ) internal view returns (bool success) {
+ assembly {
+ success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)
+ }
+ }
+
+ function delegateCall(
+ address to,
+ bytes memory data,
+ uint256 txGas
+ ) internal returns (bool success) {
+ assembly {
+ success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)
+ }
+ }
+
+ // get returned data from last call or calldelegate
+ function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {
+ assembly {
+ let len := returndatasize()
+ if gt(len, maxLen) {
+ len := maxLen
+ }
+ let ptr := mload(0x40)
+ mstore(0x40, add(ptr, add(len, 0x20)))
+ mstore(ptr, len)
+ returndatacopy(add(ptr, 0x20), 0, len)
+ returnData := ptr
+ }
+ }
+
+ // revert with explicit byte array (probably reverted info from call)
+ function revertWithData(bytes memory returnData) internal pure {
+ assembly {
+ revert(add(returnData, 32), mload(returnData))
+ }
+ }
+
+ function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {
+ bool success = call(to,0,data,gasleft());
+ if (!success) {
+ revertWithData(getReturnData(maxLen));
+ }
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deploy/1_deploy_entrypoint.ts b/lib/SoulWalletCore/lib/account-abstraction/deploy/1_deploy_entrypoint.ts
new file mode 100644
index 00000000..4c0e7b0e
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deploy/1_deploy_entrypoint.ts
@@ -0,0 +1,39 @@
+import { HardhatRuntimeEnvironment } from 'hardhat/types'
+import { DeployFunction } from 'hardhat-deploy/types'
+import { Create2Factory } from '../src/Create2Factory'
+import { ethers } from 'hardhat'
+
+const deployEntryPoint: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
+ const provider = ethers.provider
+ const from = await provider.getSigner().getAddress()
+ await new Create2Factory(ethers.provider).deployFactory()
+
+ const ret = await hre.deployments.deploy(
+ 'EntryPoint', {
+ from,
+ args: [],
+ gasLimit: 6e6,
+ deterministicDeployment: true
+ })
+ console.log('==entrypoint addr=', ret.address)
+/*
+ const entryPointAddress = ret.address
+ const w = await hre.deployments.deploy(
+ 'SimpleAccount', {
+ from,
+ args: [entryPointAddress, from],
+ gasLimit: 2e6,
+ deterministicDeployment: true
+ })
+
+ console.log('== wallet=', w.address)
+
+ const t = await hre.deployments.deploy('TestCounter', {
+ from,
+ deterministicDeployment: true
+ })
+ console.log('==testCounter=', t.address)
+ */
+}
+
+export default deployEntryPoint
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deploy/2_deploy_SimpleAccountFactory.ts b/lib/SoulWalletCore/lib/account-abstraction/deploy/2_deploy_SimpleAccountFactory.ts
new file mode 100644
index 00000000..33b81aec
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deploy/2_deploy_SimpleAccountFactory.ts
@@ -0,0 +1,26 @@
+import { HardhatRuntimeEnvironment } from 'hardhat/types'
+import { DeployFunction } from 'hardhat-deploy/types'
+import { ethers } from 'hardhat'
+
+const deploySimpleAccountFactory: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
+ const provider = ethers.provider
+ const from = await provider.getSigner().getAddress()
+ const network = await provider.getNetwork()
+ // only deploy on local test network.
+ if (network.chainId !== 31337 && network.chainId !== 1337) {
+ return
+ }
+
+ const entrypoint = await hre.deployments.get('EntryPoint')
+ const ret = await hre.deployments.deploy(
+ 'SimpleAccountFactory', {
+ from,
+ args: [entrypoint.address],
+ gasLimit: 6e6,
+ log: true,
+ deterministicDeployment: true
+ })
+ console.log('==SimpleAccountFactory addr=', ret.address)
+}
+
+export default deploySimpleAccountFactory
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/arbitrum/.chainId b/lib/SoulWalletCore/lib/account-abstraction/deployments/arbitrum/.chainId
new file mode 100644
index 00000000..7df83ecb
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/arbitrum/.chainId
@@ -0,0 +1 @@
+42161
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/arbitrum/EntryPoint.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/arbitrum/EntryPoint.json
new file mode 100644
index 00000000..916c2390
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/arbitrum/EntryPoint.json
@@ -0,0 +1,1318 @@
+{
+ "address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "paid",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bool",
+ "name": "targetSuccess",
+ "type": "bool"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetResult",
+ "type": "bytes"
+ }
+ ],
+ "name": "ExecutionResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "opIndex",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "reason",
+ "type": "string"
+ }
+ ],
+ "name": "FailedOp",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "SenderAddressResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureValidationFailed",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "stakeInfo",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IEntryPoint.AggregatorStakeInfo",
+ "name": "aggregatorInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResultWithAggregation",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "factory",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ }
+ ],
+ "name": "AccountDeployed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "BeforeExecution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalDeposit",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposited",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureAggregatorChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalStaked",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeLocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "withdrawTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeUnlocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeWithdrawn",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "success",
+ "type": "bool"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasUsed",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserOperationEvent",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "revertReason",
+ "type": "bytes"
+ }
+ ],
+ "name": "UserOperationRevertReason",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawn",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "SIG_VALIDATION_FAILED",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ }
+ ],
+ "name": "_validateSenderAndPaymaster",
+ "outputs": [],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ }
+ ],
+ "name": "addStake",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deposits",
+ "outputs": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "getDepositInfo",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "internalType": "struct IStakeManager.DepositInfo",
+ "name": "info",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "getNonce",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ }
+ ],
+ "name": "getSenderAddress",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "getUserOpHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "userOps",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "contract IAggregator",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.UserOpsPerAggregator[]",
+ "name": "opsPerAggregator",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleAggregatedOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "ops",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "incrementNonce",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.MemoryUserOp",
+ "name": "mUserOp",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "contextOffset",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.UserOpInfo",
+ "name": "opInfo",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes",
+ "name": "context",
+ "type": "bytes"
+ }
+ ],
+ "name": "innerHandleOp",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "",
+ "type": "uint192"
+ }
+ ],
+ "name": "nonceSequenceNumber",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "op",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetCallData",
+ "type": "bytes"
+ }
+ ],
+ "name": "simulateHandleOp",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "simulateValidation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unlockStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ }
+ ],
+ "name": "withdrawStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "withdrawAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdrawTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "args": [],
+ "numDeployments": 1,
+ "solcInputHash": "a4c52f0671aad8941c53d6ead2063803",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"targetSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"targetResult\",\"type\":\"bytes\"}],\"name\":\"ExecutionResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"opIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"FailedOp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderAddressResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureValidationFailed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResult\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"type\":\"tuple\"}],\"internalType\":\"struct IEntryPoint.AggregatorStakeInfo\",\"name\":\"aggregatorInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResultWithAggregation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"}],\"name\":\"AccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"BeforeExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalDeposit\",\"type\":\"uint256\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureAggregatorChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStaked\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"name\":\"StakeLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"StakeWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasUsed\",\"type\":\"uint256\"}],\"name\":\"UserOperationEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"revertReason\",\"type\":\"bytes\"}],\"name\":\"UserOperationRevertReason\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SIG_VALIDATION_FAILED\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"}],\"name\":\"_validateSenderAndPaymaster\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"}],\"name\":\"addStake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getDepositInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"internalType\":\"struct IStakeManager.DepositInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"getSenderAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"getUserOpHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"userOps\",\"type\":\"tuple[]\"},{\"internalType\":\"contract IAggregator\",\"name\":\"aggregator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.UserOpsPerAggregator[]\",\"name\":\"opsPerAggregator\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleAggregatedOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"incrementNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.MemoryUserOp\",\"name\":\"mUserOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contextOffset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.UserOpInfo\",\"name\":\"opInfo\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"name\":\"innerHandleOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"name\":\"nonceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCallData\",\"type\":\"bytes\"}],\"name\":\"simulateHandleOp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"simulateValidation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"}],\"name\":\"withdrawStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"withdrawAmount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"FailedOp(uint256,string)\":[{\"params\":{\"opIndex\":\"- index into the array of ops to the failed one (in simulateValidation, this is always zero)\",\"reason\":\"- revert reason The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues, so a failure can be attributed to the correct entity. Should be caught in off-chain handleOps simulation and not happen on-chain. Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\"}}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"params\":{\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"params\":{\"aggregatorInfo\":\"signature aggregation info (if the account requires signature aggregator) bundler MUST use it to verify the signature, or reject the UserOperation\",\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}]},\"kind\":\"dev\",\"methods\":{\"addStake(uint32)\":{\"params\":{\"unstakeDelaySec\":\"the new lock duration before the deposit can be withdrawn.\"}},\"getDepositInfo(address)\":{\"returns\":{\"info\":\"- full deposit information of given account\"}},\"getNonce(address,uint192)\":{\"params\":{\"key\":\"the high 192 bit of the nonce\",\"sender\":\"the account address\"},\"returns\":{\"nonce\":\"a full nonce to pass for next UserOp with this sender.\"}},\"getSenderAddress(bytes)\":{\"params\":{\"initCode\":\"the constructor code to be passed into the UserOperation.\"}},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"opsPerAggregator\":\"the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\"}},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"ops\":\"the operations to execute\"}},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"params\":{\"op\":\"the UserOperation to simulate\",\"target\":\"if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult are set to the return from that call.\",\"targetCallData\":\"callData to pass to target address\"}},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"details\":\"this method always revert. Successful result is ValidationResult error. other errors are failures.The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\",\"params\":{\"userOp\":\"the user operation to validate.\"}},\"withdrawStake(address)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\"}},\"withdrawTo(address,uint256)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\",\"withdrawAmount\":\"the amount to withdraw.\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"ExecutionResult(uint256,uint256,uint48,uint48,bool,bytes)\":[{\"notice\":\"return value of simulateHandleOp\"}],\"FailedOp(uint256,string)\":[{\"notice\":\"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.\"}],\"SenderAddressResult(address)\":[{\"notice\":\"return value of getSenderAddress\"}],\"SignatureValidationFailed(address)\":[{\"notice\":\"error case when a signature aggregator fails to verify the aggregated signature it had created.\"}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"notice\":\"Successful result from simulateValidation.\"}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"notice\":\"Successful result from simulateValidation, if the account returns a signature aggregator\"}]},\"events\":{\"AccountDeployed(bytes32,address,address,address)\":{\"notice\":\"account \\\"sender\\\" was deployed.\"},\"BeforeExecution()\":{\"notice\":\"an event emitted by handleOps(), before starting the execution loop. any event emitted before this event, is part of the validation.\"},\"SignatureAggregatorChanged(address)\":{\"notice\":\"signature aggregator used by the following UserOperationEvents within this bundle.\"},\"StakeLocked(address,uint256,uint256)\":{\"notice\":\"Emitted when stake or unstake delay are modified\"},\"StakeUnlocked(address,uint256)\":{\"notice\":\"Emitted once a stake is scheduled for withdrawal\"},\"UserOperationRevertReason(bytes32,address,uint256,bytes)\":{\"notice\":\"An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\"}},\"kind\":\"user\",\"methods\":{\"SIG_VALIDATION_FAILED()\":{\"notice\":\"for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value in case of signature failure, instead of revert.\"},\"_validateSenderAndPaymaster(bytes,address,bytes)\":{\"notice\":\"Called only during simulation. This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\"},\"addStake(uint32)\":{\"notice\":\"add to the account's stake - amount and delay any pending unstake is first cancelled.\"},\"balanceOf(address)\":{\"notice\":\"return the deposit (for gas payment) of the account\"},\"depositTo(address)\":{\"notice\":\"add to the deposit of the given account\"},\"deposits(address)\":{\"notice\":\"maps paymaster to their deposits and stakes\"},\"getNonce(address,uint192)\":{\"notice\":\"Return the next nonce for this sender. Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) But UserOp with different keys can come with arbitrary order.\"},\"getSenderAddress(bytes)\":{\"notice\":\"Get counterfactual sender address. Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. this method always revert, and returns the address in SenderAddressResult error\"},\"getUserOpHash((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"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.\"},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperation with Aggregators\"},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperations. no signature aggregator is used. if any account requires an aggregator (that is, it returned an aggregator when performing simulateValidation), then handleAggregatedOps() must be used instead.\"},\"incrementNonce(uint192)\":{\"notice\":\"Manually increment the nonce of the sender. This method is exposed just for completeness.. Account does NOT need to call it, neither during validation, nor elsewhere, as the EntryPoint will update the nonce regardless. Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future UserOperations will not pay extra for the first transaction with a given key.\"},\"innerHandleOp(bytes,((address,uint256,uint256,uint256,uint256,address,uint256,uint256),bytes32,uint256,uint256,uint256),bytes)\":{\"notice\":\"inner function to handle a UserOperation. Must be declared \\\"external\\\" to open a call context, but it can only be called by handleOps.\"},\"nonceSequenceNumber(address,uint192)\":{\"notice\":\"The next valid sequence number for a given nonce key.\"},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"notice\":\"simulate full execution of a UserOperation (including both validation and target execution) this method will always revert with \\\"ExecutionResult\\\". it performs full validation of the UserOperation, but ignores signature error. an optional target address is called after the userop succeeds, and its value is returned (before the entire call is reverted) Note that in order to collect the the success/failure of the target call, it must be executed with trace enabled to track the emitted events.\"},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\"},\"unlockStake()\":{\"notice\":\"attempt to unlock the stake. the value can be withdrawn (using withdrawStake) after the unstake delay.\"},\"withdrawStake(address)\":{\"notice\":\"withdraw from the (unlocked) stake. must first call unlockStake and wait for the unstakeDelay to pass\"},\"withdrawTo(address,uint256)\":{\"notice\":\"withdraw from the deposit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/core/EntryPoint.sol\":\"EntryPoint\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0x190dd6f8d592b7e4e930feb7f4313aeb8e1c4ad3154c27ce1cf6a512fc30d8cc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ce8dfb62d0c4fa260d6eec8f1cd47f5f2a044e11bde5b31d18072fa6e7d9010\",\"dweb:/ipfs/QmTyFztU3tLEcEDnqqiaW4UJetqsU77LXc6pjc9oTXCK5u\"]},\"contracts/core/EntryPoint.sol\":{\"keccak256\":\"0x04f86318b47f052d7308795ffae6ecec0d023d2458b4e17751b89a0e4acfcdc6\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://c9f6e359c8dbe875ad974d3a0fb7b3d62319a6b115c44bac1e4587ae2ad2edaf\",\"dweb:/ipfs/QmTSWTov2rUeYk8cwzrtsd3uVXokCYok4gMiZ1sPs9tycH\"]},\"contracts/core/Helpers.sol\":{\"keccak256\":\"0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746\",\"dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU\"]},\"contracts/core/NonceManager.sol\":{\"keccak256\":\"0xa17a4a6fde70088ab18ffe6df830f3efa31f1cd0e1a7160336c96e3c94984d25\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://b38615df9f80c56282b72888e9ba1eb1a9413fa67a0dbf094deda7af9feb38e7\",\"dweb:/ipfs/QmSzcXetEJRH4UHuUmZiSgX6bFgfqHWfmyuxVnh4NosMk1\"]},\"contracts/core/SenderCreator.sol\":{\"keccak256\":\"0x44b9449fec82d6cdfb01d52fdd5a72f90099c651316123810cf9633f00b018c2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a9c0487390e72638681d175c45bc92425c802fffdca4bd0ae8457782ee284612\",\"dweb:/ipfs/QmVbzuehCUWJWqEHyMWuc6cRVbxfcMdFsmGL9o4Wz7WY2x\"]},\"contracts/core/StakeManager.sol\":{\"keccak256\":\"0x21aa0956382bd000b1b8c3b1d19ca6ebcd6c9029eebb19c612fb38ee5dd2430a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0a625c8795354d9f429367f9c1d14eb8af7db9c7f2c2a2033e2066ced76a573a\",\"dweb:/ipfs/Qmd1j6UarUg54q1G2HCNCLQz8XGVZR1qxX7eQ6cytHpQPN\"]},\"contracts/interfaces/IAccount.sol\":{\"keccak256\":\"0x556a0e5980de18e90b115553ed502408155ba35f58642823010d9288047bc418\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a0f420134b79596db8737173c7b933ae0a33059e107b6327c43aa40d4744a9e4\",\"dweb:/ipfs/QmRo8s1AhXmEMV7uPYnbpYwU19e9Bk6jmYBJTiPx3Fo85W\"]},\"contracts/interfaces/IAggregator.sol\":{\"keccak256\":\"0x060e9ddb0152250c269ba0640dc5753834ac44cf182a2837d508c0c529cae26a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://20ed837bc5909c89ff1910246bf245a5dad6840aa939382e1694964eb7dbd37b\",\"dweb:/ipfs/QmTMybRq5yyghPDDs1ZCNAVB9sSJ4WHe6Q9mejuKPTAdNP\"]},\"contracts/interfaces/IEntryPoint.sol\":{\"keccak256\":\"0x3a90bf308819ed125fa4202f880999caff8a8686633b8ddb79a30ca240d5b8f8\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://d2d21cc92c2fdab2b58d21bc25d4cd0e8c284b922528a186b087b818d54bc6cf\",\"dweb:/ipfs/QmT1qrfuBjsv2rmRCDn8mgPXHp94hARJwzbcDuBLDTbFWd\"]},\"contracts/interfaces/INonceManager.sol\":{\"keccak256\":\"0x509871e6c63663cdcc3eba19920fe84e991f38b289b1377ac3c3a6d9f22d7e12\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://00fe21b4349b24c50df60e1a705179293982bd9e7a32b78d4bac9620f89e7fe2\",\"dweb:/ipfs/QmSFFYGfUwQbVa6hASjU7YxTvgi2HkfrPr4X5oPHscHg8b\"]},\"contracts/interfaces/IPaymaster.sol\":{\"keccak256\":\"0x36858ba8685024974f533530420688da3454d29996ebc42e410673a1ed2ec456\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://616cbcf51778b1961b7f20a547bec7efae6d1d565df0f651926241ed8bde9ad8\",\"dweb:/ipfs/QmaVsgffUUmeUJYgStvRr8cNZ1LBbrc3FYNLW4JT1dVLia\"]},\"contracts/interfaces/IStakeManager.sol\":{\"keccak256\":\"0xd227b02888cd4ac68daebcdfd992ec00f9fff66fa3b3bb16f656cd582fa3480f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://b389da4714a138be63704a576a482505eab2855e263b38a93706395d8d42e7c3\",\"dweb:/ipfs/QmeeAZpdHwUXxqP8pxA7GNtoCGBmmH4FaqLLwScVKGxtxZ\"]},\"contracts/interfaces/UserOperation.sol\":{\"keccak256\":\"0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c\",\"dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN\"]},\"contracts/utils/Exec.sol\":{\"keccak256\":\"0x5b232117afbc2939f3ffc92745614867e9e1d475a3e1e5443adae13c200174f1\",\"license\":\"LGPL-3.0-only\",\"urls\":[\"bzz-raw://62e7365379a06ead7b47637945bcaee095d51aab1d3ac00ddec69443e6cbe9fe\",\"dweb:/ipfs/QmctG3aw4U3KMSMeJKoLJ1NJewjMWfppnd1m3kxNTe39Uy\"]}},\"version\":1}",
+ "bytecode": "0x60a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033",
+ "deployedBytecode": "0x60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c63430008110033"
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/arbitrum/solcInputs/a4c52f0671aad8941c53d6ead2063803.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/arbitrum/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
new file mode 100644
index 00000000..dd58ba5a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/arbitrum/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
@@ -0,0 +1,68 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts/security/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n"
+ },
+ "contracts/core/EntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard {\n\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success,) = beneficiary.call{value : amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) public nonReentrant {\n\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(address(aggregator) != address(1), \"AA96 invalid aggregator\");\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {}\n catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {\n\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);\n }\n\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {\n return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(paymasterAndData.length >= 20, \"AA93 invalid paymasterAndData\");\n mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,\n sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));\n revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);\n }\n revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);\n\n }\n\n function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0) revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);\n if (sender1 == address(0)) revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender) revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0) revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0 : 20]));\n emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(UserOperation calldata userOp) internal view {\n // solhint-disable-next-line no-empty-blocks\n try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}\n catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0 : 20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)\n internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;\n }\n try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA23 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)\n internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(verificationGasLimit > gasUsedByValidateAccountPrepayment, \"AA41 too little verificationGas\");\n uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA33 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)\n private returns (uint256 validationData, uint256 paymasterValidationData) {\n\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |\n userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);\n (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}\n catch Error(string memory reason) {\n revert FailedOp(opIndex, string.concat(\"AA50 postOp reverted: \", reason));\n }\n catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {\n assembly {offset := data}\n }\n\n function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {\n assembly {data := offset}\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {mstore(0, number())}\n }\n}\n\n"
+ },
+ "contracts/core/Helpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\n struct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n }\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n// intersect account and paymaster ranges.\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(validationData);\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n }\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n }\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\n function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n }\n\n"
+ },
+ "contracts/core/NonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(address sender, uint192 key)\n public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(address sender, uint256 nonce) internal returns (bool) {\n\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n\n}\n"
+ },
+ "contracts/core/SenderCreator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(bytes calldata initCode) external returns (address sender) {\n address factory = address(bytes20(initCode[0 : 20]));\n bytes memory initCallData = initCode[20 :];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n"
+ },
+ "contracts/core/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(address account) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(unstakeDelaySec >= info.unstakeDelaySec, \"cannot decrease unstake time\");\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(info.withdrawTime <= block.timestamp, \"Stake withdrawal is not due\");\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success,) = withdrawAddress.call{value : stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success,) = withdrawAddress.call{value : withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n"
+ },
+ "contracts/interfaces/IAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external returns (uint256 validationData);\n}\n"
+ },
+ "contracts/interfaces/IAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\n}\n"
+ },
+ "contracts/interfaces/IEntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo);\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n\n"
+ },
+ "contracts/interfaces/INonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(address sender, uint192 key)\n external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n"
+ },
+ "contracts/interfaces/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;\n}\n"
+ },
+ "contracts/interfaces/IStakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n\n event Deposited(\n address indexed account,\n uint256 totalDeposit\n );\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(\n address indexed account,\n uint256 withdrawTime\n );\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
+ },
+ "contracts/interfaces/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n }\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {data := calldataload(userOp)}\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return abi.encode(\n sender, nonce,\n hashInitCode, hashCallData,\n callGasLimit, verificationGasLimit, preVerificationGas,\n maxFeePerGas, maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/utils/Exec.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {\n bool success = call(to,0,data,gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 1000000
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/gnosis/.chainId b/lib/SoulWalletCore/lib/account-abstraction/deployments/gnosis/.chainId
new file mode 100644
index 00000000..105d7d9a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/gnosis/.chainId
@@ -0,0 +1 @@
+100
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/gnosis/EntryPoint.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/gnosis/EntryPoint.json
new file mode 100644
index 00000000..916c2390
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/gnosis/EntryPoint.json
@@ -0,0 +1,1318 @@
+{
+ "address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "paid",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bool",
+ "name": "targetSuccess",
+ "type": "bool"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetResult",
+ "type": "bytes"
+ }
+ ],
+ "name": "ExecutionResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "opIndex",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "reason",
+ "type": "string"
+ }
+ ],
+ "name": "FailedOp",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "SenderAddressResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureValidationFailed",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "stakeInfo",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IEntryPoint.AggregatorStakeInfo",
+ "name": "aggregatorInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResultWithAggregation",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "factory",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ }
+ ],
+ "name": "AccountDeployed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "BeforeExecution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalDeposit",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposited",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureAggregatorChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalStaked",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeLocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "withdrawTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeUnlocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeWithdrawn",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "success",
+ "type": "bool"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasUsed",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserOperationEvent",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "revertReason",
+ "type": "bytes"
+ }
+ ],
+ "name": "UserOperationRevertReason",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawn",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "SIG_VALIDATION_FAILED",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ }
+ ],
+ "name": "_validateSenderAndPaymaster",
+ "outputs": [],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ }
+ ],
+ "name": "addStake",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deposits",
+ "outputs": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "getDepositInfo",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "internalType": "struct IStakeManager.DepositInfo",
+ "name": "info",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "getNonce",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ }
+ ],
+ "name": "getSenderAddress",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "getUserOpHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "userOps",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "contract IAggregator",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.UserOpsPerAggregator[]",
+ "name": "opsPerAggregator",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleAggregatedOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "ops",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "incrementNonce",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.MemoryUserOp",
+ "name": "mUserOp",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "contextOffset",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.UserOpInfo",
+ "name": "opInfo",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes",
+ "name": "context",
+ "type": "bytes"
+ }
+ ],
+ "name": "innerHandleOp",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "",
+ "type": "uint192"
+ }
+ ],
+ "name": "nonceSequenceNumber",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "op",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetCallData",
+ "type": "bytes"
+ }
+ ],
+ "name": "simulateHandleOp",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "simulateValidation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unlockStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ }
+ ],
+ "name": "withdrawStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "withdrawAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdrawTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "args": [],
+ "numDeployments": 1,
+ "solcInputHash": "a4c52f0671aad8941c53d6ead2063803",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"targetSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"targetResult\",\"type\":\"bytes\"}],\"name\":\"ExecutionResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"opIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"FailedOp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderAddressResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureValidationFailed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResult\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"type\":\"tuple\"}],\"internalType\":\"struct IEntryPoint.AggregatorStakeInfo\",\"name\":\"aggregatorInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResultWithAggregation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"}],\"name\":\"AccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"BeforeExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalDeposit\",\"type\":\"uint256\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureAggregatorChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStaked\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"name\":\"StakeLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"StakeWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasUsed\",\"type\":\"uint256\"}],\"name\":\"UserOperationEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"revertReason\",\"type\":\"bytes\"}],\"name\":\"UserOperationRevertReason\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SIG_VALIDATION_FAILED\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"}],\"name\":\"_validateSenderAndPaymaster\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"}],\"name\":\"addStake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getDepositInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"internalType\":\"struct IStakeManager.DepositInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"getSenderAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"getUserOpHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"userOps\",\"type\":\"tuple[]\"},{\"internalType\":\"contract IAggregator\",\"name\":\"aggregator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.UserOpsPerAggregator[]\",\"name\":\"opsPerAggregator\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleAggregatedOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"incrementNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.MemoryUserOp\",\"name\":\"mUserOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contextOffset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.UserOpInfo\",\"name\":\"opInfo\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"name\":\"innerHandleOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"name\":\"nonceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCallData\",\"type\":\"bytes\"}],\"name\":\"simulateHandleOp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"simulateValidation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"}],\"name\":\"withdrawStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"withdrawAmount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"FailedOp(uint256,string)\":[{\"params\":{\"opIndex\":\"- index into the array of ops to the failed one (in simulateValidation, this is always zero)\",\"reason\":\"- revert reason The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues, so a failure can be attributed to the correct entity. Should be caught in off-chain handleOps simulation and not happen on-chain. Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\"}}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"params\":{\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"params\":{\"aggregatorInfo\":\"signature aggregation info (if the account requires signature aggregator) bundler MUST use it to verify the signature, or reject the UserOperation\",\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}]},\"kind\":\"dev\",\"methods\":{\"addStake(uint32)\":{\"params\":{\"unstakeDelaySec\":\"the new lock duration before the deposit can be withdrawn.\"}},\"getDepositInfo(address)\":{\"returns\":{\"info\":\"- full deposit information of given account\"}},\"getNonce(address,uint192)\":{\"params\":{\"key\":\"the high 192 bit of the nonce\",\"sender\":\"the account address\"},\"returns\":{\"nonce\":\"a full nonce to pass for next UserOp with this sender.\"}},\"getSenderAddress(bytes)\":{\"params\":{\"initCode\":\"the constructor code to be passed into the UserOperation.\"}},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"opsPerAggregator\":\"the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\"}},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"ops\":\"the operations to execute\"}},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"params\":{\"op\":\"the UserOperation to simulate\",\"target\":\"if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult are set to the return from that call.\",\"targetCallData\":\"callData to pass to target address\"}},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"details\":\"this method always revert. Successful result is ValidationResult error. other errors are failures.The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\",\"params\":{\"userOp\":\"the user operation to validate.\"}},\"withdrawStake(address)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\"}},\"withdrawTo(address,uint256)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\",\"withdrawAmount\":\"the amount to withdraw.\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"ExecutionResult(uint256,uint256,uint48,uint48,bool,bytes)\":[{\"notice\":\"return value of simulateHandleOp\"}],\"FailedOp(uint256,string)\":[{\"notice\":\"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.\"}],\"SenderAddressResult(address)\":[{\"notice\":\"return value of getSenderAddress\"}],\"SignatureValidationFailed(address)\":[{\"notice\":\"error case when a signature aggregator fails to verify the aggregated signature it had created.\"}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"notice\":\"Successful result from simulateValidation.\"}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"notice\":\"Successful result from simulateValidation, if the account returns a signature aggregator\"}]},\"events\":{\"AccountDeployed(bytes32,address,address,address)\":{\"notice\":\"account \\\"sender\\\" was deployed.\"},\"BeforeExecution()\":{\"notice\":\"an event emitted by handleOps(), before starting the execution loop. any event emitted before this event, is part of the validation.\"},\"SignatureAggregatorChanged(address)\":{\"notice\":\"signature aggregator used by the following UserOperationEvents within this bundle.\"},\"StakeLocked(address,uint256,uint256)\":{\"notice\":\"Emitted when stake or unstake delay are modified\"},\"StakeUnlocked(address,uint256)\":{\"notice\":\"Emitted once a stake is scheduled for withdrawal\"},\"UserOperationRevertReason(bytes32,address,uint256,bytes)\":{\"notice\":\"An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\"}},\"kind\":\"user\",\"methods\":{\"SIG_VALIDATION_FAILED()\":{\"notice\":\"for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value in case of signature failure, instead of revert.\"},\"_validateSenderAndPaymaster(bytes,address,bytes)\":{\"notice\":\"Called only during simulation. This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\"},\"addStake(uint32)\":{\"notice\":\"add to the account's stake - amount and delay any pending unstake is first cancelled.\"},\"balanceOf(address)\":{\"notice\":\"return the deposit (for gas payment) of the account\"},\"depositTo(address)\":{\"notice\":\"add to the deposit of the given account\"},\"deposits(address)\":{\"notice\":\"maps paymaster to their deposits and stakes\"},\"getNonce(address,uint192)\":{\"notice\":\"Return the next nonce for this sender. Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) But UserOp with different keys can come with arbitrary order.\"},\"getSenderAddress(bytes)\":{\"notice\":\"Get counterfactual sender address. Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. this method always revert, and returns the address in SenderAddressResult error\"},\"getUserOpHash((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"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.\"},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperation with Aggregators\"},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperations. no signature aggregator is used. if any account requires an aggregator (that is, it returned an aggregator when performing simulateValidation), then handleAggregatedOps() must be used instead.\"},\"incrementNonce(uint192)\":{\"notice\":\"Manually increment the nonce of the sender. This method is exposed just for completeness.. Account does NOT need to call it, neither during validation, nor elsewhere, as the EntryPoint will update the nonce regardless. Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future UserOperations will not pay extra for the first transaction with a given key.\"},\"innerHandleOp(bytes,((address,uint256,uint256,uint256,uint256,address,uint256,uint256),bytes32,uint256,uint256,uint256),bytes)\":{\"notice\":\"inner function to handle a UserOperation. Must be declared \\\"external\\\" to open a call context, but it can only be called by handleOps.\"},\"nonceSequenceNumber(address,uint192)\":{\"notice\":\"The next valid sequence number for a given nonce key.\"},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"notice\":\"simulate full execution of a UserOperation (including both validation and target execution) this method will always revert with \\\"ExecutionResult\\\". it performs full validation of the UserOperation, but ignores signature error. an optional target address is called after the userop succeeds, and its value is returned (before the entire call is reverted) Note that in order to collect the the success/failure of the target call, it must be executed with trace enabled to track the emitted events.\"},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\"},\"unlockStake()\":{\"notice\":\"attempt to unlock the stake. the value can be withdrawn (using withdrawStake) after the unstake delay.\"},\"withdrawStake(address)\":{\"notice\":\"withdraw from the (unlocked) stake. must first call unlockStake and wait for the unstakeDelay to pass\"},\"withdrawTo(address,uint256)\":{\"notice\":\"withdraw from the deposit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/core/EntryPoint.sol\":\"EntryPoint\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0x190dd6f8d592b7e4e930feb7f4313aeb8e1c4ad3154c27ce1cf6a512fc30d8cc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ce8dfb62d0c4fa260d6eec8f1cd47f5f2a044e11bde5b31d18072fa6e7d9010\",\"dweb:/ipfs/QmTyFztU3tLEcEDnqqiaW4UJetqsU77LXc6pjc9oTXCK5u\"]},\"contracts/core/EntryPoint.sol\":{\"keccak256\":\"0x04f86318b47f052d7308795ffae6ecec0d023d2458b4e17751b89a0e4acfcdc6\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://c9f6e359c8dbe875ad974d3a0fb7b3d62319a6b115c44bac1e4587ae2ad2edaf\",\"dweb:/ipfs/QmTSWTov2rUeYk8cwzrtsd3uVXokCYok4gMiZ1sPs9tycH\"]},\"contracts/core/Helpers.sol\":{\"keccak256\":\"0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746\",\"dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU\"]},\"contracts/core/NonceManager.sol\":{\"keccak256\":\"0xa17a4a6fde70088ab18ffe6df830f3efa31f1cd0e1a7160336c96e3c94984d25\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://b38615df9f80c56282b72888e9ba1eb1a9413fa67a0dbf094deda7af9feb38e7\",\"dweb:/ipfs/QmSzcXetEJRH4UHuUmZiSgX6bFgfqHWfmyuxVnh4NosMk1\"]},\"contracts/core/SenderCreator.sol\":{\"keccak256\":\"0x44b9449fec82d6cdfb01d52fdd5a72f90099c651316123810cf9633f00b018c2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a9c0487390e72638681d175c45bc92425c802fffdca4bd0ae8457782ee284612\",\"dweb:/ipfs/QmVbzuehCUWJWqEHyMWuc6cRVbxfcMdFsmGL9o4Wz7WY2x\"]},\"contracts/core/StakeManager.sol\":{\"keccak256\":\"0x21aa0956382bd000b1b8c3b1d19ca6ebcd6c9029eebb19c612fb38ee5dd2430a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0a625c8795354d9f429367f9c1d14eb8af7db9c7f2c2a2033e2066ced76a573a\",\"dweb:/ipfs/Qmd1j6UarUg54q1G2HCNCLQz8XGVZR1qxX7eQ6cytHpQPN\"]},\"contracts/interfaces/IAccount.sol\":{\"keccak256\":\"0x556a0e5980de18e90b115553ed502408155ba35f58642823010d9288047bc418\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a0f420134b79596db8737173c7b933ae0a33059e107b6327c43aa40d4744a9e4\",\"dweb:/ipfs/QmRo8s1AhXmEMV7uPYnbpYwU19e9Bk6jmYBJTiPx3Fo85W\"]},\"contracts/interfaces/IAggregator.sol\":{\"keccak256\":\"0x060e9ddb0152250c269ba0640dc5753834ac44cf182a2837d508c0c529cae26a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://20ed837bc5909c89ff1910246bf245a5dad6840aa939382e1694964eb7dbd37b\",\"dweb:/ipfs/QmTMybRq5yyghPDDs1ZCNAVB9sSJ4WHe6Q9mejuKPTAdNP\"]},\"contracts/interfaces/IEntryPoint.sol\":{\"keccak256\":\"0x3a90bf308819ed125fa4202f880999caff8a8686633b8ddb79a30ca240d5b8f8\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://d2d21cc92c2fdab2b58d21bc25d4cd0e8c284b922528a186b087b818d54bc6cf\",\"dweb:/ipfs/QmT1qrfuBjsv2rmRCDn8mgPXHp94hARJwzbcDuBLDTbFWd\"]},\"contracts/interfaces/INonceManager.sol\":{\"keccak256\":\"0x509871e6c63663cdcc3eba19920fe84e991f38b289b1377ac3c3a6d9f22d7e12\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://00fe21b4349b24c50df60e1a705179293982bd9e7a32b78d4bac9620f89e7fe2\",\"dweb:/ipfs/QmSFFYGfUwQbVa6hASjU7YxTvgi2HkfrPr4X5oPHscHg8b\"]},\"contracts/interfaces/IPaymaster.sol\":{\"keccak256\":\"0x36858ba8685024974f533530420688da3454d29996ebc42e410673a1ed2ec456\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://616cbcf51778b1961b7f20a547bec7efae6d1d565df0f651926241ed8bde9ad8\",\"dweb:/ipfs/QmaVsgffUUmeUJYgStvRr8cNZ1LBbrc3FYNLW4JT1dVLia\"]},\"contracts/interfaces/IStakeManager.sol\":{\"keccak256\":\"0xd227b02888cd4ac68daebcdfd992ec00f9fff66fa3b3bb16f656cd582fa3480f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://b389da4714a138be63704a576a482505eab2855e263b38a93706395d8d42e7c3\",\"dweb:/ipfs/QmeeAZpdHwUXxqP8pxA7GNtoCGBmmH4FaqLLwScVKGxtxZ\"]},\"contracts/interfaces/UserOperation.sol\":{\"keccak256\":\"0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c\",\"dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN\"]},\"contracts/utils/Exec.sol\":{\"keccak256\":\"0x5b232117afbc2939f3ffc92745614867e9e1d475a3e1e5443adae13c200174f1\",\"license\":\"LGPL-3.0-only\",\"urls\":[\"bzz-raw://62e7365379a06ead7b47637945bcaee095d51aab1d3ac00ddec69443e6cbe9fe\",\"dweb:/ipfs/QmctG3aw4U3KMSMeJKoLJ1NJewjMWfppnd1m3kxNTe39Uy\"]}},\"version\":1}",
+ "bytecode": "0x60a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033",
+ "deployedBytecode": "0x60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c63430008110033"
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/gnosis/solcInputs/a4c52f0671aad8941c53d6ead2063803.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/gnosis/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
new file mode 100644
index 00000000..dd58ba5a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/gnosis/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
@@ -0,0 +1,68 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts/security/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n"
+ },
+ "contracts/core/EntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard {\n\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success,) = beneficiary.call{value : amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) public nonReentrant {\n\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(address(aggregator) != address(1), \"AA96 invalid aggregator\");\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {}\n catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {\n\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);\n }\n\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {\n return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(paymasterAndData.length >= 20, \"AA93 invalid paymasterAndData\");\n mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,\n sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));\n revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);\n }\n revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);\n\n }\n\n function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0) revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);\n if (sender1 == address(0)) revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender) revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0) revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0 : 20]));\n emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(UserOperation calldata userOp) internal view {\n // solhint-disable-next-line no-empty-blocks\n try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}\n catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0 : 20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)\n internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;\n }\n try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA23 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)\n internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(verificationGasLimit > gasUsedByValidateAccountPrepayment, \"AA41 too little verificationGas\");\n uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA33 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)\n private returns (uint256 validationData, uint256 paymasterValidationData) {\n\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |\n userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);\n (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}\n catch Error(string memory reason) {\n revert FailedOp(opIndex, string.concat(\"AA50 postOp reverted: \", reason));\n }\n catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {\n assembly {offset := data}\n }\n\n function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {\n assembly {data := offset}\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {mstore(0, number())}\n }\n}\n\n"
+ },
+ "contracts/core/Helpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\n struct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n }\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n// intersect account and paymaster ranges.\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(validationData);\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n }\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n }\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\n function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n }\n\n"
+ },
+ "contracts/core/NonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(address sender, uint192 key)\n public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(address sender, uint256 nonce) internal returns (bool) {\n\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n\n}\n"
+ },
+ "contracts/core/SenderCreator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(bytes calldata initCode) external returns (address sender) {\n address factory = address(bytes20(initCode[0 : 20]));\n bytes memory initCallData = initCode[20 :];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n"
+ },
+ "contracts/core/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(address account) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(unstakeDelaySec >= info.unstakeDelaySec, \"cannot decrease unstake time\");\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(info.withdrawTime <= block.timestamp, \"Stake withdrawal is not due\");\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success,) = withdrawAddress.call{value : stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success,) = withdrawAddress.call{value : withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n"
+ },
+ "contracts/interfaces/IAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external returns (uint256 validationData);\n}\n"
+ },
+ "contracts/interfaces/IAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\n}\n"
+ },
+ "contracts/interfaces/IEntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo);\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n\n"
+ },
+ "contracts/interfaces/INonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(address sender, uint192 key)\n external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n"
+ },
+ "contracts/interfaces/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;\n}\n"
+ },
+ "contracts/interfaces/IStakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n\n event Deposited(\n address indexed account,\n uint256 totalDeposit\n );\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(\n address indexed account,\n uint256 withdrawTime\n );\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
+ },
+ "contracts/interfaces/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n }\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {data := calldataload(userOp)}\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return abi.encode(\n sender, nonce,\n hashInitCode, hashCallData,\n callGasLimit, verificationGasLimit, preVerificationGas,\n maxFeePerGas, maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/utils/Exec.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {\n bool success = call(to,0,data,gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 1000000
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/goerli/.chainId b/lib/SoulWalletCore/lib/account-abstraction/deployments/goerli/.chainId
new file mode 100644
index 00000000..7813681f
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/goerli/.chainId
@@ -0,0 +1 @@
+5
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/goerli/EntryPoint.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/goerli/EntryPoint.json
new file mode 100644
index 00000000..916c2390
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/goerli/EntryPoint.json
@@ -0,0 +1,1318 @@
+{
+ "address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "paid",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bool",
+ "name": "targetSuccess",
+ "type": "bool"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetResult",
+ "type": "bytes"
+ }
+ ],
+ "name": "ExecutionResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "opIndex",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "reason",
+ "type": "string"
+ }
+ ],
+ "name": "FailedOp",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "SenderAddressResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureValidationFailed",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "stakeInfo",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IEntryPoint.AggregatorStakeInfo",
+ "name": "aggregatorInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResultWithAggregation",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "factory",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ }
+ ],
+ "name": "AccountDeployed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "BeforeExecution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalDeposit",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposited",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureAggregatorChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalStaked",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeLocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "withdrawTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeUnlocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeWithdrawn",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "success",
+ "type": "bool"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasUsed",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserOperationEvent",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "revertReason",
+ "type": "bytes"
+ }
+ ],
+ "name": "UserOperationRevertReason",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawn",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "SIG_VALIDATION_FAILED",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ }
+ ],
+ "name": "_validateSenderAndPaymaster",
+ "outputs": [],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ }
+ ],
+ "name": "addStake",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deposits",
+ "outputs": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "getDepositInfo",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "internalType": "struct IStakeManager.DepositInfo",
+ "name": "info",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "getNonce",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ }
+ ],
+ "name": "getSenderAddress",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "getUserOpHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "userOps",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "contract IAggregator",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.UserOpsPerAggregator[]",
+ "name": "opsPerAggregator",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleAggregatedOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "ops",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "incrementNonce",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.MemoryUserOp",
+ "name": "mUserOp",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "contextOffset",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.UserOpInfo",
+ "name": "opInfo",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes",
+ "name": "context",
+ "type": "bytes"
+ }
+ ],
+ "name": "innerHandleOp",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "",
+ "type": "uint192"
+ }
+ ],
+ "name": "nonceSequenceNumber",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "op",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetCallData",
+ "type": "bytes"
+ }
+ ],
+ "name": "simulateHandleOp",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "simulateValidation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unlockStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ }
+ ],
+ "name": "withdrawStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "withdrawAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdrawTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "args": [],
+ "numDeployments": 1,
+ "solcInputHash": "a4c52f0671aad8941c53d6ead2063803",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"targetSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"targetResult\",\"type\":\"bytes\"}],\"name\":\"ExecutionResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"opIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"FailedOp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderAddressResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureValidationFailed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResult\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"type\":\"tuple\"}],\"internalType\":\"struct IEntryPoint.AggregatorStakeInfo\",\"name\":\"aggregatorInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResultWithAggregation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"}],\"name\":\"AccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"BeforeExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalDeposit\",\"type\":\"uint256\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureAggregatorChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStaked\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"name\":\"StakeLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"StakeWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasUsed\",\"type\":\"uint256\"}],\"name\":\"UserOperationEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"revertReason\",\"type\":\"bytes\"}],\"name\":\"UserOperationRevertReason\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SIG_VALIDATION_FAILED\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"}],\"name\":\"_validateSenderAndPaymaster\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"}],\"name\":\"addStake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getDepositInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"internalType\":\"struct IStakeManager.DepositInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"getSenderAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"getUserOpHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"userOps\",\"type\":\"tuple[]\"},{\"internalType\":\"contract IAggregator\",\"name\":\"aggregator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.UserOpsPerAggregator[]\",\"name\":\"opsPerAggregator\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleAggregatedOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"incrementNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.MemoryUserOp\",\"name\":\"mUserOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contextOffset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.UserOpInfo\",\"name\":\"opInfo\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"name\":\"innerHandleOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"name\":\"nonceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCallData\",\"type\":\"bytes\"}],\"name\":\"simulateHandleOp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"simulateValidation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"}],\"name\":\"withdrawStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"withdrawAmount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"FailedOp(uint256,string)\":[{\"params\":{\"opIndex\":\"- index into the array of ops to the failed one (in simulateValidation, this is always zero)\",\"reason\":\"- revert reason The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues, so a failure can be attributed to the correct entity. Should be caught in off-chain handleOps simulation and not happen on-chain. Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\"}}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"params\":{\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"params\":{\"aggregatorInfo\":\"signature aggregation info (if the account requires signature aggregator) bundler MUST use it to verify the signature, or reject the UserOperation\",\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}]},\"kind\":\"dev\",\"methods\":{\"addStake(uint32)\":{\"params\":{\"unstakeDelaySec\":\"the new lock duration before the deposit can be withdrawn.\"}},\"getDepositInfo(address)\":{\"returns\":{\"info\":\"- full deposit information of given account\"}},\"getNonce(address,uint192)\":{\"params\":{\"key\":\"the high 192 bit of the nonce\",\"sender\":\"the account address\"},\"returns\":{\"nonce\":\"a full nonce to pass for next UserOp with this sender.\"}},\"getSenderAddress(bytes)\":{\"params\":{\"initCode\":\"the constructor code to be passed into the UserOperation.\"}},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"opsPerAggregator\":\"the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\"}},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"ops\":\"the operations to execute\"}},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"params\":{\"op\":\"the UserOperation to simulate\",\"target\":\"if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult are set to the return from that call.\",\"targetCallData\":\"callData to pass to target address\"}},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"details\":\"this method always revert. Successful result is ValidationResult error. other errors are failures.The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\",\"params\":{\"userOp\":\"the user operation to validate.\"}},\"withdrawStake(address)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\"}},\"withdrawTo(address,uint256)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\",\"withdrawAmount\":\"the amount to withdraw.\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"ExecutionResult(uint256,uint256,uint48,uint48,bool,bytes)\":[{\"notice\":\"return value of simulateHandleOp\"}],\"FailedOp(uint256,string)\":[{\"notice\":\"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.\"}],\"SenderAddressResult(address)\":[{\"notice\":\"return value of getSenderAddress\"}],\"SignatureValidationFailed(address)\":[{\"notice\":\"error case when a signature aggregator fails to verify the aggregated signature it had created.\"}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"notice\":\"Successful result from simulateValidation.\"}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"notice\":\"Successful result from simulateValidation, if the account returns a signature aggregator\"}]},\"events\":{\"AccountDeployed(bytes32,address,address,address)\":{\"notice\":\"account \\\"sender\\\" was deployed.\"},\"BeforeExecution()\":{\"notice\":\"an event emitted by handleOps(), before starting the execution loop. any event emitted before this event, is part of the validation.\"},\"SignatureAggregatorChanged(address)\":{\"notice\":\"signature aggregator used by the following UserOperationEvents within this bundle.\"},\"StakeLocked(address,uint256,uint256)\":{\"notice\":\"Emitted when stake or unstake delay are modified\"},\"StakeUnlocked(address,uint256)\":{\"notice\":\"Emitted once a stake is scheduled for withdrawal\"},\"UserOperationRevertReason(bytes32,address,uint256,bytes)\":{\"notice\":\"An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\"}},\"kind\":\"user\",\"methods\":{\"SIG_VALIDATION_FAILED()\":{\"notice\":\"for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value in case of signature failure, instead of revert.\"},\"_validateSenderAndPaymaster(bytes,address,bytes)\":{\"notice\":\"Called only during simulation. This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\"},\"addStake(uint32)\":{\"notice\":\"add to the account's stake - amount and delay any pending unstake is first cancelled.\"},\"balanceOf(address)\":{\"notice\":\"return the deposit (for gas payment) of the account\"},\"depositTo(address)\":{\"notice\":\"add to the deposit of the given account\"},\"deposits(address)\":{\"notice\":\"maps paymaster to their deposits and stakes\"},\"getNonce(address,uint192)\":{\"notice\":\"Return the next nonce for this sender. Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) But UserOp with different keys can come with arbitrary order.\"},\"getSenderAddress(bytes)\":{\"notice\":\"Get counterfactual sender address. Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. this method always revert, and returns the address in SenderAddressResult error\"},\"getUserOpHash((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"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.\"},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperation with Aggregators\"},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperations. no signature aggregator is used. if any account requires an aggregator (that is, it returned an aggregator when performing simulateValidation), then handleAggregatedOps() must be used instead.\"},\"incrementNonce(uint192)\":{\"notice\":\"Manually increment the nonce of the sender. This method is exposed just for completeness.. Account does NOT need to call it, neither during validation, nor elsewhere, as the EntryPoint will update the nonce regardless. Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future UserOperations will not pay extra for the first transaction with a given key.\"},\"innerHandleOp(bytes,((address,uint256,uint256,uint256,uint256,address,uint256,uint256),bytes32,uint256,uint256,uint256),bytes)\":{\"notice\":\"inner function to handle a UserOperation. Must be declared \\\"external\\\" to open a call context, but it can only be called by handleOps.\"},\"nonceSequenceNumber(address,uint192)\":{\"notice\":\"The next valid sequence number for a given nonce key.\"},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"notice\":\"simulate full execution of a UserOperation (including both validation and target execution) this method will always revert with \\\"ExecutionResult\\\". it performs full validation of the UserOperation, but ignores signature error. an optional target address is called after the userop succeeds, and its value is returned (before the entire call is reverted) Note that in order to collect the the success/failure of the target call, it must be executed with trace enabled to track the emitted events.\"},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\"},\"unlockStake()\":{\"notice\":\"attempt to unlock the stake. the value can be withdrawn (using withdrawStake) after the unstake delay.\"},\"withdrawStake(address)\":{\"notice\":\"withdraw from the (unlocked) stake. must first call unlockStake and wait for the unstakeDelay to pass\"},\"withdrawTo(address,uint256)\":{\"notice\":\"withdraw from the deposit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/core/EntryPoint.sol\":\"EntryPoint\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0x190dd6f8d592b7e4e930feb7f4313aeb8e1c4ad3154c27ce1cf6a512fc30d8cc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ce8dfb62d0c4fa260d6eec8f1cd47f5f2a044e11bde5b31d18072fa6e7d9010\",\"dweb:/ipfs/QmTyFztU3tLEcEDnqqiaW4UJetqsU77LXc6pjc9oTXCK5u\"]},\"contracts/core/EntryPoint.sol\":{\"keccak256\":\"0x04f86318b47f052d7308795ffae6ecec0d023d2458b4e17751b89a0e4acfcdc6\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://c9f6e359c8dbe875ad974d3a0fb7b3d62319a6b115c44bac1e4587ae2ad2edaf\",\"dweb:/ipfs/QmTSWTov2rUeYk8cwzrtsd3uVXokCYok4gMiZ1sPs9tycH\"]},\"contracts/core/Helpers.sol\":{\"keccak256\":\"0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746\",\"dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU\"]},\"contracts/core/NonceManager.sol\":{\"keccak256\":\"0xa17a4a6fde70088ab18ffe6df830f3efa31f1cd0e1a7160336c96e3c94984d25\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://b38615df9f80c56282b72888e9ba1eb1a9413fa67a0dbf094deda7af9feb38e7\",\"dweb:/ipfs/QmSzcXetEJRH4UHuUmZiSgX6bFgfqHWfmyuxVnh4NosMk1\"]},\"contracts/core/SenderCreator.sol\":{\"keccak256\":\"0x44b9449fec82d6cdfb01d52fdd5a72f90099c651316123810cf9633f00b018c2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a9c0487390e72638681d175c45bc92425c802fffdca4bd0ae8457782ee284612\",\"dweb:/ipfs/QmVbzuehCUWJWqEHyMWuc6cRVbxfcMdFsmGL9o4Wz7WY2x\"]},\"contracts/core/StakeManager.sol\":{\"keccak256\":\"0x21aa0956382bd000b1b8c3b1d19ca6ebcd6c9029eebb19c612fb38ee5dd2430a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0a625c8795354d9f429367f9c1d14eb8af7db9c7f2c2a2033e2066ced76a573a\",\"dweb:/ipfs/Qmd1j6UarUg54q1G2HCNCLQz8XGVZR1qxX7eQ6cytHpQPN\"]},\"contracts/interfaces/IAccount.sol\":{\"keccak256\":\"0x556a0e5980de18e90b115553ed502408155ba35f58642823010d9288047bc418\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a0f420134b79596db8737173c7b933ae0a33059e107b6327c43aa40d4744a9e4\",\"dweb:/ipfs/QmRo8s1AhXmEMV7uPYnbpYwU19e9Bk6jmYBJTiPx3Fo85W\"]},\"contracts/interfaces/IAggregator.sol\":{\"keccak256\":\"0x060e9ddb0152250c269ba0640dc5753834ac44cf182a2837d508c0c529cae26a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://20ed837bc5909c89ff1910246bf245a5dad6840aa939382e1694964eb7dbd37b\",\"dweb:/ipfs/QmTMybRq5yyghPDDs1ZCNAVB9sSJ4WHe6Q9mejuKPTAdNP\"]},\"contracts/interfaces/IEntryPoint.sol\":{\"keccak256\":\"0x3a90bf308819ed125fa4202f880999caff8a8686633b8ddb79a30ca240d5b8f8\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://d2d21cc92c2fdab2b58d21bc25d4cd0e8c284b922528a186b087b818d54bc6cf\",\"dweb:/ipfs/QmT1qrfuBjsv2rmRCDn8mgPXHp94hARJwzbcDuBLDTbFWd\"]},\"contracts/interfaces/INonceManager.sol\":{\"keccak256\":\"0x509871e6c63663cdcc3eba19920fe84e991f38b289b1377ac3c3a6d9f22d7e12\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://00fe21b4349b24c50df60e1a705179293982bd9e7a32b78d4bac9620f89e7fe2\",\"dweb:/ipfs/QmSFFYGfUwQbVa6hASjU7YxTvgi2HkfrPr4X5oPHscHg8b\"]},\"contracts/interfaces/IPaymaster.sol\":{\"keccak256\":\"0x36858ba8685024974f533530420688da3454d29996ebc42e410673a1ed2ec456\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://616cbcf51778b1961b7f20a547bec7efae6d1d565df0f651926241ed8bde9ad8\",\"dweb:/ipfs/QmaVsgffUUmeUJYgStvRr8cNZ1LBbrc3FYNLW4JT1dVLia\"]},\"contracts/interfaces/IStakeManager.sol\":{\"keccak256\":\"0xd227b02888cd4ac68daebcdfd992ec00f9fff66fa3b3bb16f656cd582fa3480f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://b389da4714a138be63704a576a482505eab2855e263b38a93706395d8d42e7c3\",\"dweb:/ipfs/QmeeAZpdHwUXxqP8pxA7GNtoCGBmmH4FaqLLwScVKGxtxZ\"]},\"contracts/interfaces/UserOperation.sol\":{\"keccak256\":\"0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c\",\"dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN\"]},\"contracts/utils/Exec.sol\":{\"keccak256\":\"0x5b232117afbc2939f3ffc92745614867e9e1d475a3e1e5443adae13c200174f1\",\"license\":\"LGPL-3.0-only\",\"urls\":[\"bzz-raw://62e7365379a06ead7b47637945bcaee095d51aab1d3ac00ddec69443e6cbe9fe\",\"dweb:/ipfs/QmctG3aw4U3KMSMeJKoLJ1NJewjMWfppnd1m3kxNTe39Uy\"]}},\"version\":1}",
+ "bytecode": "0x60a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033",
+ "deployedBytecode": "0x60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c63430008110033"
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/goerli/solcInputs/a4c52f0671aad8941c53d6ead2063803.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/goerli/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
new file mode 100644
index 00000000..dd58ba5a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/goerli/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
@@ -0,0 +1,68 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts/security/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n"
+ },
+ "contracts/core/EntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard {\n\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success,) = beneficiary.call{value : amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) public nonReentrant {\n\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(address(aggregator) != address(1), \"AA96 invalid aggregator\");\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {}\n catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {\n\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);\n }\n\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {\n return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(paymasterAndData.length >= 20, \"AA93 invalid paymasterAndData\");\n mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,\n sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));\n revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);\n }\n revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);\n\n }\n\n function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0) revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);\n if (sender1 == address(0)) revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender) revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0) revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0 : 20]));\n emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(UserOperation calldata userOp) internal view {\n // solhint-disable-next-line no-empty-blocks\n try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}\n catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0 : 20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)\n internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;\n }\n try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA23 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)\n internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(verificationGasLimit > gasUsedByValidateAccountPrepayment, \"AA41 too little verificationGas\");\n uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA33 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)\n private returns (uint256 validationData, uint256 paymasterValidationData) {\n\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |\n userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);\n (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}\n catch Error(string memory reason) {\n revert FailedOp(opIndex, string.concat(\"AA50 postOp reverted: \", reason));\n }\n catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {\n assembly {offset := data}\n }\n\n function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {\n assembly {data := offset}\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {mstore(0, number())}\n }\n}\n\n"
+ },
+ "contracts/core/Helpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\n struct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n }\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n// intersect account and paymaster ranges.\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(validationData);\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n }\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n }\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\n function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n }\n\n"
+ },
+ "contracts/core/NonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(address sender, uint192 key)\n public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(address sender, uint256 nonce) internal returns (bool) {\n\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n\n}\n"
+ },
+ "contracts/core/SenderCreator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(bytes calldata initCode) external returns (address sender) {\n address factory = address(bytes20(initCode[0 : 20]));\n bytes memory initCallData = initCode[20 :];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n"
+ },
+ "contracts/core/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(address account) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(unstakeDelaySec >= info.unstakeDelaySec, \"cannot decrease unstake time\");\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(info.withdrawTime <= block.timestamp, \"Stake withdrawal is not due\");\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success,) = withdrawAddress.call{value : stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success,) = withdrawAddress.call{value : withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n"
+ },
+ "contracts/interfaces/IAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external returns (uint256 validationData);\n}\n"
+ },
+ "contracts/interfaces/IAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\n}\n"
+ },
+ "contracts/interfaces/IEntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo);\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n\n"
+ },
+ "contracts/interfaces/INonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(address sender, uint192 key)\n external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n"
+ },
+ "contracts/interfaces/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;\n}\n"
+ },
+ "contracts/interfaces/IStakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n\n event Deposited(\n address indexed account,\n uint256 totalDeposit\n );\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(\n address indexed account,\n uint256 withdrawTime\n );\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
+ },
+ "contracts/interfaces/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n }\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {data := calldataload(userOp)}\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return abi.encode(\n sender, nonce,\n hashInitCode, hashCallData,\n callGasLimit, verificationGasLimit, preVerificationGas,\n maxFeePerGas, maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/utils/Exec.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {\n bool success = call(to,0,data,gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 1000000
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/.chainId b/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/.chainId
new file mode 100644
index 00000000..f70d7bba
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/.chainId
@@ -0,0 +1 @@
+42
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/EntryPoint.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/EntryPoint.json
new file mode 100644
index 00000000..00ddccec
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/EntryPoint.json
@@ -0,0 +1,1073 @@
+{
+ "address": "0xF63621e54F16eC6e4A732e44EaA7708935f259eF",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_create2factory",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_perOpOverhead",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint32",
+ "name": "_unstakeDelayBlocks",
+ "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"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "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": "bytes",
+ "name": "reason",
+ "type": "bytes"
+ }
+ ],
+ "name": "PaymasterPostOpFailed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalStake",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "unstakeDelayBlocks",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "withdrawBlock",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeUnlocking",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "paymaster",
+ "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": "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": "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"
+ },
+ {
+ "inputs": [],
+ "name": "addDeposit",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "addDepositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "_unstakeDelayBlocks",
+ "type": "uint32"
+ }
+ ],
+ "name": "addStake",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "create2factory",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "paymasters",
+ "type": "address[]"
+ }
+ ],
+ "name": "getPaymastersStake",
+ "outputs": [
+ {
+ "internalType": "uint256[]",
+ "name": "_stakes",
+ "type": "uint256[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_salt",
+ "type": "uint256"
+ }
+ ],
+ "name": "getSenderAddress",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ }
+ ],
+ "name": "getStakeInfo",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint96",
+ "name": "stake",
+ "type": "uint96"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelayBlocks",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint96",
+ "name": "withdrawStake",
+ "type": "uint96"
+ },
+ {
+ "internalType": "uint32",
+ "name": "withdrawBlock",
+ "type": "uint32"
+ }
+ ],
+ "internalType": "struct StakeManager.StakeInfo",
+ "name": "stakeInfo",
+ "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": "callGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "op",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address payable",
+ "name": "redeemer",
+ "type": "address"
+ }
+ ],
+ "name": "handleOp",
+ "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": "callGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "ops",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "redeemer",
+ "type": "address"
+ }
+ ],
+ "name": "handleOps",
+ "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": "callGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "op",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes",
+ "name": "context",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "enum EntryPoint.PaymentMode",
+ "name": "paymentMode",
+ "type": "uint8"
+ }
+ ],
+ "name": "internalHandleOp",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "addr",
+ "type": "address"
+ }
+ ],
+ "name": "isContractDeployed",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ }
+ ],
+ "name": "isPaymasterStaked",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "requiredStake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "requiredDelayBlocks",
+ "type": "uint256"
+ }
+ ],
+ "name": "isStaked",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "perOpOverhead",
+ "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": "callGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ },
+ {
+ "internalType": "uint256",
+ "name": "gasUsedByPayForSelfOp",
+ "type": "uint256"
+ }
+ ],
+ "name": "simulatePaymasterValidation",
+ "outputs": [
+ {
+ "internalType": "bytes",
+ "name": "context",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "gasUsedByPayForOp",
+ "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": "callGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "simulateWalletValidation",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "gasUsedByPayForSelfOp",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "stakes",
+ "outputs": [
+ {
+ "internalType": "uint96",
+ "name": "stake",
+ "type": "uint96"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelayBlocks",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint96",
+ "name": "withdrawStake",
+ "type": "uint96"
+ },
+ {
+ "internalType": "uint32",
+ "name": "withdrawBlock",
+ "type": "uint32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unlockStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unstakeDelayBlocks",
+ "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"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "args": [
+ "0xce0042B868300000d44A59004Da54A005ffdcf9f",
+ 22000,
+ 100
+ ],
+ "solcInputHash": "9255faacf3ae4e81db1326413027bfa0",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_create2factory\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_perOpOverhead\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"_unstakeDelayBlocks\",\"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\"},{\"anonymous\":false,\"inputs\":[{\"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\":\"bytes\",\"name\":\"reason\",\"type\":\"bytes\"}],\"name\":\"PaymasterPostOpFailed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStake\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelayBlocks\",\"type\":\"uint256\"}],\"name\":\"StakeAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawBlock\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocking\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"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\":\"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\":\"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\"},{\"inputs\":[],\"name\":\"addDeposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"addDepositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_unstakeDelayBlocks\",\"type\":\"uint32\"}],\"name\":\"addStake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"create2factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"paymasters\",\"type\":\"address[]\"}],\"name\":\"getPaymastersStake\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_stakes\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"_salt\",\"type\":\"uint256\"}],\"name\":\"getSenderAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"}],\"name\":\"getStakeInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"stake\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelayBlocks\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"withdrawStake\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"withdrawBlock\",\"type\":\"uint32\"}],\"internalType\":\"struct StakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"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\":\"callGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"address payable\",\"name\":\"redeemer\",\"type\":\"address\"}],\"name\":\"handleOp\",\"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\":\"callGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"redeemer\",\"type\":\"address\"}],\"name\":\"handleOps\",\"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\":\"callGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"enum EntryPoint.PaymentMode\",\"name\":\"paymentMode\",\"type\":\"uint8\"}],\"name\":\"internalHandleOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"isContractDeployed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"}],\"name\":\"isPaymasterStaked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requiredStake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requiredDelayBlocks\",\"type\":\"uint256\"}],\"name\":\"isStaked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"perOpOverhead\",\"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\":\"callGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"gasUsedByPayForSelfOp\",\"type\":\"uint256\"}],\"name\":\"simulatePaymasterValidation\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"gasUsedByPayForOp\",\"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\":\"callGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"simulateWalletValidation\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gasUsedByPayForSelfOp\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"stakes\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"stake\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelayBlocks\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"withdrawStake\",\"type\":\"uint96\"},{\"internalType\":\"uint32\",\"name\":\"withdrawBlock\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unstakeDelayBlocks\",\"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\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"handleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes),address)\":{\"params\":{\"op\":\"the operation to execute\",\"redeemer\":\"the contract to redeem the fee\"}},\"simulatePaymasterValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes),uint256)\":{\"params\":{\"gasUsedByPayForSelfOp\":\"- the gas returned by simulateWalletValidation, as these 2 calls should share the same userOp.validationGas quota. The node must also verify it doesn't use banned opcode, and that it doesn't reference storage outside the paymaster's data\",\"userOp\":\"the user operation to validate.\"}},\"simulateWalletValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes))\":{\"returns\":{\"gasUsedByPayForSelfOp\":\"- gas used by the validation, to pass into simulatePaymasterValidation. The node must also verify it doesn't use banned opcode, and that it doesn't reference storage outside the wallet's data\"}}},\"version\":1},\"userdoc\":{\"events\":{\"StakeUnlocking(address,uint256)\":{\"notice\":\"Emitted once a stake is scheduled for withdrawal\"}},\"kind\":\"user\",\"methods\":{\"addDeposit()\":{\"notice\":\"add a deposit (just like stake, but with lock=0 cancel any pending unlock\"},\"addStake(uint32)\":{\"notice\":\"add stake value for this paymaster. cancel any pending unlock\"},\"handleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes),address)\":{\"notice\":\"Execute the given UserOperation.\"},\"simulatePaymasterValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes),uint256)\":{\"notice\":\"Simulate a call to paymaster.verifyPaymasterUserOp do nothing if has no paymaster.\"},\"simulateWalletValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes))\":{\"notice\":\"Simulate a call for wallet.verifyUserOp. Call must not revert.\"},\"stakes(address)\":{\"notice\":\"maps relay managers to their stakes\"},\"unstakeDelayBlocks()\":{\"notice\":\"minimum number of blocks to after 'unlock' before amount can be withdrawn.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/EntryPoint.sol\":\"EntryPoint\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/EntryPoint.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"./StakeManager.sol\\\";\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IWallet.sol\\\";\\nimport \\\"./IPaymaster.sol\\\";\\n\\ninterface ICreate2Deployer {\\n function deploy(bytes memory _initCode, bytes32 _salt) external returns (address);\\n}\\n\\ncontract EntryPoint is StakeManager {\\n\\n using UserOperationLib for UserOperation;\\n // paymaster locked stake\\n // (actual stake should be higher, to cover actual call cost)\\n uint256 constant PAYMASTER_STAKE = 1 ether;\\n\\n enum PaymentMode {\\n paymasterStake, // if paymaster is set, use paymaster's stake to pay.\\n walletStake, // wallet has enough stake to pay for request.\\n walletEth // wallet has no stake. paying with eth.\\n }\\n\\n uint public immutable perOpOverhead;\\n address public immutable create2factory;\\n\\n event UserOperationEvent(address indexed sender, address indexed paymaster, uint nonce, uint actualGasCost, uint actualGasPrice, bool success);\\n event UserOperationRevertReason(address indexed sender, uint nonce, bytes revertReason);\\n\\n event PaymasterPostOpFailed(address indexed sender, address indexed paymaster, uint nonce, bytes reason);\\n\\n //handleOps reverts with this error struct, to mark the offending op\\n // NOTE: if simulateOp passes successfully, there should be no reason for handleOps to fail on it.\\n // @param opIndex - index into the array of ops to the failed one (in simulateOp, this is always zero)\\n // @param paymaster - if paymaster.verifyPaymasterUserOp fails, this will be the paymaster's address. if verifyUserOp failed,\\n // this value will be zero (since it failed before accessing the paymaster)\\n // @param reason - revert reason\\n // only to aid troubleshooting of wallet/paymaster reverts\\n error FailedOp(uint opIndex, address paymaster, string reason);\\n\\n constructor(address _create2factory, uint _perOpOverhead, uint32 _unstakeDelayBlocks) StakeManager(_unstakeDelayBlocks) {\\n create2factory = _create2factory;\\n perOpOverhead = _perOpOverhead;\\n }\\n\\n receive() external payable {}\\n\\n /**\\n * Execute the given UserOperation.\\n * @param op the operation to execute\\n * @param redeemer the contract to redeem the fee\\n */\\n function handleOp(UserOperation calldata op, address payable redeemer) public {\\n\\n uint preGas = gasleft();\\n\\n (uint256 prefund, PaymentMode paymentMode, bytes memory context) = _validatePrepayment(0, op);\\n uint preOpGas = preGas - gasleft() + perOpOverhead;\\n\\n uint actualGasCost;\\n\\n try this.internalHandleOp(op, context, preOpGas, prefund, paymentMode) returns (uint _actualGasCost) {\\n actualGasCost = _actualGasCost;\\n } catch {\\n uint actualGas = preGas - gasleft() + preOpGas;\\n actualGasCost = handlePostOp(IPaymaster.PostOpMode.postOpReverted, op, context, actualGas, prefund, paymentMode);\\n }\\n\\n redeem(redeemer, actualGasCost);\\n }\\n\\n function redeem(address payable redeemer, uint amount) internal {\\n redeemer.transfer(amount);\\n }\\n\\n function handleOps(UserOperation[] calldata ops, address payable redeemer) public {\\n\\n uint opslen = ops.length;\\n uint256[] memory preOpGas = new uint256[](opslen);\\n bytes32[] memory contexts = new bytes32[](opslen);\\n uint256[] memory prefunds = new uint256[](opslen);\\n PaymentMode[] memory paymentModes = new PaymentMode[](opslen);\\n\\n for (uint i = 0; i < opslen; i++) {\\n uint preGas = gasleft();\\n UserOperation calldata op = ops[i];\\n\\n bytes memory context;\\n bytes32 contextOffset;\\n (prefunds[i], paymentModes[i], context) = _validatePrepayment(i, op);\\n assembly {contextOffset := context}\\n contexts[i] = contextOffset;\\n preOpGas[i] = preGas - gasleft() + perOpOverhead;\\n }\\n\\n uint collected = 0;\\n\\n for (uint i = 0; i < ops.length; i++) {\\n uint preGas = gasleft();\\n UserOperation calldata op = ops[i];\\n bytes32 contextOffset = contexts[i];\\n bytes memory context;\\n assembly {context := contextOffset}\\n uint preOpGasi = preOpGas[i];\\n uint prefundi = prefunds[i];\\n PaymentMode paymentModei = paymentModes[i];\\n\\n try this.internalHandleOp(op, context, preOpGasi, prefundi, paymentModei) returns (uint _actualGasCost) {\\n collected += _actualGasCost;\\n } catch {\\n uint actualGas = preGas - gasleft() + preOpGasi;\\n collected += handlePostOp(IPaymaster.PostOpMode.postOpReverted, op, context, actualGas, prefundi, paymentModei);\\n }\\n }\\n\\n redeem(redeemer, collected);\\n }\\n\\n function internalHandleOp(UserOperation calldata op, bytes calldata context, uint preOpGas, uint prefund, PaymentMode paymentMode) external returns (uint actualGasCost) {\\n uint preGas = gasleft();\\n require(msg.sender == address(this));\\n\\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\\n if (op.callData.length > 0) {\\n\\n (bool success,bytes memory result) = address(op.getSender()).call{gas : op.callGas}(op.callData);\\n if (!success && result.length > 0) {\\n emit UserOperationRevertReason(op.getSender(), op.nonce, result);\\n mode = IPaymaster.PostOpMode.opReverted;\\n }\\n }\\n\\n uint actualGas = preGas - gasleft() + preOpGas;\\n return handlePostOp(mode, op, context, actualGas, prefund, paymentMode);\\n }\\n\\n /**\\n * Simulate a call for wallet.verifyUserOp.\\n * Call must not revert.\\n * @return gasUsedByPayForSelfOp - gas used by the validation, to pass into simulatePaymasterValidation.\\n * The node must also verify it doesn't use banned opcode, and that it doesn't reference storage outside the wallet's data\\n */\\n function simulateWalletValidation(UserOperation calldata userOp) external returns (uint gasUsedByPayForSelfOp){\\n require(msg.sender == address(0), \\\"must be called off-chain with from=zero-addr\\\");\\n (uint requiredPreFund, PaymentMode paymentMode) = getPaymentInfo(userOp);\\n (gasUsedByPayForSelfOp,) = _validateWalletPrepayment(0, userOp, requiredPreFund, paymentMode);\\n }\\n\\n function getPaymentInfo(UserOperation calldata userOp) internal view returns (uint requiredPrefund, PaymentMode paymentMode) {\\n requiredPrefund = userOp.requiredPreFund(perOpOverhead);\\n if (userOp.hasPaymaster()) {\\n paymentMode = PaymentMode.paymasterStake;\\n } else if (isStaked(userOp.getSender(), requiredPrefund, 0)) {\\n paymentMode = PaymentMode.walletStake;\\n } else {\\n paymentMode = PaymentMode.walletEth;\\n }\\n }\\n\\n /**\\n * Simulate a call to paymaster.verifyPaymasterUserOp\\n * do nothing if has no paymaster.\\n * @param userOp the user operation to validate.\\n * @param gasUsedByPayForSelfOp - the gas returned by simulateWalletValidation, as these 2 calls should share\\n * the same userOp.validationGas quota.\\n * The node must also verify it doesn't use banned opcode, and that it doesn't reference storage outside the paymaster's data\\n */\\n function simulatePaymasterValidation(UserOperation calldata userOp, uint gasUsedByPayForSelfOp) external view returns (bytes memory context, uint gasUsedByPayForOp){\\n (uint requiredPreFund, PaymentMode paymentMode) = getPaymentInfo(userOp);\\n if (paymentMode != PaymentMode.paymasterStake) {\\n return (\\\"\\\", 0);\\n }\\n return _validatePaymasterPrepayment(0, userOp, requiredPreFund, gasUsedByPayForSelfOp);\\n }\\n\\n // get the sender address, or use \\\"create2\\\" to create it.\\n // note that the gas allocation for this creation is deterministic (by the size of callData),\\n // so it is not checked on-chain, and adds to the gas used by verifyUserOp\\n function _createSenderIfNeeded(UserOperation calldata op) internal {\\n if (op.initCode.length != 0) {\\n //its a create operation. run the create2\\n // note that we're still under the gas limit of validate, so probably\\n // this create2 creates a proxy account.\\n // appending signer makes the request unique, so no one else can make this request.\\n //nonce is meaningless during create, so we re-purpose it as salt\\n address sender1 = ICreate2Deployer(create2factory).deploy(op.initCode, bytes32(op.nonce));\\n require(sender1 != address(0), \\\"create2 failed\\\");\\n require(sender1 == op.getSender(), \\\"sender doesn't match create2 address\\\");\\n }\\n }\\n\\n //get counterfactual sender address.\\n // use the initCode and salt in the UserOperation tot create this sender contract\\n function getSenderAddress(bytes memory initCode, uint _salt) public view returns (address) {\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(create2factory),\\n _salt,\\n keccak256(initCode)\\n )\\n );\\n\\n // NOTE: cast last 20 bytes of hash to address\\n return address(uint160(uint256(hash)));\\n }\\n\\n //call wallet.verifyUserOp, and validate that it paid as needed.\\n // return actual value sent from wallet to \\\"this\\\"\\n function _validateWalletPrepayment(uint opIndex, UserOperation calldata op, uint requiredPrefund, PaymentMode paymentMode) internal returns (uint gasUsedByPayForSelfOp, uint prefund) {\\n uint preGas = gasleft();\\n _createSenderIfNeeded(op);\\n uint preBalance = address(this).balance;\\n uint requiredEthPrefund = 0;\\n if (paymentMode == PaymentMode.walletEth) {\\n requiredEthPrefund = requiredPrefund;\\n } else if (paymentMode == PaymentMode.walletStake) {\\n _prefundFromSender(op, requiredPrefund);\\n } else {\\n // paymaster pays in handlePostOp\\n }\\n try IWallet(op.getSender()).verifyUserOp{gas : op.verificationGas}(op, requiredEthPrefund) {\\n } catch Error(string memory revertReason) {\\n revert FailedOp(opIndex, address(0), revertReason);\\n } catch {\\n revert FailedOp(opIndex, address(0), \\\"\\\");\\n }\\n uint actualEthPrefund = address(this).balance - preBalance;\\n\\n if (paymentMode == PaymentMode.walletEth) {\\n if (actualEthPrefund < requiredEthPrefund) {\\n revert FailedOp(opIndex, address(0), \\\"wallet didn't pay prefund\\\");\\n }\\n prefund = actualEthPrefund;\\n } else if (paymentMode == PaymentMode.walletStake) {\\n if (actualEthPrefund != 0) {\\n revert FailedOp(opIndex, address(0), \\\"using wallet stake but wallet paid eth\\\");\\n }\\n prefund = requiredPrefund;\\n } else {\\n if (actualEthPrefund != 0) {\\n revert FailedOp(opIndex, address(0), \\\"has paymaster but wallet paid\\\");\\n }\\n prefund = requiredPrefund;\\n }\\n\\n gasUsedByPayForSelfOp = preGas - gasleft();\\n }\\n\\n //validate paymaster.verifyPaymasterUserOp\\n function _validatePaymasterPrepayment(uint opIndex, UserOperation calldata op, uint requiredPreFund, uint gasUsedByPayForSelfOp) internal view returns (bytes memory context, uint gasUsedByPayForOp) {\\n uint preGas = gasleft();\\n if (!isValidStake(op, requiredPreFund)) {\\n revert FailedOp(opIndex, op.paymaster, \\\"not enough stake\\\");\\n }\\n //no pre-pay from paymaster\\n uint gas = op.verificationGas - gasUsedByPayForSelfOp;\\n try IPaymaster(op.paymaster).verifyPaymasterUserOp{gas : gas}(op, requiredPreFund) returns (bytes memory _context){\\n context = _context;\\n } catch Error(string memory revertReason) {\\n revert FailedOp(opIndex, op.paymaster, revertReason);\\n } catch {\\n revert FailedOp(opIndex, op.paymaster, \\\"\\\");\\n }\\n gasUsedByPayForOp = preGas - gasleft();\\n }\\n\\n function _validatePrepayment(uint opIndex, UserOperation calldata userOp) private returns (uint prefund, PaymentMode paymentMode, bytes memory context){\\n\\n uint preGas = gasleft();\\n uint gasUsedByPayForSelfOp;\\n uint requiredPreFund;\\n (requiredPreFund, paymentMode) = getPaymentInfo(userOp);\\n\\n (gasUsedByPayForSelfOp, prefund) = _validateWalletPrepayment(opIndex, userOp, requiredPreFund, paymentMode);\\n\\n uint gasUsedByPayForOp = 0;\\n if (paymentMode == PaymentMode.paymasterStake) {\\n (context, gasUsedByPayForOp) = _validatePaymasterPrepayment(opIndex, userOp, requiredPreFund, gasUsedByPayForSelfOp);\\n } else {\\n context = \\\"\\\";\\n }\\n uint gasUsed = preGas - gasleft();\\n\\n if (userOp.verificationGas < gasUsed) {\\n revert FailedOp(opIndex, userOp.paymaster, \\\"Used more than verificationGas\\\");\\n }\\n }\\n\\n function getPaymastersStake(address[] calldata paymasters) external view returns (uint[] memory _stakes) {\\n _stakes = new uint[](paymasters.length);\\n for (uint i = 0; i < paymasters.length; i++) {\\n _stakes[i] = stakes[paymasters[i]].stake;\\n }\\n }\\n\\n function handlePostOp(IPaymaster.PostOpMode mode, UserOperation calldata op, bytes memory context, uint actualGas, uint prefund, PaymentMode paymentMode) private returns (uint actualGasCost) {\\n uint preGas = gasleft();\\n uint gasPrice = UserOperationLib.gasPrice(op);\\n actualGasCost = actualGas * gasPrice;\\n if (paymentMode != PaymentMode.paymasterStake) {\\n if (prefund < actualGasCost) {\\n revert (\\\"wallet prefund below actualGasCost\\\");\\n }\\n uint refund = prefund - actualGasCost;\\n if (paymentMode == PaymentMode.walletStake) {\\n _refundSenderStake(op, refund);\\n } else {\\n _refundSender(op, refund);\\n }\\n } else {\\n if (context.length > 0) {\\n //if paymaster.postOp reverts:\\n // - emit a message (just for sake of debugging of this poor paymaster)\\n // - paymaster still pays (from its stake)\\n try IPaymaster(op.paymaster).postOp(mode, context, actualGasCost) {}\\n catch (bytes memory errdata) {\\n emit PaymasterPostOpFailed(op.getSender(), op.paymaster, op.nonce, errdata);\\n }\\n }\\n //paymaster pays for full gas, including for postOp (and revert event)\\n actualGas += preGas - gasleft();\\n actualGasCost = actualGas * gasPrice;\\n //paymaster balance known to be high enough, and to be locked for this block\\n stakes[op.paymaster].stake -= uint96(actualGasCost);\\n }\\n _emitLog(op, actualGasCost, gasPrice, mode == IPaymaster.PostOpMode.opSucceeded);\\n }\\n\\n function _emitLog(UserOperation calldata op, uint actualGasCost, uint gasPrice, bool success) internal {\\n emit UserOperationEvent(op.getSender(), op.paymaster, op.nonce, actualGasCost, gasPrice, success);\\n }\\n\\n function _prefundFromSender(UserOperation calldata userOp, uint requiredPrefund) internal {\\n stakes[userOp.getSender()].stake -= uint96(requiredPrefund);\\n }\\n\\n function _refundSender(UserOperation calldata userOp, uint refund) internal {\\n //NOTE: deliberately ignoring revert: wallet should accept refund.\\n bool sendOk = payable(userOp.getSender()).send(refund);\\n (sendOk);\\n }\\n function _refundSenderStake(UserOperation calldata userOp, uint refund) internal {\\n stakes[userOp.getSender()].stake += uint96(refund);\\n }\\n\\n function isValidStake(UserOperation calldata userOp, uint requiredPreFund) internal view returns (bool) {\\n return isPaymasterStaked(userOp.paymaster, PAYMASTER_STAKE + requiredPreFund);\\n }\\n\\n function isPaymasterStaked(address paymaster, uint stake) public view returns (bool) {\\n return isStaked(paymaster, stake, unstakeDelayBlocks);\\n }\\n\\n function isContractDeployed(address addr) external view returns (bool) {\\n bytes32 hash;\\n assembly {\\n hash := extcodehash(addr)\\n }\\n return hash != bytes32(0);\\n }\\n}\\n\\n\",\"keccak256\":\"0x8b15a6fcb66f95fc079400ff2b38de805405ce6c23c4bbbc1bcd24bb6cabefb0\",\"license\":\"GPL-3.0\"},\"contracts/IPaymaster.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IPaymaster {\\n\\n enum PostOpMode {\\n opSucceeded, // user op succeeded\\n opReverted, // user op reverted. still has to pay for gas.\\n postOpReverted //user op succeeded, but caused postOp to revert. Now its a 2nd call, after user's op was deliberately reverted.\\n }\\n // payment validation: check if paymaster agree to pay (using its stake)\\n // revert to reject this request.\\n // actual payment is done after postOp is called, by deducting actual call cost form the paymaster's stake.\\n // @param userOp the user operation\\n // @param maxcost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\\n // @returns context value to send to a postOp\\n // zero length to signify postOp is not required.\\n function verifyPaymasterUserOp(UserOperation calldata userOp, uint maxcost) external view returns (bytes memory context);\\n\\n // post-operation handler.\\n // @param mode\\n // opSucceeded - user operation succeeded.\\n // opReverted - user op reverted. still has to pay for gas.\\n // postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\\n // Now this is the 2nd call, after user's op was deliberately reverted.\\n // @param context - the context value returned by verifyPaymasterUserOp\\n // @param actualGasCost - actual gas used so far (without this postOp call).\\n function postOp(PostOpMode mode, bytes calldata context, uint actualGasCost) external;\\n}\\n\",\"keccak256\":\"0xef51907c5520d22e74cc7804b30634cdc6d2cbf2fe96b77d0b6785a53c4545a5\",\"license\":\"GPL-3.0\"},\"contracts/IWallet.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IWallet {\\n\\n // validate user's signature and nonce\\n // @param requiredPrefund how much this wallet should pre-fund the transaction.\\n // @note that after execution, the excess is sent back to the wallet.\\n // @note if requiredPrefund is zero, the wallet MUST NOT send anything (the paymaster pays)\\n function verifyUserOp(UserOperation calldata userOp, uint requiredPrefund) external;\\n}\\n\",\"keccak256\":\"0x29f98a4e6033cd10007dcc9b569fda950413cc91d8560a67f20a35e8185c9228\",\"license\":\"GPL-3.0\"},\"contracts/StakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8;\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract StakeManager {\\n\\n /// minimum number of blocks to after 'unlock' before amount can be withdrawn.\\n uint32 immutable public unstakeDelayBlocks;\\n\\n constructor(uint32 _unstakeDelayBlocks) {\\n unstakeDelayBlocks = _unstakeDelayBlocks;\\n }\\n\\n event StakeAdded(\\n address indexed paymaster,\\n uint256 totalStake,\\n uint256 unstakeDelayBlocks\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocking(\\n address indexed paymaster,\\n uint256 withdrawBlock\\n );\\n\\n event StakeWithdrawn(\\n address indexed paymaster,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// @param stake - amount of ether staked for this paymaster\\n /// @param withdrawStake - once 'unlocked' the value is no longer staked.\\n /// @param withdrawBlock - first block number 'withdraw' will be callable, or zero if the unlock has not been called\\n struct StakeInfo {\\n uint96 stake;\\n uint32 unstakeDelayBlocks;\\n uint96 withdrawStake;\\n uint32 withdrawBlock;\\n }\\n\\n /// maps relay managers to their stakes\\n mapping(address => StakeInfo) public stakes;\\n\\n function getStakeInfo(address paymaster) external view returns (StakeInfo memory stakeInfo) {\\n return stakes[paymaster];\\n }\\n\\n /**\\n * add a deposit (just like stake, but with lock=0\\n * cancel any pending unlock\\n */\\n function addDeposit() external payable {\\n addStake(0);\\n }\\n\\n //add deposit to another account (doesn't change lock status)\\n function addDepositTo(address target) external payable {\\n stakes[target].stake += uint96(msg.value);\\n }\\n\\n /**\\n * add stake value for this paymaster.\\n * cancel any pending unlock\\n */\\n function addStake(uint32 _unstakeDelayBlocks) public payable {\\n require(_unstakeDelayBlocks >= stakes[msg.sender].unstakeDelayBlocks, \\\"cannot decrease unstake blocks\\\");\\n uint96 stake = uint96(stakes[msg.sender].stake + msg.value + stakes[msg.sender].withdrawStake);\\n stakes[msg.sender] = StakeInfo(\\n stake,\\n _unstakeDelayBlocks,\\n 0,\\n 0);\\n emit StakeAdded(msg.sender, stake, _unstakeDelayBlocks);\\n }\\n\\n function unlockStake() external {\\n StakeInfo storage info = stakes[msg.sender];\\n require(info.withdrawBlock == 0, \\\"already pending\\\");\\n require(info.stake != 0 && info.unstakeDelayBlocks != 0, \\\"no stake to unlock\\\");\\n uint32 withdrawBlock = uint32(block.number) + info.unstakeDelayBlocks;\\n info.withdrawBlock = withdrawBlock;\\n info.withdrawStake = info.stake;\\n info.stake = 0;\\n emit StakeUnlocking(msg.sender, withdrawBlock);\\n }\\n\\n function withdrawStake(address payable withdrawAddress) external {\\n StakeInfo memory info = stakes[msg.sender];\\n if (info.unstakeDelayBlocks != 0) {\\n require(info.withdrawStake > 0, \\\"no unlocked stake\\\");\\n require(info.withdrawBlock <= block.number, \\\"Withdrawal is not due\\\");\\n }\\n uint256 amount = info.withdrawStake + info.stake;\\n stakes[msg.sender] = StakeInfo(0, info.unstakeDelayBlocks, 0, 0);\\n withdrawAddress.transfer(amount);\\n emit StakeWithdrawn(msg.sender, withdrawAddress, amount);\\n }\\n\\n function isStaked(address paymaster, uint requiredStake, uint requiredDelayBlocks) public view returns (bool) {\\n StakeInfo memory stakeInfo = stakes[paymaster];\\n return stakeInfo.stake >= requiredStake && stakeInfo.unstakeDelayBlocks >= requiredDelayBlocks;\\n }\\n}\\n\",\"keccak256\":\"0x238f903aceaaa89fd289d99c16ff660b6f911837f50ccf3fc3bb94653024b1aa\",\"license\":\"GPL-3.0-only\"},\"contracts/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n struct UserOperation {\\n\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint callGas;\\n uint verificationGas;\\n uint preVerificationGas;\\n uint maxFeePerGas;\\n uint maxPriorityFeePerGas;\\n address paymaster;\\n bytes paymasterData;\\n bytes signature;\\n }\\n\\nlibrary UserOperationLib {\\n\\n function getSender(UserOperation calldata userOp) internal view returns (address ret) {\\n assembly {ret := calldataload(userOp)}\\n }\\n\\n //relayer/miner might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(UserOperation calldata userOp) internal view returns (uint) {\\n unchecked {\\n return min(userOp.maxFeePerGas, userOp.maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function requiredGas(UserOperation calldata userOp) internal pure returns (uint) {\\n unchecked {\\n return userOp.callGas + userOp.verificationGas + userOp.preVerificationGas;\\n }\\n }\\n\\n function requiredPreFund(UserOperation calldata userOp, uint overhead) internal view returns (uint prefund) {\\n return (requiredGas(userOp) + overhead) * gasPrice(userOp);\\n }\\n\\n function hasPaymaster(UserOperation calldata userOp) internal pure returns (bool) {\\n return userOp.paymaster != address(0);\\n }\\n\\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\\n //lighter signature scheme. must match UserOp.ts#packUserOp\\n bytes calldata sig = userOp.signature;\\n assembly {\\n let ofs := userOp\\n let len := sub(sub(sig.offset, ofs), 32)\\n ret := mload(0x40)\\n mstore(0x40, add(ret, add(len, 32)))\\n mstore(ret, len)\\n calldatacopy(add(ret, 32), ofs, len)\\n }\\n return ret;\\n\\n //TODO: eip712-style ?\\n return abi.encode(\\n userOp.sender,\\n userOp.nonce,\\n keccak256(userOp.initCode),\\n keccak256(userOp.callData),\\n userOp.callGas,\\n userOp.verificationGas,\\n userOp.preVerificationGas,\\n userOp.maxFeePerGas,\\n userOp.maxPriorityFeePerGas,\\n userOp.paymaster,\\n keccak256(userOp.paymasterData)\\n );\\n }\\n\\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(pack(userOp))));\\n }\\n\\n function min(uint a, uint b) internal pure returns (uint) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x7ea8383b9bbd8cfa5a96f59e1f37c20a681daa798b80d67eb52ade3c53f3ea30\",\"license\":\"GPL-3.0\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"keccak256\":\"0x72b6a1d297cd3b033d7c2e4a7e7864934bb767db6453623f1c3082c6534547f4\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x60e06040523480156200001157600080fd5b5060405162002cc738038062002cc7833981016040819052620000349162000060565b60e01b6001600160e01b03191660805260609190911b6001600160601b03191660c05260a052620000bb565b6000806000606084860312156200007657600080fd5b83516001600160a01b03811681146200008e57600080fd5b60208501516040860151919450925063ffffffff81168114620000b057600080fd5b809150509250925092565b60805160e01c60a05160c05160601c612bac6200011b60003960008181610156015281816103e50152611f350152600081816102af01528181610a0a01528181611330015261187101526000818161056e01526107f50152612bac6000f3fe6080604052600436106101235760003560e01c8063af2ed7d7116100a0578063c345315311610064578063c345315314610446578063dbbabd6a1461053c578063e7c350e31461055c578063f20751eb146105a5578063f3737f19146105c657600080fd5b8063af2ed7d71461033a578063bb9fe6bf1461035a578063bf55512e1461036f578063c23a5cea1461038f578063c31e4354146103af57600080fd5b80632815c17b116100e75780632815c17b146102755780634a58db1914610295578063643407ce1461029d578063739b8950146102df578063828190131461030c57600080fd5b80630396cb601461012f5780630bfb68471461014457806316934fc4146101955780631c112a44146102255780631fa75c861461025557600080fd5b3661012a57005b600080fd5b61014261013d366004612540565b6105d9565b005b34801561015057600080fd5b506101787f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101a157600080fd5b506101ee6101b0366004612161565b6000602081905290815260409020546001600160601b038082169163ffffffff600160601b8204811692600160801b83041691600160e01b90041684565b604080516001600160601b03958616815263ffffffff9485166020820152949092169184019190915216606082015260800161018c565b34801561023157600080fd5b506102456102403660046121c7565b610764565b604051901515815260200161018c565b34801561026157600080fd5b5061024561027036600461219b565b6107ec565b34801561028157600080fd5b5061014261029036600461223d565b610826565b610142610c24565b3480156102a957600080fd5b506102d17f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161018c565b3480156102eb57600080fd5b506102ff6102fa3660046121fc565b610c30565b60405161018c91906126dd565b34801561031857600080fd5b5061032c6103273660046124e3565b610d09565b60405161018c929190612745565b34801561034657600080fd5b506102d161035536600461242a565b610d70565b34801561036657600080fd5b50610142610ee2565b34801561037b57600080fd5b506102d161038a36600461239d565b611055565b34801561039b57600080fd5b506101426103aa366004612161565b6110e0565b3480156103bb57600080fd5b506101786103ca366004612314565b8151602092830120604080516001600160f81b0319818601527f000000000000000000000000000000000000000000000000000000000000000060601b6bffffffffffffffffffffffff191660218201526035810193909352605580840192909252805180840390920182526075909201909152805191012090565b34801561045257600080fd5b506104eb610461366004612161565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b031660009081526020818152604091829020825160808101845290546001600160601b03808216835263ffffffff600160601b8304811694840194909452600160801b82041693820193909352600160e01b90920416606082015290565b60405161018c919060006080820190506001600160601b03808451168352602084015163ffffffff808216602086015282604087015116604086015280606087015116606086015250505092915050565b34801561054857600080fd5b506101426105573660046123d9565b611311565b34801561056857600080fd5b506105907f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161018c565b3480156105b157600080fd5b506102456105c0366004612161565b3f151590565b6101426105d4366004612161565b61142b565b3360009081526020819052604090205463ffffffff600160601b9091048116908216101561064e5760405162461bcd60e51b815260206004820152601e60248201527f63616e6e6f7420646563726561736520756e7374616b6520626c6f636b73000060448201526064015b60405180910390fd5b336000908152602081905260408120546001600160601b03600160801b820481169161067c9134911661290f565b610686919061290f565b604080516080810182526001600160601b0383811680835263ffffffff878116602080860182815260008789018181526060890182815233808452838652928b902099518a54945192519151908a166001600160801b031990951694909417600160601b92881692909202919091176001600160801b0316600160801b91909816026001600160e01b031696909617600160e01b91909416029290921790945584519182528101929092529293507f270d6dd254edd1d985c81cf7861b8f28fb06b6d719df04d90464034d4341244091015b60405180910390a25050565b6001600160a01b038316600090815260208181526040808320815160808101835290546001600160601b0380821680845263ffffffff600160601b8404811696850196909652600160801b830490911693830193909352600160e01b9004909216606083015284118015906107e3575082816020015163ffffffff1610155b95945050505050565b600061081f83837f000000000000000000000000000000000000000000000000000000000000000063ffffffff16610764565b9392505050565b816000816001600160401b0381111561084157610841612a88565b60405190808252806020026020018201604052801561086a578160200160208202803683370190505b5090506000826001600160401b0381111561088757610887612a88565b6040519080825280602002602001820160405280156108b0578160200160208202803683370190505b5090506000836001600160401b038111156108cd576108cd612a88565b6040519080825280602002602001820160405280156108f6578160200160208202803683370190505b5090506000846001600160401b0381111561091357610913612a88565b60405190808252806020026020018201604052801561093c578160200160208202803683370190505b50905060005b85811015610a735760005a9050368a8a8481811061096257610962612a72565b90506020028101906109749190612882565b9050606060006109848584611483565b89888151811061099657610996612a72565b602002602001018989815181106109af576109af612a72565b602002602001018296508360028111156109cb576109cb612a5c565b60028111156109dc576109dc612a5c565b81525083815250505050819050808886815181106109fc576109fc612a72565b6020026020010181815250507f00000000000000000000000000000000000000000000000000000000000000005a610a349086612990565b610a3e919061290f565b898681518110610a5057610a50612a72565b602002602001018181525050505050508080610a6b90612a2b565b915050610942565b506000805b88811015610c0e5760005a9050368b8b84818110610a9857610a98612a72565b9050602002810190610aaa9190612882565b90506000878481518110610ac057610ac0612a72565b60200260200101519050606081905060008a8681518110610ae357610ae3612a72565b602002602001015190506000898781518110610b0157610b01612a72565b602002602001015190506000898881518110610b1f57610b1f612a72565b60200260200101519050306001600160a01b031663af2ed7d787868686866040518663ffffffff1660e01b8152600401610b5d959493929190612799565b602060405180830381600087803b158015610b7757600080fd5b505af1925050508015610ba7575060408051601f3d908101601f19168201909252610ba491810190612527565b60015b610be6576000835a610bb9908a612990565b610bc3919061290f565b9050610bd460028887848787611589565b610bde908b61290f565b995050610bf4565b610bf0818b61290f565b9950505b505050505050508080610c0690612a2b565b915050610a78565b50610c19878261182d565b505050505050505050565b610c2e60006105d9565b565b6060816001600160401b03811115610c4a57610c4a612a88565b604051908082528060200260200182016040528015610c73578160200160208202803683370190505b50905060005b82811015610d0257600080858584818110610c9657610c96612a72565b9050602002016020810190610cab9190612161565b6001600160a01b0316815260208101919091526040016000205482516001600160601b0390911690839083908110610ce557610ce5612a72565b602090810291909101015280610cfa81612a2b565b915050610c79565b5092915050565b60606000806000610d1986611868565b90925090506000816002811115610d3257610d32612a5c565b14610d555760006040518060200160405280600081525090935093505050610d69565b610d6260008784886118cf565b9350935050505b9250929050565b6000805a9050333014610d8257600080fd5b600080610d9260608b018b61283c565b90501115610e74576000808a356001600160a01b031660808c0135610dba60608e018e61283c565b604051610dc89291906126cd565b60006040518083038160008787f1925050503d8060008114610e06576040519150601f19603f3d011682016040523d82523d6000602084013e610e0b565b606091505b509150915081158015610e1f575060008151115b15610e71578a356001600160a01b03167fbe4889eb241fb33bc0e9873f6e442f4c5dc653a55e7ad8bca2f001c9b3d818fb8c6020013583604051610e64929190612823565b60405180910390a2600192505b50505b6000865a610e829085612990565b610e8c919061290f565b9050610ed4828b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508792508c91508b9050611589565b9a9950505050505050505050565b3360009081526020819052604090208054600160e01b900463ffffffff1615610f3f5760405162461bcd60e51b815260206004820152600f60248201526e616c72656164792070656e64696e6760881b6044820152606401610645565b80546001600160601b031615801590610f6557508054600160601b900463ffffffff1615155b610fa65760405162461bcd60e51b81526020600482015260126024820152716e6f207374616b6520746f20756e6c6f636b60701b6044820152606401610645565b8054600090610fc290600160601b900463ffffffff1643612927565b82546001600160801b0381166bffffffffffffffffffffffff60801b19600160e01b63ffffffff8516908102918216929092176001600160601b039384169190931617600160801b02919091176bffffffffffffffffffffffff1916845560405190815290915033907fab3a43860ac8cdb29929ba1a1f556b4decf9617f4811c190010e1672e55839b190602001610758565b600033156110ba5760405162461bcd60e51b815260206004820152602c60248201527f6d7573742062652063616c6c6564206f66662d636861696e207769746820667260448201526b37b69ebd32b93796b0b2323960a11b6064820152608401610645565b6000806110c684611868565b915091506110d76000858484611aab565b50949350505050565b3360009081526020818152604091829020825160808101845290546001600160601b03808216835263ffffffff600160601b83048116948401859052600160801b830490911694830194909452600160e01b90049092166060830152156111e457600081604001516001600160601b0316116111925760405162461bcd60e51b81526020600482015260116024820152706e6f20756e6c6f636b6564207374616b6560781b6044820152606401610645565b43816060015163ffffffff1611156111e45760405162461bcd60e51b81526020600482015260156024820152745769746864726177616c206973206e6f742064756560581b6044820152606401610645565b805160408201516000916111f79161294f565b60408051608081018252600080825260208681015163ffffffff9081168285019081528486018481526060860185815233865293859052868520955186549251915194518416600160e01b026001600160e01b036001600160601b03968716600160801b02166001600160801b0393909516600160601b026001600160801b031990941691861691909117929092171691909117179092559151921692506001600160a01b0385169183156108fc0291849190818181858888f193505050501580156112c7573d6000803e3d6000fd5b50604080516001600160a01b03851681526020810183905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda3910160405180910390a2505050565b60005a90506000806000611326600087611483565b92509250925060007f00000000000000000000000000000000000000000000000000000000000000005a61135a9087612990565b611364919061290f565b60405163af2ed7d760e01b8152909150600090309063af2ed7d790611395908b90879087908b908b90600401612799565b602060405180830381600087803b1580156113af57600080fd5b505af19250505080156113df575060408051601f3d908101601f191682019092526113dc91810190612527565b60015b611414576000825a6113f19089612990565b6113fb919061290f565b905061140c60028a86848a8a611589565b915050611417565b90505b611421878261182d565b5050505050505050565b6001600160a01b0381166000908152602081905260408120805434929061145c9084906001600160601b031661294f565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050565b600080606060005a905060008061149987611868565b955090506114a988888388611aab565b965091506000808660028111156114c2576114c2612a5c565b14156114de576114d4898984866118cf565b90955090506114f1565b6040518060200160405280600081525094505b60005a6114fe9086612990565b9050808960a00135101561157d578961151f6101408b016101208c01612161565b60405162fa072b60e01b815260048101929092526001600160a01b0316602482015260606044820152601e60648201527f55736564206d6f7265207468616e20766572696669636174696f6e4761730000608482015260a401610645565b50505050509250925092565b6000805a9050600061159a88611d77565b90506115a68187612971565b925060008460028111156115bc576115bc612a5c565b14611663578285101561161c5760405162461bcd60e51b815260206004820152602260248201527f77616c6c65742070726566756e642062656c6f772061637475616c476173436f6044820152611cdd60f21b6064820152608401610645565b60006116288487612990565b9050600185600281111561163e5761163e612a5c565b14156116535761164e8982611d94565b61165d565b61165d8982611dee565b50611801565b86511561176f5761167c61014089016101208a01612161565b6001600160a01b031663a9a234098a89866040518463ffffffff1660e01b81526004016116ab93929190612767565b600060405180830381600087803b1580156116c557600080fd5b505af19250505080156116d6575060015b61176f573d808015611704576040519150601f19603f3d011682016040523d82523d6000602084013e611709565b606091505b5061171c6101408a016101208b01612161565b6001600160a01b031689356001600160a01b03167f45197bfe91c32368fd75a4fcab42a1eff7699e79df0e171a343537be7657efb68b6020013584604051611765929190612823565b60405180910390a3505b5a61177a9083612990565b611784908761290f565b95506117908187612971565b9250826000806117a86101408c016101208d01612161565b6001600160a01b031681526020810191909152604001600090812080549091906117dc9084906001600160601b03166129a7565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b61182188848360008d600281111561181b5761181b612a5c565b14611e1b565b50509695505050505050565b6040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015611863573d6000803e3d6000fd5b505050565b600080611895837f0000000000000000000000000000000000000000000000000000000000000000611e97565b91506118a083611ec6565b156118ad57506000915091565b6118ba8335836000610764565b156118c757506001915091565b506002915091565b60606000805a90506118e18686611eec565b61194957866118f861014088016101208901612161565b60405162fa072b60e01b815260048101929092526001600160a01b0316602482015260606044820152601060648201526f6e6f7420656e6f756768207374616b6560801b608482015260a401610645565b60006119598560a0890135612990565b905061196d61014088016101208901612161565b6001600160a01b03166380fd44d58289896040518463ffffffff1660e01b815260040161199b9291906127e6565b60006040518083038187803b1580156119b357600080fd5b5086fa935050505080156119e957506040513d6000823e601f3d908101601f191682016040526119e69190810190612293565b60015b611a91576119f5612a9e565b806308c379a01415611a445750611a0a612aba565b80611a155750611a46565b88611a286101408a016101208b01612161565b8260405162fa072b60e01b8152600401610645939291906127f9565b505b87611a5961014089016101208a01612161565b60405162fa072b60e01b815260048101929092526001600160a01b031660248201526060604482015260006064820152608401610645565b93505a611a9e9083612990565b9250505094509492505050565b60008060005a9050611abc86611f15565b4760006002866002811115611ad357611ad3612a5c565b1415611ae0575085611b04565b6001866002811115611af457611af4612a5c565b1415611b0457611b04888861209d565b6040516307dfd9cf60e51b81526001600160a01b038935169063fbfb39e09060a08b013590611b39908c9086906004016127e6565b600060405180830381600088803b158015611b5357600080fd5b5087f193505050508015611b65575060015b611be257611b71612a9e565b806308c379a01415611bb05750611b86612aba565b80611b915750611bb2565b8960008260405162fa072b60e01b8152600401610645939291906127f9565b505b60405162fa072b60e01b8152600481018a9052600060248201819052606060448301526064820152608401610645565b6000611bee8347612990565b90506002876002811115611c0457611c04612a5c565b1415611c705781811015611c685760405162fa072b60e01b8152600481018b90526000602482015260606044820152601960648201527f77616c6c6574206469646e2774207061792070726566756e6400000000000000608482015260a401610645565b809450611d5d565b6001876002811115611c8457611c84612a5c565b1415611cfd578015611cf55760405162fa072b60e01b8152600481018b90526000602482015260606044820152602660648201527f7573696e672077616c6c6574207374616b65206275742077616c6c65742070616084820152650d2c840cae8d60d31b60a482015260c401610645565b879450611d5d565b8015611d595760405162fa072b60e01b8152600481018b90526000602482015260606044820152601d60648201527f686173207061796d6173746572206275742077616c6c65742070616964000000608482015260a401610645565b8794505b5a611d689085612990565b95505050505094509492505050565b6000611d8e8260e0013548846101000135016120cf565b92915050565b6001600160a01b0382351660009081526020819052604081208054839290611dc69084906001600160601b031661294f565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050565b6040516000906001600160a01b038435169083156108fc0290849084818181858888f15050505050505050565b611e2d61014085016101208601612161565b6001600160a01b03168435604080516020808901358252810187905290810185905283151560608201526001600160a01b0391909116907fc27a60e61c14607957b41fa2dad696de47b2d80e390d0eaaf1514c0cd20342939060800160405180910390a350505050565b6000611ea283611d77565b611ebc83608086013560a08701350160c08701350161290f565b61081f9190612971565b600080611edb61014084016101208501612161565b6001600160a01b0316141592915050565b600061081f611f0361014085016101208601612161565b61027084670de0b6b3a764000061290f565b611f22604082018261283c565b15905061209a5760006001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016634af63f02611f67604085018561283c565b6040516001600160e01b031960e085901b168152611f8f929190602088013590600401612721565b602060405180830381600087803b158015611fa957600080fd5b505af1158015611fbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe1919061217e565b90506001600160a01b03811661202a5760405162461bcd60e51b815260206004820152600e60248201526d18dc99585d194c8819985a5b195960921b6044820152606401610645565b81356001600160a01b0316816001600160a01b0316146120985760405162461bcd60e51b8152602060048201526024808201527f73656e64657220646f65736e2774206d617463682063726561746532206164646044820152637265737360e01b6064820152608401610645565b505b50565b6001600160a01b0382351660009081526020819052604081208054839290611dc69084906001600160601b03166129a7565b60008183106120de578161081f565b5090919050565b80356120f081612b61565b919050565b60008083601f84011261210757600080fd5b5081356001600160401b0381111561211e57600080fd5b6020830191508360208260051b8501011115610d6957600080fd5b8035600381106120f057600080fd5b6000610180828403121561215b57600080fd5b50919050565b60006020828403121561217357600080fd5b813561081f81612b61565b60006020828403121561219057600080fd5b815161081f81612b61565b600080604083850312156121ae57600080fd5b82356121b981612b61565b946020939093013593505050565b6000806000606084860312156121dc57600080fd5b83356121e781612b61565b95602085013595506040909401359392505050565b6000806020838503121561220f57600080fd5b82356001600160401b0381111561222557600080fd5b612231858286016120f5565b90969095509350505050565b60008060006040848603121561225257600080fd5b83356001600160401b0381111561226857600080fd5b612274868287016120f5565b909450925050602084013561228881612b61565b809150509250925092565b6000602082840312156122a557600080fd5b81516001600160401b038111156122bb57600080fd5b8201601f810184136122cc57600080fd5b80516122d7816128a3565b6040516122e482826129ff565b8281528660208486010111156122f957600080fd5b61230a8360208301602087016129cf565b9695505050505050565b6000806040838503121561232757600080fd5b82356001600160401b0381111561233d57600080fd5b8301601f8101851361234e57600080fd5b8035612359816128a3565b60405161236682826129ff565b82815287602084860101111561237b57600080fd5b8260208501602083013760006020938201840152979590910135955050505050565b6000602082840312156123af57600080fd5b81356001600160401b038111156123c557600080fd5b6123d184828501612148565b949350505050565b600080604083850312156123ec57600080fd5b82356001600160401b0381111561240257600080fd5b61240e85828601612148565b925050602083013561241f81612b61565b809150509250929050565b60008060008060008060a0878903121561244357600080fd5b86356001600160401b038082111561245a57600080fd5b6124668a838b01612148565b9750602089013591508082111561247c57600080fd5b818901915089601f83011261249057600080fd5b81358181111561249f57600080fd5b8a60208285010111156124b157600080fd5b60208301975080965050505060408701359250606087013591506124d760808801612139565b90509295509295509295565b600080604083850312156124f657600080fd5b82356001600160401b0381111561250c57600080fd5b61251885828601612148565b95602094909401359450505050565b60006020828403121561253957600080fd5b5051919050565b60006020828403121561255257600080fd5b813563ffffffff8116811461081f57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b600081518084526125a78160208601602086016129cf565b601f01601f19169290920160200192915050565b60006101806125da846125cd856120e5565b6001600160a01b03169052565b602083013560208501526125f160408401846128ca565b8260408701526126048387018284612566565b9250505061261560608401846128ca565b8583036060870152612628838284612566565b925050506080830135608085015260a083013560a085015260c083013560c085015260e083013560e085015261010080840135818601525061012061266e8185016120e5565b6001600160a01b03169085015261014061268a848201856128ca565b8684038388015261269c848284612566565b93505050506101606126b0818501856128ca565b868403838801526126c2848284612566565b979650505050505050565b8183823760009101908152919050565b6020808252825182820181905260009190848201906040850190845b81811015612715578351835292840192918401916001016126f9565b50909695505050505050565b604081526000612735604083018587612566565b9050826020830152949350505050565b604081526000612758604083018561258f565b90508260208301529392505050565b61277084612b43565b838152606060208201526000612789606083018561258f565b9050826040830152949350505050565b60a0815260006127ac60a08301886125bb565b82810360208401526127be818861258f565b9150508460408301528360608301526127d683612b43565b8260808301529695505050505050565b60408152600061275860408301856125bb565b8381526001600160a01b03831660208201526060604082018190526000906107e39083018461258f565b8281526040602082015260006123d1604083018461258f565b6000808335601e1984360301811261285357600080fd5b8301803591506001600160401b0382111561286d57600080fd5b602001915036819003821315610d6957600080fd5b6000823561017e1983360301811261289957600080fd5b9190910192915050565b60006001600160401b038211156128bc576128bc612a88565b50601f01601f191660200190565b6000808335601e198436030181126128e157600080fd5b83016020810192503590506001600160401b0381111561290057600080fd5b803603831315610d6957600080fd5b6000821982111561292257612922612a46565b500190565b600063ffffffff80831681851680830382111561294657612946612a46565b01949350505050565b60006001600160601b0380831681851680830382111561294657612946612a46565b600081600019048311821515161561298b5761298b612a46565b500290565b6000828210156129a2576129a2612a46565b500390565b60006001600160601b03838116908316818110156129c7576129c7612a46565b039392505050565b60005b838110156129ea5781810151838201526020016129d2565b838111156129f9576000848401525b50505050565b601f8201601f191681016001600160401b0381118282101715612a2457612a24612a88565b6040525050565b6000600019821415612a3f57612a3f612a46565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600060033d1115612ab75760046000803e5060005160e01c5b90565b600060443d1015612ac85790565b6040516003193d81016004833e81513d6001600160401b038160248401118184111715612af757505050505090565b8285019150815181811115612b0f5750505050505090565b843d8701016020828501011115612b295750505050505090565b612b38602082860101876129ff565b509095945050505050565b6003811061209a57634e487b7160e01b600052602160045260246000fd5b6001600160a01b038116811461209a57600080fdfea26469706673582212207d15049d6b9c7e811e26d8092a0a93a7d0ccb320de507c9e54141a4480435a1c64736f6c63430008070033",
+ "deployedBytecode": "0x6080604052600436106101235760003560e01c8063af2ed7d7116100a0578063c345315311610064578063c345315314610446578063dbbabd6a1461053c578063e7c350e31461055c578063f20751eb146105a5578063f3737f19146105c657600080fd5b8063af2ed7d71461033a578063bb9fe6bf1461035a578063bf55512e1461036f578063c23a5cea1461038f578063c31e4354146103af57600080fd5b80632815c17b116100e75780632815c17b146102755780634a58db1914610295578063643407ce1461029d578063739b8950146102df578063828190131461030c57600080fd5b80630396cb601461012f5780630bfb68471461014457806316934fc4146101955780631c112a44146102255780631fa75c861461025557600080fd5b3661012a57005b600080fd5b61014261013d366004612540565b6105d9565b005b34801561015057600080fd5b506101787f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101a157600080fd5b506101ee6101b0366004612161565b6000602081905290815260409020546001600160601b038082169163ffffffff600160601b8204811692600160801b83041691600160e01b90041684565b604080516001600160601b03958616815263ffffffff9485166020820152949092169184019190915216606082015260800161018c565b34801561023157600080fd5b506102456102403660046121c7565b610764565b604051901515815260200161018c565b34801561026157600080fd5b5061024561027036600461219b565b6107ec565b34801561028157600080fd5b5061014261029036600461223d565b610826565b610142610c24565b3480156102a957600080fd5b506102d17f000000000000000000000000000000000000000000000000000000000000000081565b60405190815260200161018c565b3480156102eb57600080fd5b506102ff6102fa3660046121fc565b610c30565b60405161018c91906126dd565b34801561031857600080fd5b5061032c6103273660046124e3565b610d09565b60405161018c929190612745565b34801561034657600080fd5b506102d161035536600461242a565b610d70565b34801561036657600080fd5b50610142610ee2565b34801561037b57600080fd5b506102d161038a36600461239d565b611055565b34801561039b57600080fd5b506101426103aa366004612161565b6110e0565b3480156103bb57600080fd5b506101786103ca366004612314565b8151602092830120604080516001600160f81b0319818601527f000000000000000000000000000000000000000000000000000000000000000060601b6bffffffffffffffffffffffff191660218201526035810193909352605580840192909252805180840390920182526075909201909152805191012090565b34801561045257600080fd5b506104eb610461366004612161565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b031660009081526020818152604091829020825160808101845290546001600160601b03808216835263ffffffff600160601b8304811694840194909452600160801b82041693820193909352600160e01b90920416606082015290565b60405161018c919060006080820190506001600160601b03808451168352602084015163ffffffff808216602086015282604087015116604086015280606087015116606086015250505092915050565b34801561054857600080fd5b506101426105573660046123d9565b611311565b34801561056857600080fd5b506105907f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff909116815260200161018c565b3480156105b157600080fd5b506102456105c0366004612161565b3f151590565b6101426105d4366004612161565b61142b565b3360009081526020819052604090205463ffffffff600160601b9091048116908216101561064e5760405162461bcd60e51b815260206004820152601e60248201527f63616e6e6f7420646563726561736520756e7374616b6520626c6f636b73000060448201526064015b60405180910390fd5b336000908152602081905260408120546001600160601b03600160801b820481169161067c9134911661290f565b610686919061290f565b604080516080810182526001600160601b0383811680835263ffffffff878116602080860182815260008789018181526060890182815233808452838652928b902099518a54945192519151908a166001600160801b031990951694909417600160601b92881692909202919091176001600160801b0316600160801b91909816026001600160e01b031696909617600160e01b91909416029290921790945584519182528101929092529293507f270d6dd254edd1d985c81cf7861b8f28fb06b6d719df04d90464034d4341244091015b60405180910390a25050565b6001600160a01b038316600090815260208181526040808320815160808101835290546001600160601b0380821680845263ffffffff600160601b8404811696850196909652600160801b830490911693830193909352600160e01b9004909216606083015284118015906107e3575082816020015163ffffffff1610155b95945050505050565b600061081f83837f000000000000000000000000000000000000000000000000000000000000000063ffffffff16610764565b9392505050565b816000816001600160401b0381111561084157610841612a88565b60405190808252806020026020018201604052801561086a578160200160208202803683370190505b5090506000826001600160401b0381111561088757610887612a88565b6040519080825280602002602001820160405280156108b0578160200160208202803683370190505b5090506000836001600160401b038111156108cd576108cd612a88565b6040519080825280602002602001820160405280156108f6578160200160208202803683370190505b5090506000846001600160401b0381111561091357610913612a88565b60405190808252806020026020018201604052801561093c578160200160208202803683370190505b50905060005b85811015610a735760005a9050368a8a8481811061096257610962612a72565b90506020028101906109749190612882565b9050606060006109848584611483565b89888151811061099657610996612a72565b602002602001018989815181106109af576109af612a72565b602002602001018296508360028111156109cb576109cb612a5c565b60028111156109dc576109dc612a5c565b81525083815250505050819050808886815181106109fc576109fc612a72565b6020026020010181815250507f00000000000000000000000000000000000000000000000000000000000000005a610a349086612990565b610a3e919061290f565b898681518110610a5057610a50612a72565b602002602001018181525050505050508080610a6b90612a2b565b915050610942565b506000805b88811015610c0e5760005a9050368b8b84818110610a9857610a98612a72565b9050602002810190610aaa9190612882565b90506000878481518110610ac057610ac0612a72565b60200260200101519050606081905060008a8681518110610ae357610ae3612a72565b602002602001015190506000898781518110610b0157610b01612a72565b602002602001015190506000898881518110610b1f57610b1f612a72565b60200260200101519050306001600160a01b031663af2ed7d787868686866040518663ffffffff1660e01b8152600401610b5d959493929190612799565b602060405180830381600087803b158015610b7757600080fd5b505af1925050508015610ba7575060408051601f3d908101601f19168201909252610ba491810190612527565b60015b610be6576000835a610bb9908a612990565b610bc3919061290f565b9050610bd460028887848787611589565b610bde908b61290f565b995050610bf4565b610bf0818b61290f565b9950505b505050505050508080610c0690612a2b565b915050610a78565b50610c19878261182d565b505050505050505050565b610c2e60006105d9565b565b6060816001600160401b03811115610c4a57610c4a612a88565b604051908082528060200260200182016040528015610c73578160200160208202803683370190505b50905060005b82811015610d0257600080858584818110610c9657610c96612a72565b9050602002016020810190610cab9190612161565b6001600160a01b0316815260208101919091526040016000205482516001600160601b0390911690839083908110610ce557610ce5612a72565b602090810291909101015280610cfa81612a2b565b915050610c79565b5092915050565b60606000806000610d1986611868565b90925090506000816002811115610d3257610d32612a5c565b14610d555760006040518060200160405280600081525090935093505050610d69565b610d6260008784886118cf565b9350935050505b9250929050565b6000805a9050333014610d8257600080fd5b600080610d9260608b018b61283c565b90501115610e74576000808a356001600160a01b031660808c0135610dba60608e018e61283c565b604051610dc89291906126cd565b60006040518083038160008787f1925050503d8060008114610e06576040519150601f19603f3d011682016040523d82523d6000602084013e610e0b565b606091505b509150915081158015610e1f575060008151115b15610e71578a356001600160a01b03167fbe4889eb241fb33bc0e9873f6e442f4c5dc653a55e7ad8bca2f001c9b3d818fb8c6020013583604051610e64929190612823565b60405180910390a2600192505b50505b6000865a610e829085612990565b610e8c919061290f565b9050610ed4828b8b8b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508792508c91508b9050611589565b9a9950505050505050505050565b3360009081526020819052604090208054600160e01b900463ffffffff1615610f3f5760405162461bcd60e51b815260206004820152600f60248201526e616c72656164792070656e64696e6760881b6044820152606401610645565b80546001600160601b031615801590610f6557508054600160601b900463ffffffff1615155b610fa65760405162461bcd60e51b81526020600482015260126024820152716e6f207374616b6520746f20756e6c6f636b60701b6044820152606401610645565b8054600090610fc290600160601b900463ffffffff1643612927565b82546001600160801b0381166bffffffffffffffffffffffff60801b19600160e01b63ffffffff8516908102918216929092176001600160601b039384169190931617600160801b02919091176bffffffffffffffffffffffff1916845560405190815290915033907fab3a43860ac8cdb29929ba1a1f556b4decf9617f4811c190010e1672e55839b190602001610758565b600033156110ba5760405162461bcd60e51b815260206004820152602c60248201527f6d7573742062652063616c6c6564206f66662d636861696e207769746820667260448201526b37b69ebd32b93796b0b2323960a11b6064820152608401610645565b6000806110c684611868565b915091506110d76000858484611aab565b50949350505050565b3360009081526020818152604091829020825160808101845290546001600160601b03808216835263ffffffff600160601b83048116948401859052600160801b830490911694830194909452600160e01b90049092166060830152156111e457600081604001516001600160601b0316116111925760405162461bcd60e51b81526020600482015260116024820152706e6f20756e6c6f636b6564207374616b6560781b6044820152606401610645565b43816060015163ffffffff1611156111e45760405162461bcd60e51b81526020600482015260156024820152745769746864726177616c206973206e6f742064756560581b6044820152606401610645565b805160408201516000916111f79161294f565b60408051608081018252600080825260208681015163ffffffff9081168285019081528486018481526060860185815233865293859052868520955186549251915194518416600160e01b026001600160e01b036001600160601b03968716600160801b02166001600160801b0393909516600160601b026001600160801b031990941691861691909117929092171691909117179092559151921692506001600160a01b0385169183156108fc0291849190818181858888f193505050501580156112c7573d6000803e3d6000fd5b50604080516001600160a01b03851681526020810183905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda3910160405180910390a2505050565b60005a90506000806000611326600087611483565b92509250925060007f00000000000000000000000000000000000000000000000000000000000000005a61135a9087612990565b611364919061290f565b60405163af2ed7d760e01b8152909150600090309063af2ed7d790611395908b90879087908b908b90600401612799565b602060405180830381600087803b1580156113af57600080fd5b505af19250505080156113df575060408051601f3d908101601f191682019092526113dc91810190612527565b60015b611414576000825a6113f19089612990565b6113fb919061290f565b905061140c60028a86848a8a611589565b915050611417565b90505b611421878261182d565b5050505050505050565b6001600160a01b0381166000908152602081905260408120805434929061145c9084906001600160601b031661294f565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050565b600080606060005a905060008061149987611868565b955090506114a988888388611aab565b965091506000808660028111156114c2576114c2612a5c565b14156114de576114d4898984866118cf565b90955090506114f1565b6040518060200160405280600081525094505b60005a6114fe9086612990565b9050808960a00135101561157d578961151f6101408b016101208c01612161565b60405162fa072b60e01b815260048101929092526001600160a01b0316602482015260606044820152601e60648201527f55736564206d6f7265207468616e20766572696669636174696f6e4761730000608482015260a401610645565b50505050509250925092565b6000805a9050600061159a88611d77565b90506115a68187612971565b925060008460028111156115bc576115bc612a5c565b14611663578285101561161c5760405162461bcd60e51b815260206004820152602260248201527f77616c6c65742070726566756e642062656c6f772061637475616c476173436f6044820152611cdd60f21b6064820152608401610645565b60006116288487612990565b9050600185600281111561163e5761163e612a5c565b14156116535761164e8982611d94565b61165d565b61165d8982611dee565b50611801565b86511561176f5761167c61014089016101208a01612161565b6001600160a01b031663a9a234098a89866040518463ffffffff1660e01b81526004016116ab93929190612767565b600060405180830381600087803b1580156116c557600080fd5b505af19250505080156116d6575060015b61176f573d808015611704576040519150601f19603f3d011682016040523d82523d6000602084013e611709565b606091505b5061171c6101408a016101208b01612161565b6001600160a01b031689356001600160a01b03167f45197bfe91c32368fd75a4fcab42a1eff7699e79df0e171a343537be7657efb68b6020013584604051611765929190612823565b60405180910390a3505b5a61177a9083612990565b611784908761290f565b95506117908187612971565b9250826000806117a86101408c016101208d01612161565b6001600160a01b031681526020810191909152604001600090812080549091906117dc9084906001600160601b03166129a7565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b61182188848360008d600281111561181b5761181b612a5c565b14611e1b565b50509695505050505050565b6040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015611863573d6000803e3d6000fd5b505050565b600080611895837f0000000000000000000000000000000000000000000000000000000000000000611e97565b91506118a083611ec6565b156118ad57506000915091565b6118ba8335836000610764565b156118c757506001915091565b506002915091565b60606000805a90506118e18686611eec565b61194957866118f861014088016101208901612161565b60405162fa072b60e01b815260048101929092526001600160a01b0316602482015260606044820152601060648201526f6e6f7420656e6f756768207374616b6560801b608482015260a401610645565b60006119598560a0890135612990565b905061196d61014088016101208901612161565b6001600160a01b03166380fd44d58289896040518463ffffffff1660e01b815260040161199b9291906127e6565b60006040518083038187803b1580156119b357600080fd5b5086fa935050505080156119e957506040513d6000823e601f3d908101601f191682016040526119e69190810190612293565b60015b611a91576119f5612a9e565b806308c379a01415611a445750611a0a612aba565b80611a155750611a46565b88611a286101408a016101208b01612161565b8260405162fa072b60e01b8152600401610645939291906127f9565b505b87611a5961014089016101208a01612161565b60405162fa072b60e01b815260048101929092526001600160a01b031660248201526060604482015260006064820152608401610645565b93505a611a9e9083612990565b9250505094509492505050565b60008060005a9050611abc86611f15565b4760006002866002811115611ad357611ad3612a5c565b1415611ae0575085611b04565b6001866002811115611af457611af4612a5c565b1415611b0457611b04888861209d565b6040516307dfd9cf60e51b81526001600160a01b038935169063fbfb39e09060a08b013590611b39908c9086906004016127e6565b600060405180830381600088803b158015611b5357600080fd5b5087f193505050508015611b65575060015b611be257611b71612a9e565b806308c379a01415611bb05750611b86612aba565b80611b915750611bb2565b8960008260405162fa072b60e01b8152600401610645939291906127f9565b505b60405162fa072b60e01b8152600481018a9052600060248201819052606060448301526064820152608401610645565b6000611bee8347612990565b90506002876002811115611c0457611c04612a5c565b1415611c705781811015611c685760405162fa072b60e01b8152600481018b90526000602482015260606044820152601960648201527f77616c6c6574206469646e2774207061792070726566756e6400000000000000608482015260a401610645565b809450611d5d565b6001876002811115611c8457611c84612a5c565b1415611cfd578015611cf55760405162fa072b60e01b8152600481018b90526000602482015260606044820152602660648201527f7573696e672077616c6c6574207374616b65206275742077616c6c65742070616084820152650d2c840cae8d60d31b60a482015260c401610645565b879450611d5d565b8015611d595760405162fa072b60e01b8152600481018b90526000602482015260606044820152601d60648201527f686173207061796d6173746572206275742077616c6c65742070616964000000608482015260a401610645565b8794505b5a611d689085612990565b95505050505094509492505050565b6000611d8e8260e0013548846101000135016120cf565b92915050565b6001600160a01b0382351660009081526020819052604081208054839290611dc69084906001600160601b031661294f565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050565b6040516000906001600160a01b038435169083156108fc0290849084818181858888f15050505050505050565b611e2d61014085016101208601612161565b6001600160a01b03168435604080516020808901358252810187905290810185905283151560608201526001600160a01b0391909116907fc27a60e61c14607957b41fa2dad696de47b2d80e390d0eaaf1514c0cd20342939060800160405180910390a350505050565b6000611ea283611d77565b611ebc83608086013560a08701350160c08701350161290f565b61081f9190612971565b600080611edb61014084016101208501612161565b6001600160a01b0316141592915050565b600061081f611f0361014085016101208601612161565b61027084670de0b6b3a764000061290f565b611f22604082018261283c565b15905061209a5760006001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016634af63f02611f67604085018561283c565b6040516001600160e01b031960e085901b168152611f8f929190602088013590600401612721565b602060405180830381600087803b158015611fa957600080fd5b505af1158015611fbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fe1919061217e565b90506001600160a01b03811661202a5760405162461bcd60e51b815260206004820152600e60248201526d18dc99585d194c8819985a5b195960921b6044820152606401610645565b81356001600160a01b0316816001600160a01b0316146120985760405162461bcd60e51b8152602060048201526024808201527f73656e64657220646f65736e2774206d617463682063726561746532206164646044820152637265737360e01b6064820152608401610645565b505b50565b6001600160a01b0382351660009081526020819052604081208054839290611dc69084906001600160601b03166129a7565b60008183106120de578161081f565b5090919050565b80356120f081612b61565b919050565b60008083601f84011261210757600080fd5b5081356001600160401b0381111561211e57600080fd5b6020830191508360208260051b8501011115610d6957600080fd5b8035600381106120f057600080fd5b6000610180828403121561215b57600080fd5b50919050565b60006020828403121561217357600080fd5b813561081f81612b61565b60006020828403121561219057600080fd5b815161081f81612b61565b600080604083850312156121ae57600080fd5b82356121b981612b61565b946020939093013593505050565b6000806000606084860312156121dc57600080fd5b83356121e781612b61565b95602085013595506040909401359392505050565b6000806020838503121561220f57600080fd5b82356001600160401b0381111561222557600080fd5b612231858286016120f5565b90969095509350505050565b60008060006040848603121561225257600080fd5b83356001600160401b0381111561226857600080fd5b612274868287016120f5565b909450925050602084013561228881612b61565b809150509250925092565b6000602082840312156122a557600080fd5b81516001600160401b038111156122bb57600080fd5b8201601f810184136122cc57600080fd5b80516122d7816128a3565b6040516122e482826129ff565b8281528660208486010111156122f957600080fd5b61230a8360208301602087016129cf565b9695505050505050565b6000806040838503121561232757600080fd5b82356001600160401b0381111561233d57600080fd5b8301601f8101851361234e57600080fd5b8035612359816128a3565b60405161236682826129ff565b82815287602084860101111561237b57600080fd5b8260208501602083013760006020938201840152979590910135955050505050565b6000602082840312156123af57600080fd5b81356001600160401b038111156123c557600080fd5b6123d184828501612148565b949350505050565b600080604083850312156123ec57600080fd5b82356001600160401b0381111561240257600080fd5b61240e85828601612148565b925050602083013561241f81612b61565b809150509250929050565b60008060008060008060a0878903121561244357600080fd5b86356001600160401b038082111561245a57600080fd5b6124668a838b01612148565b9750602089013591508082111561247c57600080fd5b818901915089601f83011261249057600080fd5b81358181111561249f57600080fd5b8a60208285010111156124b157600080fd5b60208301975080965050505060408701359250606087013591506124d760808801612139565b90509295509295509295565b600080604083850312156124f657600080fd5b82356001600160401b0381111561250c57600080fd5b61251885828601612148565b95602094909401359450505050565b60006020828403121561253957600080fd5b5051919050565b60006020828403121561255257600080fd5b813563ffffffff8116811461081f57600080fd5b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b600081518084526125a78160208601602086016129cf565b601f01601f19169290920160200192915050565b60006101806125da846125cd856120e5565b6001600160a01b03169052565b602083013560208501526125f160408401846128ca565b8260408701526126048387018284612566565b9250505061261560608401846128ca565b8583036060870152612628838284612566565b925050506080830135608085015260a083013560a085015260c083013560c085015260e083013560e085015261010080840135818601525061012061266e8185016120e5565b6001600160a01b03169085015261014061268a848201856128ca565b8684038388015261269c848284612566565b93505050506101606126b0818501856128ca565b868403838801526126c2848284612566565b979650505050505050565b8183823760009101908152919050565b6020808252825182820181905260009190848201906040850190845b81811015612715578351835292840192918401916001016126f9565b50909695505050505050565b604081526000612735604083018587612566565b9050826020830152949350505050565b604081526000612758604083018561258f565b90508260208301529392505050565b61277084612b43565b838152606060208201526000612789606083018561258f565b9050826040830152949350505050565b60a0815260006127ac60a08301886125bb565b82810360208401526127be818861258f565b9150508460408301528360608301526127d683612b43565b8260808301529695505050505050565b60408152600061275860408301856125bb565b8381526001600160a01b03831660208201526060604082018190526000906107e39083018461258f565b8281526040602082015260006123d1604083018461258f565b6000808335601e1984360301811261285357600080fd5b8301803591506001600160401b0382111561286d57600080fd5b602001915036819003821315610d6957600080fd5b6000823561017e1983360301811261289957600080fd5b9190910192915050565b60006001600160401b038211156128bc576128bc612a88565b50601f01601f191660200190565b6000808335601e198436030181126128e157600080fd5b83016020810192503590506001600160401b0381111561290057600080fd5b803603831315610d6957600080fd5b6000821982111561292257612922612a46565b500190565b600063ffffffff80831681851680830382111561294657612946612a46565b01949350505050565b60006001600160601b0380831681851680830382111561294657612946612a46565b600081600019048311821515161561298b5761298b612a46565b500290565b6000828210156129a2576129a2612a46565b500390565b60006001600160601b03838116908316818110156129c7576129c7612a46565b039392505050565b60005b838110156129ea5781810151838201526020016129d2565b838111156129f9576000848401525b50505050565b601f8201601f191681016001600160401b0381118282101715612a2457612a24612a88565b6040525050565b6000600019821415612a3f57612a3f612a46565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600060033d1115612ab75760046000803e5060005160e01c5b90565b600060443d1015612ac85790565b6040516003193d81016004833e81513d6001600160401b038160248401118184111715612af757505050505090565b8285019150815181811115612b0f5750505050505090565b843d8701016020828501011115612b295750505050505090565b612b38602082860101876129ff565b509095945050505050565b6003811061209a57634e487b7160e01b600052602160045260246000fd5b6001600160a01b038116811461209a57600080fdfea26469706673582212207d15049d6b9c7e811e26d8092a0a93a7d0ccb320de507c9e54141a4480435a1c64736f6c63430008070033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {
+ "handleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes),address)": {
+ "params": {
+ "op": "the operation to execute",
+ "redeemer": "the contract to redeem the fee"
+ }
+ },
+ "simulatePaymasterValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes),uint256)": {
+ "params": {
+ "gasUsedByPayForSelfOp": "- the gas returned by simulateWalletValidation, as these 2 calls should share the same userOp.validationGas quota. The node must also verify it doesn't use banned opcode, and that it doesn't reference storage outside the paymaster's data",
+ "userOp": "the user operation to validate."
+ }
+ },
+ "simulateWalletValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes))": {
+ "returns": {
+ "gasUsedByPayForSelfOp": "- gas used by the validation, to pass into simulatePaymasterValidation. The node must also verify it doesn't use banned opcode, and that it doesn't reference storage outside the wallet's data"
+ }
+ }
+ },
+ "version": 1
+ },
+ "userdoc": {
+ "events": {
+ "StakeUnlocking(address,uint256)": {
+ "notice": "Emitted once a stake is scheduled for withdrawal"
+ }
+ },
+ "kind": "user",
+ "methods": {
+ "addDeposit()": {
+ "notice": "add a deposit (just like stake, but with lock=0 cancel any pending unlock"
+ },
+ "addStake(uint32)": {
+ "notice": "add stake value for this paymaster. cancel any pending unlock"
+ },
+ "handleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes),address)": {
+ "notice": "Execute the given UserOperation."
+ },
+ "simulatePaymasterValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes),uint256)": {
+ "notice": "Simulate a call to paymaster.verifyPaymasterUserOp do nothing if has no paymaster."
+ },
+ "simulateWalletValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,address,bytes,bytes))": {
+ "notice": "Simulate a call for wallet.verifyUserOp. Call must not revert."
+ },
+ "stakes(address)": {
+ "notice": "maps relay managers to their stakes"
+ },
+ "unstakeDelayBlocks()": {
+ "notice": "minimum number of blocks to after 'unlock' before amount can be withdrawn."
+ }
+ },
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 2325,
+ "contract": "contracts/EntryPoint.sol:EntryPoint",
+ "label": "stakes",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_address,t_struct(StakeInfo)2319_storage)"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_struct(StakeInfo)2319_storage)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => struct StakeManager.StakeInfo)",
+ "numberOfBytes": "32",
+ "value": "t_struct(StakeInfo)2319_storage"
+ },
+ "t_struct(StakeInfo)2319_storage": {
+ "encoding": "inplace",
+ "label": "struct StakeManager.StakeInfo",
+ "members": [
+ {
+ "astId": 2312,
+ "contract": "contracts/EntryPoint.sol:EntryPoint",
+ "label": "stake",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint96"
+ },
+ {
+ "astId": 2314,
+ "contract": "contracts/EntryPoint.sol:EntryPoint",
+ "label": "unstakeDelayBlocks",
+ "offset": 12,
+ "slot": "0",
+ "type": "t_uint32"
+ },
+ {
+ "astId": 2316,
+ "contract": "contracts/EntryPoint.sol:EntryPoint",
+ "label": "withdrawStake",
+ "offset": 16,
+ "slot": "0",
+ "type": "t_uint96"
+ },
+ {
+ "astId": 2318,
+ "contract": "contracts/EntryPoint.sol:EntryPoint",
+ "label": "withdrawBlock",
+ "offset": 28,
+ "slot": "0",
+ "type": "t_uint32"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_uint32": {
+ "encoding": "inplace",
+ "label": "uint32",
+ "numberOfBytes": "4"
+ },
+ "t_uint96": {
+ "encoding": "inplace",
+ "label": "uint96",
+ "numberOfBytes": "12"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/SimpleWallet.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/SimpleWallet.json
new file mode 100644
index 00000000..6b14b548
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/SimpleWallet.json
@@ -0,0 +1,338 @@
+{
+ "address": "0x16d53bCF7d1614D0fF81559abB94bfBC7d3B84D9",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "contract EntryPoint",
+ "name": "_entryPoint",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_owner",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "contract EntryPoint",
+ "name": "oldEntryPoint",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "contract EntryPoint",
+ "name": "newEntryPoint",
+ "type": "address"
+ }
+ ],
+ "name": "EntryPointChanged",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "addDeposit",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "entryPoint",
+ "outputs": [
+ {
+ "internalType": "contract EntryPoint",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "dest",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "func",
+ "type": "bytes"
+ }
+ ],
+ "name": "exec",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "dest",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "func",
+ "type": "bytes"
+ }
+ ],
+ "name": "execFromEntryPoint",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "nonce",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "dest",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "contract EntryPoint",
+ "name": "_entryPoint",
+ "type": "address"
+ }
+ ],
+ "name": "updateEntryPoint",
+ "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": "callGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ },
+ {
+ "internalType": "uint256",
+ "name": "requiredPrefund",
+ "type": "uint256"
+ }
+ ],
+ "name": "verifyUserOp",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ }
+ ],
+ "name": "withdrawDeposit",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "args": [
+ "0xF63621e54F16eC6e4A732e44EaA7708935f259eF",
+ "0xd21934eD8eAf27a67f0A70042Af50A1D6d195E81"
+ ],
+ "solcInputHash": "9255faacf3ae4e81db1326413027bfa0",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract EntryPoint\",\"name\":\"_entryPoint\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"contract EntryPoint\",\"name\":\"oldEntryPoint\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"contract EntryPoint\",\"name\":\"newEntryPoint\",\"type\":\"address\"}],\"name\":\"EntryPointChanged\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"addDeposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"entryPoint\",\"outputs\":[{\"internalType\":\"contract EntryPoint\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"func\",\"type\":\"bytes\"}],\"name\":\"exec\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"func\",\"type\":\"bytes\"}],\"name\":\"execFromEntryPoint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"dest\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract EntryPoint\",\"name\":\"_entryPoint\",\"type\":\"address\"}],\"name\":\"updateEntryPoint\",\"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\":\"callGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"requiredPrefund\",\"type\":\"uint256\"}],\"name\":\"verifyUserOp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"}],\"name\":\"withdrawDeposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/samples/SimpleWallet.sol\":\"SimpleWallet\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/EntryPoint.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"./StakeManager.sol\\\";\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IWallet.sol\\\";\\nimport \\\"./IPaymaster.sol\\\";\\n\\ninterface ICreate2Deployer {\\n function deploy(bytes memory _initCode, bytes32 _salt) external returns (address);\\n}\\n\\ncontract EntryPoint is StakeManager {\\n\\n using UserOperationLib for UserOperation;\\n // paymaster locked stake\\n // (actual stake should be higher, to cover actual call cost)\\n uint256 constant PAYMASTER_STAKE = 1 ether;\\n\\n enum PaymentMode {\\n paymasterStake, // if paymaster is set, use paymaster's stake to pay.\\n walletStake, // wallet has enough stake to pay for request.\\n walletEth // wallet has no stake. paying with eth.\\n }\\n\\n uint public immutable perOpOverhead;\\n address public immutable create2factory;\\n\\n event UserOperationEvent(address indexed sender, address indexed paymaster, uint nonce, uint actualGasCost, uint actualGasPrice, bool success);\\n event UserOperationRevertReason(address indexed sender, uint nonce, bytes revertReason);\\n\\n event PaymasterPostOpFailed(address indexed sender, address indexed paymaster, uint nonce, bytes reason);\\n\\n //handleOps reverts with this error struct, to mark the offending op\\n // NOTE: if simulateOp passes successfully, there should be no reason for handleOps to fail on it.\\n // @param opIndex - index into the array of ops to the failed one (in simulateOp, this is always zero)\\n // @param paymaster - if paymaster.verifyPaymasterUserOp fails, this will be the paymaster's address. if verifyUserOp failed,\\n // this value will be zero (since it failed before accessing the paymaster)\\n // @param reason - revert reason\\n // only to aid troubleshooting of wallet/paymaster reverts\\n error FailedOp(uint opIndex, address paymaster, string reason);\\n\\n constructor(address _create2factory, uint _perOpOverhead, uint32 _unstakeDelayBlocks) StakeManager(_unstakeDelayBlocks) {\\n create2factory = _create2factory;\\n perOpOverhead = _perOpOverhead;\\n }\\n\\n receive() external payable {}\\n\\n /**\\n * Execute the given UserOperation.\\n * @param op the operation to execute\\n * @param redeemer the contract to redeem the fee\\n */\\n function handleOp(UserOperation calldata op, address payable redeemer) public {\\n\\n uint preGas = gasleft();\\n\\n (uint256 prefund, PaymentMode paymentMode, bytes memory context) = _validatePrepayment(0, op);\\n uint preOpGas = preGas - gasleft() + perOpOverhead;\\n\\n uint actualGasCost;\\n\\n try this.internalHandleOp(op, context, preOpGas, prefund, paymentMode) returns (uint _actualGasCost) {\\n actualGasCost = _actualGasCost;\\n } catch {\\n uint actualGas = preGas - gasleft() + preOpGas;\\n actualGasCost = handlePostOp(IPaymaster.PostOpMode.postOpReverted, op, context, actualGas, prefund, paymentMode);\\n }\\n\\n redeem(redeemer, actualGasCost);\\n }\\n\\n function redeem(address payable redeemer, uint amount) internal {\\n redeemer.transfer(amount);\\n }\\n\\n function handleOps(UserOperation[] calldata ops, address payable redeemer) public {\\n\\n uint opslen = ops.length;\\n uint256[] memory preOpGas = new uint256[](opslen);\\n bytes32[] memory contexts = new bytes32[](opslen);\\n uint256[] memory prefunds = new uint256[](opslen);\\n PaymentMode[] memory paymentModes = new PaymentMode[](opslen);\\n\\n for (uint i = 0; i < opslen; i++) {\\n uint preGas = gasleft();\\n UserOperation calldata op = ops[i];\\n\\n bytes memory context;\\n bytes32 contextOffset;\\n (prefunds[i], paymentModes[i], context) = _validatePrepayment(i, op);\\n assembly {contextOffset := context}\\n contexts[i] = contextOffset;\\n preOpGas[i] = preGas - gasleft() + perOpOverhead;\\n }\\n\\n uint collected = 0;\\n\\n for (uint i = 0; i < ops.length; i++) {\\n uint preGas = gasleft();\\n UserOperation calldata op = ops[i];\\n bytes32 contextOffset = contexts[i];\\n bytes memory context;\\n assembly {context := contextOffset}\\n uint preOpGasi = preOpGas[i];\\n uint prefundi = prefunds[i];\\n PaymentMode paymentModei = paymentModes[i];\\n\\n try this.internalHandleOp(op, context, preOpGasi, prefundi, paymentModei) returns (uint _actualGasCost) {\\n collected += _actualGasCost;\\n } catch {\\n uint actualGas = preGas - gasleft() + preOpGasi;\\n collected += handlePostOp(IPaymaster.PostOpMode.postOpReverted, op, context, actualGas, prefundi, paymentModei);\\n }\\n }\\n\\n redeem(redeemer, collected);\\n }\\n\\n function internalHandleOp(UserOperation calldata op, bytes calldata context, uint preOpGas, uint prefund, PaymentMode paymentMode) external returns (uint actualGasCost) {\\n uint preGas = gasleft();\\n require(msg.sender == address(this));\\n\\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\\n if (op.callData.length > 0) {\\n\\n (bool success,bytes memory result) = address(op.getSender()).call{gas : op.callGas}(op.callData);\\n if (!success && result.length > 0) {\\n emit UserOperationRevertReason(op.getSender(), op.nonce, result);\\n mode = IPaymaster.PostOpMode.opReverted;\\n }\\n }\\n\\n uint actualGas = preGas - gasleft() + preOpGas;\\n return handlePostOp(mode, op, context, actualGas, prefund, paymentMode);\\n }\\n\\n /**\\n * Simulate a call for wallet.verifyUserOp.\\n * Call must not revert.\\n * @return gasUsedByPayForSelfOp - gas used by the validation, to pass into simulatePaymasterValidation.\\n * The node must also verify it doesn't use banned opcode, and that it doesn't reference storage outside the wallet's data\\n */\\n function simulateWalletValidation(UserOperation calldata userOp) external returns (uint gasUsedByPayForSelfOp){\\n require(msg.sender == address(0), \\\"must be called off-chain with from=zero-addr\\\");\\n (uint requiredPreFund, PaymentMode paymentMode) = getPaymentInfo(userOp);\\n (gasUsedByPayForSelfOp,) = _validateWalletPrepayment(0, userOp, requiredPreFund, paymentMode);\\n }\\n\\n function getPaymentInfo(UserOperation calldata userOp) internal view returns (uint requiredPrefund, PaymentMode paymentMode) {\\n requiredPrefund = userOp.requiredPreFund(perOpOverhead);\\n if (userOp.hasPaymaster()) {\\n paymentMode = PaymentMode.paymasterStake;\\n } else if (isStaked(userOp.getSender(), requiredPrefund, 0)) {\\n paymentMode = PaymentMode.walletStake;\\n } else {\\n paymentMode = PaymentMode.walletEth;\\n }\\n }\\n\\n /**\\n * Simulate a call to paymaster.verifyPaymasterUserOp\\n * do nothing if has no paymaster.\\n * @param userOp the user operation to validate.\\n * @param gasUsedByPayForSelfOp - the gas returned by simulateWalletValidation, as these 2 calls should share\\n * the same userOp.validationGas quota.\\n * The node must also verify it doesn't use banned opcode, and that it doesn't reference storage outside the paymaster's data\\n */\\n function simulatePaymasterValidation(UserOperation calldata userOp, uint gasUsedByPayForSelfOp) external view returns (bytes memory context, uint gasUsedByPayForOp){\\n (uint requiredPreFund, PaymentMode paymentMode) = getPaymentInfo(userOp);\\n if (paymentMode != PaymentMode.paymasterStake) {\\n return (\\\"\\\", 0);\\n }\\n return _validatePaymasterPrepayment(0, userOp, requiredPreFund, gasUsedByPayForSelfOp);\\n }\\n\\n // get the sender address, or use \\\"create2\\\" to create it.\\n // note that the gas allocation for this creation is deterministic (by the size of callData),\\n // so it is not checked on-chain, and adds to the gas used by verifyUserOp\\n function _createSenderIfNeeded(UserOperation calldata op) internal {\\n if (op.initCode.length != 0) {\\n //its a create operation. run the create2\\n // note that we're still under the gas limit of validate, so probably\\n // this create2 creates a proxy account.\\n // appending signer makes the request unique, so no one else can make this request.\\n //nonce is meaningless during create, so we re-purpose it as salt\\n address sender1 = ICreate2Deployer(create2factory).deploy(op.initCode, bytes32(op.nonce));\\n require(sender1 != address(0), \\\"create2 failed\\\");\\n require(sender1 == op.getSender(), \\\"sender doesn't match create2 address\\\");\\n }\\n }\\n\\n //get counterfactual sender address.\\n // use the initCode and salt in the UserOperation tot create this sender contract\\n function getSenderAddress(bytes memory initCode, uint _salt) public view returns (address) {\\n bytes32 hash = keccak256(\\n abi.encodePacked(\\n bytes1(0xff),\\n address(create2factory),\\n _salt,\\n keccak256(initCode)\\n )\\n );\\n\\n // NOTE: cast last 20 bytes of hash to address\\n return address(uint160(uint256(hash)));\\n }\\n\\n //call wallet.verifyUserOp, and validate that it paid as needed.\\n // return actual value sent from wallet to \\\"this\\\"\\n function _validateWalletPrepayment(uint opIndex, UserOperation calldata op, uint requiredPrefund, PaymentMode paymentMode) internal returns (uint gasUsedByPayForSelfOp, uint prefund) {\\n uint preGas = gasleft();\\n _createSenderIfNeeded(op);\\n uint preBalance = address(this).balance;\\n uint requiredEthPrefund = 0;\\n if (paymentMode == PaymentMode.walletEth) {\\n requiredEthPrefund = requiredPrefund;\\n } else if (paymentMode == PaymentMode.walletStake) {\\n _prefundFromSender(op, requiredPrefund);\\n } else {\\n // paymaster pays in handlePostOp\\n }\\n try IWallet(op.getSender()).verifyUserOp{gas : op.verificationGas}(op, requiredEthPrefund) {\\n } catch Error(string memory revertReason) {\\n revert FailedOp(opIndex, address(0), revertReason);\\n } catch {\\n revert FailedOp(opIndex, address(0), \\\"\\\");\\n }\\n uint actualEthPrefund = address(this).balance - preBalance;\\n\\n if (paymentMode == PaymentMode.walletEth) {\\n if (actualEthPrefund < requiredEthPrefund) {\\n revert FailedOp(opIndex, address(0), \\\"wallet didn't pay prefund\\\");\\n }\\n prefund = actualEthPrefund;\\n } else if (paymentMode == PaymentMode.walletStake) {\\n if (actualEthPrefund != 0) {\\n revert FailedOp(opIndex, address(0), \\\"using wallet stake but wallet paid eth\\\");\\n }\\n prefund = requiredPrefund;\\n } else {\\n if (actualEthPrefund != 0) {\\n revert FailedOp(opIndex, address(0), \\\"has paymaster but wallet paid\\\");\\n }\\n prefund = requiredPrefund;\\n }\\n\\n gasUsedByPayForSelfOp = preGas - gasleft();\\n }\\n\\n //validate paymaster.verifyPaymasterUserOp\\n function _validatePaymasterPrepayment(uint opIndex, UserOperation calldata op, uint requiredPreFund, uint gasUsedByPayForSelfOp) internal view returns (bytes memory context, uint gasUsedByPayForOp) {\\n uint preGas = gasleft();\\n if (!isValidStake(op, requiredPreFund)) {\\n revert FailedOp(opIndex, op.paymaster, \\\"not enough stake\\\");\\n }\\n //no pre-pay from paymaster\\n uint gas = op.verificationGas - gasUsedByPayForSelfOp;\\n try IPaymaster(op.paymaster).verifyPaymasterUserOp{gas : gas}(op, requiredPreFund) returns (bytes memory _context){\\n context = _context;\\n } catch Error(string memory revertReason) {\\n revert FailedOp(opIndex, op.paymaster, revertReason);\\n } catch {\\n revert FailedOp(opIndex, op.paymaster, \\\"\\\");\\n }\\n gasUsedByPayForOp = preGas - gasleft();\\n }\\n\\n function _validatePrepayment(uint opIndex, UserOperation calldata userOp) private returns (uint prefund, PaymentMode paymentMode, bytes memory context){\\n\\n uint preGas = gasleft();\\n uint gasUsedByPayForSelfOp;\\n uint requiredPreFund;\\n (requiredPreFund, paymentMode) = getPaymentInfo(userOp);\\n\\n (gasUsedByPayForSelfOp, prefund) = _validateWalletPrepayment(opIndex, userOp, requiredPreFund, paymentMode);\\n\\n uint gasUsedByPayForOp = 0;\\n if (paymentMode == PaymentMode.paymasterStake) {\\n (context, gasUsedByPayForOp) = _validatePaymasterPrepayment(opIndex, userOp, requiredPreFund, gasUsedByPayForSelfOp);\\n } else {\\n context = \\\"\\\";\\n }\\n uint gasUsed = preGas - gasleft();\\n\\n if (userOp.verificationGas < gasUsed) {\\n revert FailedOp(opIndex, userOp.paymaster, \\\"Used more than verificationGas\\\");\\n }\\n }\\n\\n function getPaymastersStake(address[] calldata paymasters) external view returns (uint[] memory _stakes) {\\n _stakes = new uint[](paymasters.length);\\n for (uint i = 0; i < paymasters.length; i++) {\\n _stakes[i] = stakes[paymasters[i]].stake;\\n }\\n }\\n\\n function handlePostOp(IPaymaster.PostOpMode mode, UserOperation calldata op, bytes memory context, uint actualGas, uint prefund, PaymentMode paymentMode) private returns (uint actualGasCost) {\\n uint preGas = gasleft();\\n uint gasPrice = UserOperationLib.gasPrice(op);\\n actualGasCost = actualGas * gasPrice;\\n if (paymentMode != PaymentMode.paymasterStake) {\\n if (prefund < actualGasCost) {\\n revert (\\\"wallet prefund below actualGasCost\\\");\\n }\\n uint refund = prefund - actualGasCost;\\n if (paymentMode == PaymentMode.walletStake) {\\n _refundSenderStake(op, refund);\\n } else {\\n _refundSender(op, refund);\\n }\\n } else {\\n if (context.length > 0) {\\n //if paymaster.postOp reverts:\\n // - emit a message (just for sake of debugging of this poor paymaster)\\n // - paymaster still pays (from its stake)\\n try IPaymaster(op.paymaster).postOp(mode, context, actualGasCost) {}\\n catch (bytes memory errdata) {\\n emit PaymasterPostOpFailed(op.getSender(), op.paymaster, op.nonce, errdata);\\n }\\n }\\n //paymaster pays for full gas, including for postOp (and revert event)\\n actualGas += preGas - gasleft();\\n actualGasCost = actualGas * gasPrice;\\n //paymaster balance known to be high enough, and to be locked for this block\\n stakes[op.paymaster].stake -= uint96(actualGasCost);\\n }\\n _emitLog(op, actualGasCost, gasPrice, mode == IPaymaster.PostOpMode.opSucceeded);\\n }\\n\\n function _emitLog(UserOperation calldata op, uint actualGasCost, uint gasPrice, bool success) internal {\\n emit UserOperationEvent(op.getSender(), op.paymaster, op.nonce, actualGasCost, gasPrice, success);\\n }\\n\\n function _prefundFromSender(UserOperation calldata userOp, uint requiredPrefund) internal {\\n stakes[userOp.getSender()].stake -= uint96(requiredPrefund);\\n }\\n\\n function _refundSender(UserOperation calldata userOp, uint refund) internal {\\n //NOTE: deliberately ignoring revert: wallet should accept refund.\\n bool sendOk = payable(userOp.getSender()).send(refund);\\n (sendOk);\\n }\\n function _refundSenderStake(UserOperation calldata userOp, uint refund) internal {\\n stakes[userOp.getSender()].stake += uint96(refund);\\n }\\n\\n function isValidStake(UserOperation calldata userOp, uint requiredPreFund) internal view returns (bool) {\\n return isPaymasterStaked(userOp.paymaster, PAYMASTER_STAKE + requiredPreFund);\\n }\\n\\n function isPaymasterStaked(address paymaster, uint stake) public view returns (bool) {\\n return isStaked(paymaster, stake, unstakeDelayBlocks);\\n }\\n\\n function isContractDeployed(address addr) external view returns (bool) {\\n bytes32 hash;\\n assembly {\\n hash := extcodehash(addr)\\n }\\n return hash != bytes32(0);\\n }\\n}\\n\\n\",\"keccak256\":\"0x8b15a6fcb66f95fc079400ff2b38de805405ce6c23c4bbbc1bcd24bb6cabefb0\",\"license\":\"GPL-3.0\"},\"contracts/IPaymaster.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IPaymaster {\\n\\n enum PostOpMode {\\n opSucceeded, // user op succeeded\\n opReverted, // user op reverted. still has to pay for gas.\\n postOpReverted //user op succeeded, but caused postOp to revert. Now its a 2nd call, after user's op was deliberately reverted.\\n }\\n // payment validation: check if paymaster agree to pay (using its stake)\\n // revert to reject this request.\\n // actual payment is done after postOp is called, by deducting actual call cost form the paymaster's stake.\\n // @param userOp the user operation\\n // @param maxcost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\\n // @returns context value to send to a postOp\\n // zero length to signify postOp is not required.\\n function verifyPaymasterUserOp(UserOperation calldata userOp, uint maxcost) external view returns (bytes memory context);\\n\\n // post-operation handler.\\n // @param mode\\n // opSucceeded - user operation succeeded.\\n // opReverted - user op reverted. still has to pay for gas.\\n // postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\\n // Now this is the 2nd call, after user's op was deliberately reverted.\\n // @param context - the context value returned by verifyPaymasterUserOp\\n // @param actualGasCost - actual gas used so far (without this postOp call).\\n function postOp(PostOpMode mode, bytes calldata context, uint actualGasCost) external;\\n}\\n\",\"keccak256\":\"0xef51907c5520d22e74cc7804b30634cdc6d2cbf2fe96b77d0b6785a53c4545a5\",\"license\":\"GPL-3.0\"},\"contracts/IWallet.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IWallet {\\n\\n // validate user's signature and nonce\\n // @param requiredPrefund how much this wallet should pre-fund the transaction.\\n // @note that after execution, the excess is sent back to the wallet.\\n // @note if requiredPrefund is zero, the wallet MUST NOT send anything (the paymaster pays)\\n function verifyUserOp(UserOperation calldata userOp, uint requiredPrefund) external;\\n}\\n\",\"keccak256\":\"0x29f98a4e6033cd10007dcc9b569fda950413cc91d8560a67f20a35e8185c9228\",\"license\":\"GPL-3.0\"},\"contracts/StakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8;\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\ncontract StakeManager {\\n\\n /// minimum number of blocks to after 'unlock' before amount can be withdrawn.\\n uint32 immutable public unstakeDelayBlocks;\\n\\n constructor(uint32 _unstakeDelayBlocks) {\\n unstakeDelayBlocks = _unstakeDelayBlocks;\\n }\\n\\n event StakeAdded(\\n address indexed paymaster,\\n uint256 totalStake,\\n uint256 unstakeDelayBlocks\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocking(\\n address indexed paymaster,\\n uint256 withdrawBlock\\n );\\n\\n event StakeWithdrawn(\\n address indexed paymaster,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// @param stake - amount of ether staked for this paymaster\\n /// @param withdrawStake - once 'unlocked' the value is no longer staked.\\n /// @param withdrawBlock - first block number 'withdraw' will be callable, or zero if the unlock has not been called\\n struct StakeInfo {\\n uint96 stake;\\n uint32 unstakeDelayBlocks;\\n uint96 withdrawStake;\\n uint32 withdrawBlock;\\n }\\n\\n /// maps relay managers to their stakes\\n mapping(address => StakeInfo) public stakes;\\n\\n function getStakeInfo(address paymaster) external view returns (StakeInfo memory stakeInfo) {\\n return stakes[paymaster];\\n }\\n\\n /**\\n * add a deposit (just like stake, but with lock=0\\n * cancel any pending unlock\\n */\\n function addDeposit() external payable {\\n addStake(0);\\n }\\n\\n //add deposit to another account (doesn't change lock status)\\n function addDepositTo(address target) external payable {\\n stakes[target].stake += uint96(msg.value);\\n }\\n\\n /**\\n * add stake value for this paymaster.\\n * cancel any pending unlock\\n */\\n function addStake(uint32 _unstakeDelayBlocks) public payable {\\n require(_unstakeDelayBlocks >= stakes[msg.sender].unstakeDelayBlocks, \\\"cannot decrease unstake blocks\\\");\\n uint96 stake = uint96(stakes[msg.sender].stake + msg.value + stakes[msg.sender].withdrawStake);\\n stakes[msg.sender] = StakeInfo(\\n stake,\\n _unstakeDelayBlocks,\\n 0,\\n 0);\\n emit StakeAdded(msg.sender, stake, _unstakeDelayBlocks);\\n }\\n\\n function unlockStake() external {\\n StakeInfo storage info = stakes[msg.sender];\\n require(info.withdrawBlock == 0, \\\"already pending\\\");\\n require(info.stake != 0 && info.unstakeDelayBlocks != 0, \\\"no stake to unlock\\\");\\n uint32 withdrawBlock = uint32(block.number) + info.unstakeDelayBlocks;\\n info.withdrawBlock = withdrawBlock;\\n info.withdrawStake = info.stake;\\n info.stake = 0;\\n emit StakeUnlocking(msg.sender, withdrawBlock);\\n }\\n\\n function withdrawStake(address payable withdrawAddress) external {\\n StakeInfo memory info = stakes[msg.sender];\\n if (info.unstakeDelayBlocks != 0) {\\n require(info.withdrawStake > 0, \\\"no unlocked stake\\\");\\n require(info.withdrawBlock <= block.number, \\\"Withdrawal is not due\\\");\\n }\\n uint256 amount = info.withdrawStake + info.stake;\\n stakes[msg.sender] = StakeInfo(0, info.unstakeDelayBlocks, 0, 0);\\n withdrawAddress.transfer(amount);\\n emit StakeWithdrawn(msg.sender, withdrawAddress, amount);\\n }\\n\\n function isStaked(address paymaster, uint requiredStake, uint requiredDelayBlocks) public view returns (bool) {\\n StakeInfo memory stakeInfo = stakes[paymaster];\\n return stakeInfo.stake >= requiredStake && stakeInfo.unstakeDelayBlocks >= requiredDelayBlocks;\\n }\\n}\\n\",\"keccak256\":\"0x238f903aceaaa89fd289d99c16ff660b6f911837f50ccf3fc3bb94653024b1aa\",\"license\":\"GPL-3.0-only\"},\"contracts/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n struct UserOperation {\\n\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint callGas;\\n uint verificationGas;\\n uint preVerificationGas;\\n uint maxFeePerGas;\\n uint maxPriorityFeePerGas;\\n address paymaster;\\n bytes paymasterData;\\n bytes signature;\\n }\\n\\nlibrary UserOperationLib {\\n\\n function getSender(UserOperation calldata userOp) internal view returns (address ret) {\\n assembly {ret := calldataload(userOp)}\\n }\\n\\n //relayer/miner might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(UserOperation calldata userOp) internal view returns (uint) {\\n unchecked {\\n return min(userOp.maxFeePerGas, userOp.maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function requiredGas(UserOperation calldata userOp) internal pure returns (uint) {\\n unchecked {\\n return userOp.callGas + userOp.verificationGas + userOp.preVerificationGas;\\n }\\n }\\n\\n function requiredPreFund(UserOperation calldata userOp, uint overhead) internal view returns (uint prefund) {\\n return (requiredGas(userOp) + overhead) * gasPrice(userOp);\\n }\\n\\n function hasPaymaster(UserOperation calldata userOp) internal pure returns (bool) {\\n return userOp.paymaster != address(0);\\n }\\n\\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\\n //lighter signature scheme. must match UserOp.ts#packUserOp\\n bytes calldata sig = userOp.signature;\\n assembly {\\n let ofs := userOp\\n let len := sub(sub(sig.offset, ofs), 32)\\n ret := mload(0x40)\\n mstore(0x40, add(ret, add(len, 32)))\\n mstore(ret, len)\\n calldatacopy(add(ret, 32), ofs, len)\\n }\\n return ret;\\n\\n //TODO: eip712-style ?\\n return abi.encode(\\n userOp.sender,\\n userOp.nonce,\\n keccak256(userOp.initCode),\\n keccak256(userOp.callData),\\n userOp.callGas,\\n userOp.verificationGas,\\n userOp.preVerificationGas,\\n userOp.maxFeePerGas,\\n userOp.maxPriorityFeePerGas,\\n userOp.paymaster,\\n keccak256(userOp.paymasterData)\\n );\\n }\\n\\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(pack(userOp))));\\n }\\n\\n function min(uint a, uint b) internal pure returns (uint) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x7ea8383b9bbd8cfa5a96f59e1f37c20a681daa798b80d67eb52ade3c53f3ea30\",\"license\":\"GPL-3.0\"},\"contracts/samples/SimpleWallet.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"../IWallet.sol\\\";\\nimport \\\"../EntryPoint.sol\\\";\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n//minimal wallet\\n// this is sample minimal wallet.\\n// has execute, eth handling methods\\n// has a single signer that can send requests through the entryPoint.\\ncontract SimpleWallet is IWallet {\\n using UserOperationLib for UserOperation;\\n struct OwnerNonce {\\n uint96 nonce;\\n address owner;\\n }\\n OwnerNonce ownerNonce;\\n EntryPoint public entryPoint;\\n\\n function nonce() public view returns (uint) {\\n return ownerNonce.nonce;\\n }\\n\\n function owner() public view returns(address) {\\n return ownerNonce.owner;\\n }\\n\\n event EntryPointChanged(EntryPoint oldEntryPoint, EntryPoint newEntryPoint);\\n\\n receive() external payable {}\\n\\n constructor(EntryPoint _entryPoint, address _owner) {\\n entryPoint = _entryPoint;\\n ownerNonce.owner = _owner;\\n }\\n\\n modifier onlyOwner() {\\n _onlyOwner();\\n _;\\n }\\n\\n function _onlyOwner() internal view {\\n //directly from EOA owner, or through the entryPoint (which gets redirected through execFromEntryPoint)\\n require(msg.sender == ownerNonce.owner || msg.sender == address(this), \\\"only owner\\\");\\n }\\n\\n function transfer(address payable dest, uint amount) external onlyOwner {\\n dest.transfer(amount);\\n }\\n\\n function exec(address dest, uint value, bytes calldata func) external onlyOwner {\\n _call(dest, value, func);\\n }\\n\\n function updateEntryPoint(EntryPoint _entryPoint) external onlyOwner {\\n emit EntryPointChanged(entryPoint, _entryPoint);\\n entryPoint = _entryPoint;\\n }\\n\\n function _requireFromEntryPoint() internal view {\\n require(msg.sender == address(entryPoint), \\\"wallet: not from EntryPoint\\\");\\n }\\n\\n function verifyUserOp(UserOperation calldata userOp, uint requiredPrefund) external override {\\n _requireFromEntryPoint();\\n _validateSignature(userOp);\\n _validateAndIncrementNonce(userOp);\\n _payPrefund(requiredPrefund);\\n }\\n\\n function _payPrefund(uint requiredPrefund) internal {\\n if (requiredPrefund != 0) {\\n (bool success) = payable(msg.sender).send(requiredPrefund);\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not wallet.)\\n }\\n }\\n\\n //called by entryPoint, only after verifyUserOp succeeded.\\n function execFromEntryPoint(address dest, uint value, bytes calldata func) external {\\n _requireFromEntryPoint();\\n _call(dest, value, func);\\n }\\n\\n function _validateAndIncrementNonce(UserOperation calldata userOp) internal {\\n //during construction, the \\\"nonce\\\" field hold the salt.\\n // if we assert it is zero, then we allow only a single wallet per owner.\\n if (userOp.initCode.length == 0) {\\n require(ownerNonce.nonce++ == userOp.nonce, \\\"wallet: invalid nonce\\\");\\n }\\n }\\n\\n function _validateSignature(UserOperation calldata userOp) internal view {\\n\\n bytes32 hash = userOp.hash();\\n (bytes32 r, bytes32 s, uint8 v) = _rsv(userOp.signature);\\n\\n require(owner() == _ecrecover(hash, v, r, s), \\\"wallet: wrong signature\\\");\\n }\\n\\n function _rsv(bytes calldata signature) internal pure returns (bytes32 r, bytes32 s, uint8 v) {\\n\\n require(signature.length == 65, \\\"wallet: invalid signature length\\\");\\n assembly {\\n r := calldataload(signature.offset)\\n s := calldataload(add(signature.offset, 0x20))\\n v := byte(0, calldataload(add(signature.offset, 0x40)))\\n }\\n }\\n\\n function _ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n return ecrecover(hash, v, r, s);\\n }\\n\\n function _call(address sender, uint value, bytes memory data) internal {\\n (bool success, bytes memory result) = sender.call{value : value}(data);\\n if (!success) {\\n assembly {\\n revert(result, add(result, 32))\\n }\\n }\\n }\\n\\n function addDeposit() public payable {\\n entryPoint.addDeposit{value : msg.value}();\\n }\\n\\n function withdrawDeposit(address payable withdrawAddress) public {\\n entryPoint.withdrawStake(withdrawAddress);\\n }\\n}\\n\",\"keccak256\":\"0xf3afea609dd9502a958ce8dbbef6fd2271663c750d356cf911a082f2fa4e7d4b\",\"license\":\"GPL-3.0\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"keccak256\":\"0x72b6a1d297cd3b033d7c2e4a7e7864934bb767db6453623f1c3082c6534547f4\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50604051610aed380380610aed83398101604081905261002f91610077565b600180546001600160a01b039384166001600160a01b031990911617905560008054919092166c01000000000000000000000000026001600160601b039091161790556100c9565b6000806040838503121561008a57600080fd5b8251610095816100b1565b60208401519092506100a6816100b1565b809150509250929050565b6001600160a01b03811681146100c657600080fd5b50565b610a15806100d86000396000f3fe6080604052600436106100955760003560e01c80638da5cb5b116100595780638da5cb5b1461012b578063a9059cbb14610169578063affed0e014610189578063b0d691fe146101b0578063fbfb39e0146101d057600080fd5b80630565bb67146100a15780631b71bb6e146100c35780634a58db19146100e357806351e41700146100eb57806380c5c7d01461010b57600080fd5b3661009c57005b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610846565b6101f0565b005b3480156100cf57600080fd5b506100c16100de3660046107f6565b61023f565b6100c16102b0565b3480156100f757600080fd5b506100c16101063660046107f6565b61031b565b34801561011757600080fd5b506100c1610126366004610846565b610362565b34801561013757600080fd5b50600054600160601b90046001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b34801561017557600080fd5b506100c161018436600461081a565b61036a565b34801561019557600080fd5b506000546001600160601b0316604051908152602001610160565b3480156101bc57600080fd5b5060015461014c906001600160a01b031681565b3480156101dc57600080fd5b506100c16101eb3660046108cf565b6103ad565b6101f86103d4565b610239848484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061043392505050565b50505050565b6102476103d4565b600154604080516001600160a01b03928316815291831660208301527f450909c1478d09248269d4ad4fa8cba61ca3f50faed58c7aedefa51c7f62b83a910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b600160009054906101000a90046001600160a01b03166001600160a01b0316634a58db19346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561030057600080fd5b505af1158015610314573d6000803e3d6000fd5b5050505050565b60015460405163611d2e7560e11b81526001600160a01b0383811660048301529091169063c23a5cea90602401600060405180830381600087803b15801561030057600080fd5b6101f86104a2565b6103726103d4565b6040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156103a8573d6000803e3d6000fd5b505050565b6103b56104a2565b6103be826104fc565b6103c7826105ae565b6103d081610658565b5050565b600054600160601b90046001600160a01b03163314806103f357503330145b6104315760405162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b60448201526064015b60405180910390fd5b565b600080846001600160a01b0316848460405161044f919061090c565b60006040518083038185875af1925050503d806000811461048c576040519150601f19603f3d011682016040523d82523d6000602084013e610491565b606091505b509150915081610314576020810181fd5b6001546001600160a01b031633146104315760405162461bcd60e51b815260206004820152601b60248201527f77616c6c65743a206e6f742066726f6d20456e747279506f696e7400000000006044820152606401610428565b600061050782610680565b90506000808061052361051e610160870187610947565b6106e3565b9250925092506105358482858561074f565b6001600160a01b03166105586000546001600160a01b03600160601b9091041690565b6001600160a01b0316146103145760405162461bcd60e51b815260206004820152601760248201527f77616c6c65743a2077726f6e67207369676e61747572650000000000000000006044820152606401610428565b6105bb6040820182610947565b1515905061065557600080546020830135916001600160601b0390911690806105e383610995565b91906101000a8154816001600160601b0302191690836001600160601b031602179055506001600160601b0316146106555760405162461bcd60e51b815260206004820152601560248201527477616c6c65743a20696e76616c6964206e6f6e636560581b6044820152606401610428565b50565b801561065557604051600090339083156108fc0290849084818181858888f150505050505050565b600061068b826107b7565b80516020918201206040517f19457468657265756d205369676e6564204d6573736167653a0a33320000000092810192909252603c820152605c01604051602081830303815290604052805190602001209050919050565b60008080604184146107375760405162461bcd60e51b815260206004820181905260248201527f77616c6c65743a20696e76616c6964207369676e6174757265206c656e6774686044820152606401610428565b50508235936020840135936040013560001a92509050565b6040805160008082526020820180845287905260ff861692820192909252606081018490526080810183905260019060a0016020604051602081039080840390855afa1580156107a3573d6000803e3d6000fd5b5050604051601f1901519695505050505050565b60603660006107ca610160850185610947565b915091508360208184030360405194506020810185016040528085528082602087013750505050919050565b60006020828403121561080857600080fd5b8135610813816109ca565b9392505050565b6000806040838503121561082d57600080fd5b8235610838816109ca565b946020939093013593505050565b6000806000806060858703121561085c57600080fd5b8435610867816109ca565b935060208501359250604085013567ffffffffffffffff8082111561088b57600080fd5b818701915087601f83011261089f57600080fd5b8135818111156108ae57600080fd5b8860208285010111156108c057600080fd5b95989497505060200194505050565b600080604083850312156108e257600080fd5b823567ffffffffffffffff8111156108f957600080fd5b8301610180818603121561083857600080fd5b6000825160005b8181101561092d5760208186018101518583015201610913565b8181111561093c576000828501525b509190910192915050565b6000808335601e1984360301811261095e57600080fd5b83018035915067ffffffffffffffff82111561097957600080fd5b60200191503681900382131561098e57600080fd5b9250929050565b60006001600160601b03808316818114156109c057634e487b7160e01b600052601160045260246000fd5b6001019392505050565b6001600160a01b038116811461065557600080fdfea264697066735822122060a95252b25b23dd208aa04a5a7d75efffd9ee1f7980d087a2ac978cfed715bd64736f6c63430008070033",
+ "deployedBytecode": "0x6080604052600436106100955760003560e01c80638da5cb5b116100595780638da5cb5b1461012b578063a9059cbb14610169578063affed0e014610189578063b0d691fe146101b0578063fbfb39e0146101d057600080fd5b80630565bb67146100a15780631b71bb6e146100c35780634a58db19146100e357806351e41700146100eb57806380c5c7d01461010b57600080fd5b3661009c57005b600080fd5b3480156100ad57600080fd5b506100c16100bc366004610846565b6101f0565b005b3480156100cf57600080fd5b506100c16100de3660046107f6565b61023f565b6100c16102b0565b3480156100f757600080fd5b506100c16101063660046107f6565b61031b565b34801561011757600080fd5b506100c1610126366004610846565b610362565b34801561013757600080fd5b50600054600160601b90046001600160a01b03165b6040516001600160a01b0390911681526020015b60405180910390f35b34801561017557600080fd5b506100c161018436600461081a565b61036a565b34801561019557600080fd5b506000546001600160601b0316604051908152602001610160565b3480156101bc57600080fd5b5060015461014c906001600160a01b031681565b3480156101dc57600080fd5b506100c16101eb3660046108cf565b6103ad565b6101f86103d4565b610239848484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061043392505050565b50505050565b6102476103d4565b600154604080516001600160a01b03928316815291831660208301527f450909c1478d09248269d4ad4fa8cba61ca3f50faed58c7aedefa51c7f62b83a910160405180910390a1600180546001600160a01b0319166001600160a01b0392909216919091179055565b600160009054906101000a90046001600160a01b03166001600160a01b0316634a58db19346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561030057600080fd5b505af1158015610314573d6000803e3d6000fd5b5050505050565b60015460405163611d2e7560e11b81526001600160a01b0383811660048301529091169063c23a5cea90602401600060405180830381600087803b15801561030057600080fd5b6101f86104a2565b6103726103d4565b6040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156103a8573d6000803e3d6000fd5b505050565b6103b56104a2565b6103be826104fc565b6103c7826105ae565b6103d081610658565b5050565b600054600160601b90046001600160a01b03163314806103f357503330145b6104315760405162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b60448201526064015b60405180910390fd5b565b600080846001600160a01b0316848460405161044f919061090c565b60006040518083038185875af1925050503d806000811461048c576040519150601f19603f3d011682016040523d82523d6000602084013e610491565b606091505b509150915081610314576020810181fd5b6001546001600160a01b031633146104315760405162461bcd60e51b815260206004820152601b60248201527f77616c6c65743a206e6f742066726f6d20456e747279506f696e7400000000006044820152606401610428565b600061050782610680565b90506000808061052361051e610160870187610947565b6106e3565b9250925092506105358482858561074f565b6001600160a01b03166105586000546001600160a01b03600160601b9091041690565b6001600160a01b0316146103145760405162461bcd60e51b815260206004820152601760248201527f77616c6c65743a2077726f6e67207369676e61747572650000000000000000006044820152606401610428565b6105bb6040820182610947565b1515905061065557600080546020830135916001600160601b0390911690806105e383610995565b91906101000a8154816001600160601b0302191690836001600160601b031602179055506001600160601b0316146106555760405162461bcd60e51b815260206004820152601560248201527477616c6c65743a20696e76616c6964206e6f6e636560581b6044820152606401610428565b50565b801561065557604051600090339083156108fc0290849084818181858888f150505050505050565b600061068b826107b7565b80516020918201206040517f19457468657265756d205369676e6564204d6573736167653a0a33320000000092810192909252603c820152605c01604051602081830303815290604052805190602001209050919050565b60008080604184146107375760405162461bcd60e51b815260206004820181905260248201527f77616c6c65743a20696e76616c6964207369676e6174757265206c656e6774686044820152606401610428565b50508235936020840135936040013560001a92509050565b6040805160008082526020820180845287905260ff861692820192909252606081018490526080810183905260019060a0016020604051602081039080840390855afa1580156107a3573d6000803e3d6000fd5b5050604051601f1901519695505050505050565b60603660006107ca610160850185610947565b915091508360208184030360405194506020810185016040528085528082602087013750505050919050565b60006020828403121561080857600080fd5b8135610813816109ca565b9392505050565b6000806040838503121561082d57600080fd5b8235610838816109ca565b946020939093013593505050565b6000806000806060858703121561085c57600080fd5b8435610867816109ca565b935060208501359250604085013567ffffffffffffffff8082111561088b57600080fd5b818701915087601f83011261089f57600080fd5b8135818111156108ae57600080fd5b8860208285010111156108c057600080fd5b95989497505060200194505050565b600080604083850312156108e257600080fd5b823567ffffffffffffffff8111156108f957600080fd5b8301610180818603121561083857600080fd5b6000825160005b8181101561092d5760208186018101518583015201610913565b8181111561093c576000828501525b509190910192915050565b6000808335601e1984360301811261095e57600080fd5b83018035915067ffffffffffffffff82111561097957600080fd5b60200191503681900382131561098e57600080fd5b9250929050565b60006001600160601b03808316818114156109c057634e487b7160e01b600052601160045260246000fd5b6001019392505050565b6001600160a01b038116811461065557600080fdfea264697066735822122060a95252b25b23dd208aa04a5a7d75efffd9ee1f7980d087a2ac978cfed715bd64736f6c63430008070033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {},
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 2814,
+ "contract": "contracts/samples/SimpleWallet.sol:SimpleWallet",
+ "label": "ownerNonce",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_struct(OwnerNonce)2811_storage"
+ },
+ {
+ "astId": 2817,
+ "contract": "contracts/samples/SimpleWallet.sol:SimpleWallet",
+ "label": "entryPoint",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_contract(EntryPoint)2231"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_contract(EntryPoint)2231": {
+ "encoding": "inplace",
+ "label": "contract EntryPoint",
+ "numberOfBytes": "20"
+ },
+ "t_struct(OwnerNonce)2811_storage": {
+ "encoding": "inplace",
+ "label": "struct SimpleWallet.OwnerNonce",
+ "members": [
+ {
+ "astId": 2808,
+ "contract": "contracts/samples/SimpleWallet.sol:SimpleWallet",
+ "label": "nonce",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_uint96"
+ },
+ {
+ "astId": 2810,
+ "contract": "contracts/samples/SimpleWallet.sol:SimpleWallet",
+ "label": "owner",
+ "offset": 12,
+ "slot": "0",
+ "type": "t_address"
+ }
+ ],
+ "numberOfBytes": "32"
+ },
+ "t_uint96": {
+ "encoding": "inplace",
+ "label": "uint96",
+ "numberOfBytes": "12"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/TestCounter.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/TestCounter.json
new file mode 100644
index 00000000..0dbb2ce0
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/TestCounter.json
@@ -0,0 +1,118 @@
+{
+ "address": "0x4B52ceEDE2e695CAeDBC1Cc8E7f9d5Ef18F0EeF5",
+ "abi": [
+ {
+ "inputs": [],
+ "name": "count",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "counters",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "repeat",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "name": "gasWaster",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+ ],
+ "args": [],
+ "solcInputHash": "9255faacf3ae4e81db1326413027bfa0",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"count\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"counters\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"repeat\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"name\":\"gasWaster\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/test/TestCounter.sol\":\"TestCounter\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/IWallet.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IWallet {\\n\\n // validate user's signature and nonce\\n // @param requiredPrefund how much this wallet should pre-fund the transaction.\\n // @note that after execution, the excess is sent back to the wallet.\\n // @note if requiredPrefund is zero, the wallet MUST NOT send anything (the paymaster pays)\\n function verifyUserOp(UserOperation calldata userOp, uint requiredPrefund) external;\\n}\\n\",\"keccak256\":\"0x29f98a4e6033cd10007dcc9b569fda950413cc91d8560a67f20a35e8185c9228\",\"license\":\"GPL-3.0\"},\"contracts/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"hardhat/console.sol\\\";\\n\\n struct UserOperation {\\n\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint callGas;\\n uint verificationGas;\\n uint preVerificationGas;\\n uint maxFeePerGas;\\n uint maxPriorityFeePerGas;\\n address paymaster;\\n bytes paymasterData;\\n bytes signature;\\n }\\n\\nlibrary UserOperationLib {\\n\\n function getSender(UserOperation calldata userOp) internal view returns (address ret) {\\n assembly {ret := calldataload(userOp)}\\n }\\n\\n //relayer/miner might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(UserOperation calldata userOp) internal view returns (uint) {\\n unchecked {\\n return min(userOp.maxFeePerGas, userOp.maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function requiredGas(UserOperation calldata userOp) internal pure returns (uint) {\\n unchecked {\\n return userOp.callGas + userOp.verificationGas + userOp.preVerificationGas;\\n }\\n }\\n\\n function requiredPreFund(UserOperation calldata userOp, uint overhead) internal view returns (uint prefund) {\\n return (requiredGas(userOp) + overhead) * gasPrice(userOp);\\n }\\n\\n function hasPaymaster(UserOperation calldata userOp) internal pure returns (bool) {\\n return userOp.paymaster != address(0);\\n }\\n\\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\\n //lighter signature scheme. must match UserOp.ts#packUserOp\\n bytes calldata sig = userOp.signature;\\n assembly {\\n let ofs := userOp\\n let len := sub(sub(sig.offset, ofs), 32)\\n ret := mload(0x40)\\n mstore(0x40, add(ret, add(len, 32)))\\n mstore(ret, len)\\n calldatacopy(add(ret, 32), ofs, len)\\n }\\n return ret;\\n\\n //TODO: eip712-style ?\\n return abi.encode(\\n userOp.sender,\\n userOp.nonce,\\n keccak256(userOp.initCode),\\n keccak256(userOp.callData),\\n userOp.callGas,\\n userOp.verificationGas,\\n userOp.preVerificationGas,\\n userOp.maxFeePerGas,\\n userOp.maxPriorityFeePerGas,\\n userOp.paymaster,\\n keccak256(userOp.paymasterData)\\n );\\n }\\n\\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\",\\n keccak256(pack(userOp))));\\n }\\n\\n function min(uint a, uint b) internal pure returns (uint) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x7ea8383b9bbd8cfa5a96f59e1f37c20a681daa798b80d67eb52ade3c53f3ea30\",\"license\":\"GPL-3.0\"},\"contracts/test/TestCounter.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.7;\\n\\nimport \\\"../UserOperation.sol\\\";\\nimport \\\"../IWallet.sol\\\";\\n\\n//sample \\\"receiver\\\" contract, for testing \\\"exec\\\" from wallet.\\ncontract TestCounter {\\n mapping(address => uint) public counters;\\n\\n function count() public {\\n counters[msg.sender] = counters[msg.sender] + 1;\\n\\n }\\n\\n //helper method to waste gas\\n // repeat - waste gas on writing storage in a loop\\n // junk - dynamic buffer to stress the function size.\\n mapping(uint => uint) xxx;\\n uint offset;\\n\\n function gasWaster(uint repeat, string calldata /*junk*/) external {\\n for (uint i = 1; i <= repeat; i++) {\\n offset++;\\n xxx[offset] = i;\\n }\\n }\\n}\",\"keccak256\":\"0xfa15d72740c6ba7c1aca1925e27774b3701a585e866960ca70460ae55e0ae7d3\",\"license\":\"GPL-3.0\"},\"hardhat/console.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity >= 0.4.22 <0.9.0;\\n\\nlibrary console {\\n\\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\\n\\n\\tfunction _sendLogPayload(bytes memory payload) private view {\\n\\t\\tuint256 payloadLength = payload.length;\\n\\t\\taddress consoleAddress = CONSOLE_ADDRESS;\\n\\t\\tassembly {\\n\\t\\t\\tlet payloadStart := add(payload, 32)\\n\\t\\t\\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\\n\\t\\t}\\n\\t}\\n\\n\\tfunction log() internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log()\\\"));\\n\\t}\\n\\n\\tfunction logInt(int p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(int)\\\", p0));\\n\\t}\\n\\n\\tfunction logUint(uint p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint)\\\", p0));\\n\\t}\\n\\n\\tfunction logString(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction logBool(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction logAddress(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes(bytes memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes1(bytes1 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes1)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes2(bytes2 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes2)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes3(bytes3 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes3)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes4(bytes4 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes4)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes5(bytes5 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes5)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes6(bytes6 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes6)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes7(bytes7 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes7)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes8(bytes8 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes8)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes9(bytes9 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes9)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes10(bytes10 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes10)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes11(bytes11 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes11)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes12(bytes12 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes12)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes13(bytes13 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes13)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes14(bytes14 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes14)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes15(bytes15 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes15)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes16(bytes16 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes16)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes17(bytes17 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes17)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes18(bytes18 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes18)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes19(bytes19 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes19)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes20(bytes20 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes20)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes21(bytes21 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes21)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes22(bytes22 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes22)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes23(bytes23 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes23)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes24(bytes24 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes24)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes25(bytes25 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes25)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes26(bytes26 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes26)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes27(bytes27 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes27)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes28(bytes28 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes28)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes29(bytes29 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes29)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes30(bytes30 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes30)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes31(bytes31 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes31)\\\", p0));\\n\\t}\\n\\n\\tfunction logBytes32(bytes32 p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bytes32)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint)\\\", p0));\\n\\t}\\n\\n\\tfunction log(string memory p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string)\\\", p0));\\n\\t}\\n\\n\\tfunction log(bool p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool)\\\", p0));\\n\\t}\\n\\n\\tfunction log(address p0) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address)\\\", p0));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(address p0, address p1) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address)\\\", p0, p1));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address)\\\", p0, p1, p2));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(uint p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(uint,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(string,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(bool p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(bool,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, uint p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,uint,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,string,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, bool p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,bool,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, uint p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,uint,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,string,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, bool p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,bool,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, uint p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,uint)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,string)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, bool p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,bool)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n\\tfunction log(address p0, address p1, address p2, address p3) internal view {\\n\\t\\t_sendLogPayload(abi.encodeWithSignature(\\\"log(address,address,address,address)\\\", p0, p1, p2, p3));\\n\\t}\\n\\n}\\n\",\"keccak256\":\"0x72b6a1d297cd3b033d7c2e4a7e7864934bb767db6453623f1c3082c6534547f4\",\"license\":\"MIT\"}},\"version\":1}",
+ "bytecode": "0x608060405234801561001057600080fd5b50610238806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806306661abd14610046578063a1b4689014610050578063be65ab8c14610063575b600080fd5b61004e610095565b005b61004e61005e36600461013d565b6100c2565b61008361007136600461010d565b60006020819052908152604090205481565b60405190815260200160405180910390f35b336000908152602081905260409020546100b09060016101b9565b33600090815260208190526040902055565b60015b83811161010757600280549060006100dc836101d1565b90915550506002546000908152600160205260409020819055806100ff816101d1565b9150506100c5565b50505050565b60006020828403121561011f57600080fd5b81356001600160a01b038116811461013657600080fd5b9392505050565b60008060006040848603121561015257600080fd5b83359250602084013567ffffffffffffffff8082111561017157600080fd5b818601915086601f83011261018557600080fd5b81358181111561019457600080fd5b8760208285010111156101a657600080fd5b6020830194508093505050509250925092565b600082198211156101cc576101cc6101ec565b500190565b60006000198214156101e5576101e56101ec565b5060010190565b634e487b7160e01b600052601160045260246000fdfea26469706673582212202705b7732e8fc4fb811ca9240189d156e252ec8b1aef99971c2fc2cdbeb336d764736f6c63430008070033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806306661abd14610046578063a1b4689014610050578063be65ab8c14610063575b600080fd5b61004e610095565b005b61004e61005e36600461013d565b6100c2565b61008361007136600461010d565b60006020819052908152604090205481565b60405190815260200160405180910390f35b336000908152602081905260409020546100b09060016101b9565b33600090815260208190526040902055565b60015b83811161010757600280549060006100dc836101d1565b90915550506002546000908152600160205260409020819055806100ff816101d1565b9150506100c5565b50505050565b60006020828403121561011f57600080fd5b81356001600160a01b038116811461013657600080fd5b9392505050565b60008060006040848603121561015257600080fd5b83359250602084013567ffffffffffffffff8082111561017157600080fd5b818601915086601f83011261018557600080fd5b81358181111561019457600080fd5b8760208285010111156101a657600080fd5b6020830194508093505050509250925092565b600082198211156101cc576101cc6101ec565b500190565b60006000198214156101e5576101e56101ec565b5060010190565b634e487b7160e01b600052601160045260246000fdfea26469706673582212202705b7732e8fc4fb811ca9240189d156e252ec8b1aef99971c2fc2cdbeb336d764736f6c63430008070033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {},
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {},
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [
+ {
+ "astId": 3638,
+ "contract": "contracts/test/TestCounter.sol:TestCounter",
+ "label": "counters",
+ "offset": 0,
+ "slot": "0",
+ "type": "t_mapping(t_address,t_uint256)"
+ },
+ {
+ "astId": 3658,
+ "contract": "contracts/test/TestCounter.sol:TestCounter",
+ "label": "xxx",
+ "offset": 0,
+ "slot": "1",
+ "type": "t_mapping(t_uint256,t_uint256)"
+ },
+ {
+ "astId": 3660,
+ "contract": "contracts/test/TestCounter.sol:TestCounter",
+ "label": "offset",
+ "offset": 0,
+ "slot": "2",
+ "type": "t_uint256"
+ }
+ ],
+ "types": {
+ "t_address": {
+ "encoding": "inplace",
+ "label": "address",
+ "numberOfBytes": "20"
+ },
+ "t_mapping(t_address,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_address",
+ "label": "mapping(address => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_mapping(t_uint256,t_uint256)": {
+ "encoding": "mapping",
+ "key": "t_uint256",
+ "label": "mapping(uint256 => uint256)",
+ "numberOfBytes": "32",
+ "value": "t_uint256"
+ },
+ "t_uint256": {
+ "encoding": "inplace",
+ "label": "uint256",
+ "numberOfBytes": "32"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/solcInputs/9255faacf3ae4e81db1326413027bfa0.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/solcInputs/9255faacf3ae4e81db1326413027bfa0.json
new file mode 100644
index 00000000..5a05e3bb
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/kovan/solcInputs/9255faacf3ae4e81db1326413027bfa0.json
@@ -0,0 +1,86 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/EntryPoint.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.7;\n\nimport \"./StakeManager.sol\";\nimport \"./UserOperation.sol\";\nimport \"./IWallet.sol\";\nimport \"./IPaymaster.sol\";\n\ninterface ICreate2Deployer {\n function deploy(bytes memory _initCode, bytes32 _salt) external returns (address);\n}\n\ncontract EntryPoint is StakeManager {\n\n using UserOperationLib for UserOperation;\n // paymaster locked stake\n // (actual stake should be higher, to cover actual call cost)\n uint256 constant PAYMASTER_STAKE = 1 ether;\n\n enum PaymentMode {\n paymasterStake, // if paymaster is set, use paymaster's stake to pay.\n walletStake, // wallet has enough stake to pay for request.\n walletEth // wallet has no stake. paying with eth.\n }\n\n uint public immutable perOpOverhead;\n address public immutable create2factory;\n\n event UserOperationEvent(address indexed sender, address indexed paymaster, uint nonce, uint actualGasCost, uint actualGasPrice, bool success);\n event UserOperationRevertReason(address indexed sender, uint nonce, bytes revertReason);\n\n event PaymasterPostOpFailed(address indexed sender, address indexed paymaster, uint nonce, bytes reason);\n\n //handleOps reverts with this error struct, to mark the offending op\n // NOTE: if simulateOp passes successfully, there should be no reason for handleOps to fail on it.\n // @param opIndex - index into the array of ops to the failed one (in simulateOp, this is always zero)\n // @param paymaster - if paymaster.verifyPaymasterUserOp fails, this will be the paymaster's address. if verifyUserOp failed,\n // this value will be zero (since it failed before accessing the paymaster)\n // @param reason - revert reason\n // only to aid troubleshooting of wallet/paymaster reverts\n error FailedOp(uint opIndex, address paymaster, string reason);\n\n constructor(address _create2factory, uint _perOpOverhead, uint32 _unstakeDelayBlocks) StakeManager(_unstakeDelayBlocks) {\n create2factory = _create2factory;\n perOpOverhead = _perOpOverhead;\n }\n\n receive() external payable {}\n\n /**\n * Execute the given UserOperation.\n * @param op the operation to execute\n * @param redeemer the contract to redeem the fee\n */\n function handleOp(UserOperation calldata op, address payable redeemer) public {\n\n uint preGas = gasleft();\n\n (uint256 prefund, PaymentMode paymentMode, bytes memory context) = _validatePrepayment(0, op);\n uint preOpGas = preGas - gasleft() + perOpOverhead;\n\n uint actualGasCost;\n\n try this.internalHandleOp(op, context, preOpGas, prefund, paymentMode) returns (uint _actualGasCost) {\n actualGasCost = _actualGasCost;\n } catch {\n uint actualGas = preGas - gasleft() + preOpGas;\n actualGasCost = handlePostOp(IPaymaster.PostOpMode.postOpReverted, op, context, actualGas, prefund, paymentMode);\n }\n\n redeem(redeemer, actualGasCost);\n }\n\n function redeem(address payable redeemer, uint amount) internal {\n redeemer.transfer(amount);\n }\n\n function handleOps(UserOperation[] calldata ops, address payable redeemer) public {\n\n uint opslen = ops.length;\n uint256[] memory preOpGas = new uint256[](opslen);\n bytes32[] memory contexts = new bytes32[](opslen);\n uint256[] memory prefunds = new uint256[](opslen);\n PaymentMode[] memory paymentModes = new PaymentMode[](opslen);\n\n for (uint i = 0; i < opslen; i++) {\n uint preGas = gasleft();\n UserOperation calldata op = ops[i];\n\n bytes memory context;\n bytes32 contextOffset;\n (prefunds[i], paymentModes[i], context) = _validatePrepayment(i, op);\n assembly {contextOffset := context}\n contexts[i] = contextOffset;\n preOpGas[i] = preGas - gasleft() + perOpOverhead;\n }\n\n uint collected = 0;\n\n for (uint i = 0; i < ops.length; i++) {\n uint preGas = gasleft();\n UserOperation calldata op = ops[i];\n bytes32 contextOffset = contexts[i];\n bytes memory context;\n assembly {context := contextOffset}\n uint preOpGasi = preOpGas[i];\n uint prefundi = prefunds[i];\n PaymentMode paymentModei = paymentModes[i];\n\n try this.internalHandleOp(op, context, preOpGasi, prefundi, paymentModei) returns (uint _actualGasCost) {\n collected += _actualGasCost;\n } catch {\n uint actualGas = preGas - gasleft() + preOpGasi;\n collected += handlePostOp(IPaymaster.PostOpMode.postOpReverted, op, context, actualGas, prefundi, paymentModei);\n }\n }\n\n redeem(redeemer, collected);\n }\n\n function internalHandleOp(UserOperation calldata op, bytes calldata context, uint preOpGas, uint prefund, PaymentMode paymentMode) external returns (uint actualGasCost) {\n uint preGas = gasleft();\n require(msg.sender == address(this));\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (op.callData.length > 0) {\n\n (bool success,bytes memory result) = address(op.getSender()).call{gas : op.callGas}(op.callData);\n if (!success && result.length > 0) {\n emit UserOperationRevertReason(op.getSender(), op.nonce, result);\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n uint actualGas = preGas - gasleft() + preOpGas;\n return handlePostOp(mode, op, context, actualGas, prefund, paymentMode);\n }\n\n /**\n * Simulate a call for wallet.verifyUserOp.\n * Call must not revert.\n * @return gasUsedByPayForSelfOp - gas used by the validation, to pass into simulatePaymasterValidation.\n * The node must also verify it doesn't use banned opcode, and that it doesn't reference storage outside the wallet's data\n */\n function simulateWalletValidation(UserOperation calldata userOp) external returns (uint gasUsedByPayForSelfOp){\n require(msg.sender == address(0), \"must be called off-chain with from=zero-addr\");\n (uint requiredPreFund, PaymentMode paymentMode) = getPaymentInfo(userOp);\n (gasUsedByPayForSelfOp,) = _validateWalletPrepayment(0, userOp, requiredPreFund, paymentMode);\n }\n\n function getPaymentInfo(UserOperation calldata userOp) internal view returns (uint requiredPrefund, PaymentMode paymentMode) {\n requiredPrefund = userOp.requiredPreFund(perOpOverhead);\n if (userOp.hasPaymaster()) {\n paymentMode = PaymentMode.paymasterStake;\n } else if (isStaked(userOp.getSender(), requiredPrefund, 0)) {\n paymentMode = PaymentMode.walletStake;\n } else {\n paymentMode = PaymentMode.walletEth;\n }\n }\n\n /**\n * Simulate a call to paymaster.verifyPaymasterUserOp\n * do nothing if has no paymaster.\n * @param userOp the user operation to validate.\n * @param gasUsedByPayForSelfOp - the gas returned by simulateWalletValidation, as these 2 calls should share\n * the same userOp.validationGas quota.\n * The node must also verify it doesn't use banned opcode, and that it doesn't reference storage outside the paymaster's data\n */\n function simulatePaymasterValidation(UserOperation calldata userOp, uint gasUsedByPayForSelfOp) external view returns (bytes memory context, uint gasUsedByPayForOp){\n (uint requiredPreFund, PaymentMode paymentMode) = getPaymentInfo(userOp);\n if (paymentMode != PaymentMode.paymasterStake) {\n return (\"\", 0);\n }\n return _validatePaymasterPrepayment(0, userOp, requiredPreFund, gasUsedByPayForSelfOp);\n }\n\n // get the sender address, or use \"create2\" to create it.\n // note that the gas allocation for this creation is deterministic (by the size of callData),\n // so it is not checked on-chain, and adds to the gas used by verifyUserOp\n function _createSenderIfNeeded(UserOperation calldata op) internal {\n if (op.initCode.length != 0) {\n //its a create operation. run the create2\n // note that we're still under the gas limit of validate, so probably\n // this create2 creates a proxy account.\n // appending signer makes the request unique, so no one else can make this request.\n //nonce is meaningless during create, so we re-purpose it as salt\n address sender1 = ICreate2Deployer(create2factory).deploy(op.initCode, bytes32(op.nonce));\n require(sender1 != address(0), \"create2 failed\");\n require(sender1 == op.getSender(), \"sender doesn't match create2 address\");\n }\n }\n\n //get counterfactual sender address.\n // use the initCode and salt in the UserOperation tot create this sender contract\n function getSenderAddress(bytes memory initCode, uint _salt) public view returns (address) {\n bytes32 hash = keccak256(\n abi.encodePacked(\n bytes1(0xff),\n address(create2factory),\n _salt,\n keccak256(initCode)\n )\n );\n\n // NOTE: cast last 20 bytes of hash to address\n return address(uint160(uint256(hash)));\n }\n\n //call wallet.verifyUserOp, and validate that it paid as needed.\n // return actual value sent from wallet to \"this\"\n function _validateWalletPrepayment(uint opIndex, UserOperation calldata op, uint requiredPrefund, PaymentMode paymentMode) internal returns (uint gasUsedByPayForSelfOp, uint prefund) {\n uint preGas = gasleft();\n _createSenderIfNeeded(op);\n uint preBalance = address(this).balance;\n uint requiredEthPrefund = 0;\n if (paymentMode == PaymentMode.walletEth) {\n requiredEthPrefund = requiredPrefund;\n } else if (paymentMode == PaymentMode.walletStake) {\n _prefundFromSender(op, requiredPrefund);\n } else {\n // paymaster pays in handlePostOp\n }\n try IWallet(op.getSender()).verifyUserOp{gas : op.verificationGas}(op, requiredEthPrefund) {\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, address(0), revertReason);\n } catch {\n revert FailedOp(opIndex, address(0), \"\");\n }\n uint actualEthPrefund = address(this).balance - preBalance;\n\n if (paymentMode == PaymentMode.walletEth) {\n if (actualEthPrefund < requiredEthPrefund) {\n revert FailedOp(opIndex, address(0), \"wallet didn't pay prefund\");\n }\n prefund = actualEthPrefund;\n } else if (paymentMode == PaymentMode.walletStake) {\n if (actualEthPrefund != 0) {\n revert FailedOp(opIndex, address(0), \"using wallet stake but wallet paid eth\");\n }\n prefund = requiredPrefund;\n } else {\n if (actualEthPrefund != 0) {\n revert FailedOp(opIndex, address(0), \"has paymaster but wallet paid\");\n }\n prefund = requiredPrefund;\n }\n\n gasUsedByPayForSelfOp = preGas - gasleft();\n }\n\n //validate paymaster.verifyPaymasterUserOp\n function _validatePaymasterPrepayment(uint opIndex, UserOperation calldata op, uint requiredPreFund, uint gasUsedByPayForSelfOp) internal view returns (bytes memory context, uint gasUsedByPayForOp) {\n uint preGas = gasleft();\n if (!isValidStake(op, requiredPreFund)) {\n revert FailedOp(opIndex, op.paymaster, \"not enough stake\");\n }\n //no pre-pay from paymaster\n uint gas = op.verificationGas - gasUsedByPayForSelfOp;\n try IPaymaster(op.paymaster).verifyPaymasterUserOp{gas : gas}(op, requiredPreFund) returns (bytes memory _context){\n context = _context;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, op.paymaster, revertReason);\n } catch {\n revert FailedOp(opIndex, op.paymaster, \"\");\n }\n gasUsedByPayForOp = preGas - gasleft();\n }\n\n function _validatePrepayment(uint opIndex, UserOperation calldata userOp) private returns (uint prefund, PaymentMode paymentMode, bytes memory context){\n\n uint preGas = gasleft();\n uint gasUsedByPayForSelfOp;\n uint requiredPreFund;\n (requiredPreFund, paymentMode) = getPaymentInfo(userOp);\n\n (gasUsedByPayForSelfOp, prefund) = _validateWalletPrepayment(opIndex, userOp, requiredPreFund, paymentMode);\n\n uint gasUsedByPayForOp = 0;\n if (paymentMode == PaymentMode.paymasterStake) {\n (context, gasUsedByPayForOp) = _validatePaymasterPrepayment(opIndex, userOp, requiredPreFund, gasUsedByPayForSelfOp);\n } else {\n context = \"\";\n }\n uint gasUsed = preGas - gasleft();\n\n if (userOp.verificationGas < gasUsed) {\n revert FailedOp(opIndex, userOp.paymaster, \"Used more than verificationGas\");\n }\n }\n\n function getPaymastersStake(address[] calldata paymasters) external view returns (uint[] memory _stakes) {\n _stakes = new uint[](paymasters.length);\n for (uint i = 0; i < paymasters.length; i++) {\n _stakes[i] = stakes[paymasters[i]].stake;\n }\n }\n\n function handlePostOp(IPaymaster.PostOpMode mode, UserOperation calldata op, bytes memory context, uint actualGas, uint prefund, PaymentMode paymentMode) private returns (uint actualGasCost) {\n uint preGas = gasleft();\n uint gasPrice = UserOperationLib.gasPrice(op);\n actualGasCost = actualGas * gasPrice;\n if (paymentMode != PaymentMode.paymasterStake) {\n if (prefund < actualGasCost) {\n revert (\"wallet prefund below actualGasCost\");\n }\n uint refund = prefund - actualGasCost;\n if (paymentMode == PaymentMode.walletStake) {\n _refundSenderStake(op, refund);\n } else {\n _refundSender(op, refund);\n }\n } else {\n if (context.length > 0) {\n //if paymaster.postOp reverts:\n // - emit a message (just for sake of debugging of this poor paymaster)\n // - paymaster still pays (from its stake)\n try IPaymaster(op.paymaster).postOp(mode, context, actualGasCost) {}\n catch (bytes memory errdata) {\n emit PaymasterPostOpFailed(op.getSender(), op.paymaster, op.nonce, errdata);\n }\n }\n //paymaster pays for full gas, including for postOp (and revert event)\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n //paymaster balance known to be high enough, and to be locked for this block\n stakes[op.paymaster].stake -= uint96(actualGasCost);\n }\n _emitLog(op, actualGasCost, gasPrice, mode == IPaymaster.PostOpMode.opSucceeded);\n }\n\n function _emitLog(UserOperation calldata op, uint actualGasCost, uint gasPrice, bool success) internal {\n emit UserOperationEvent(op.getSender(), op.paymaster, op.nonce, actualGasCost, gasPrice, success);\n }\n\n function _prefundFromSender(UserOperation calldata userOp, uint requiredPrefund) internal {\n stakes[userOp.getSender()].stake -= uint96(requiredPrefund);\n }\n\n function _refundSender(UserOperation calldata userOp, uint refund) internal {\n //NOTE: deliberately ignoring revert: wallet should accept refund.\n bool sendOk = payable(userOp.getSender()).send(refund);\n (sendOk);\n }\n function _refundSenderStake(UserOperation calldata userOp, uint refund) internal {\n stakes[userOp.getSender()].stake += uint96(refund);\n }\n\n function isValidStake(UserOperation calldata userOp, uint requiredPreFund) internal view returns (bool) {\n return isPaymasterStaked(userOp.paymaster, PAYMASTER_STAKE + requiredPreFund);\n }\n\n function isPaymasterStaked(address paymaster, uint stake) public view returns (bool) {\n return isStaked(paymaster, stake, unstakeDelayBlocks);\n }\n\n function isContractDeployed(address addr) external view returns (bool) {\n bytes32 hash;\n assembly {\n hash := extcodehash(addr)\n }\n return hash != bytes32(0);\n }\n}\n\n"
+ },
+ "contracts/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8;\n\nimport \"hardhat/console.sol\";\n\ncontract StakeManager {\n\n /// minimum number of blocks to after 'unlock' before amount can be withdrawn.\n uint32 immutable public unstakeDelayBlocks;\n\n constructor(uint32 _unstakeDelayBlocks) {\n unstakeDelayBlocks = _unstakeDelayBlocks;\n }\n\n event StakeAdded(\n address indexed paymaster,\n uint256 totalStake,\n uint256 unstakeDelayBlocks\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocking(\n address indexed paymaster,\n uint256 withdrawBlock\n );\n\n event StakeWithdrawn(\n address indexed paymaster,\n address withdrawAddress,\n uint256 amount\n );\n\n /// @param stake - amount of ether staked for this paymaster\n /// @param withdrawStake - once 'unlocked' the value is no longer staked.\n /// @param withdrawBlock - first block number 'withdraw' will be callable, or zero if the unlock has not been called\n struct StakeInfo {\n uint96 stake;\n uint32 unstakeDelayBlocks;\n uint96 withdrawStake;\n uint32 withdrawBlock;\n }\n\n /// maps relay managers to their stakes\n mapping(address => StakeInfo) public stakes;\n\n function getStakeInfo(address paymaster) external view returns (StakeInfo memory stakeInfo) {\n return stakes[paymaster];\n }\n\n /**\n * add a deposit (just like stake, but with lock=0\n * cancel any pending unlock\n */\n function addDeposit() external payable {\n addStake(0);\n }\n\n //add deposit to another account (doesn't change lock status)\n function addDepositTo(address target) external payable {\n stakes[target].stake += uint96(msg.value);\n }\n\n /**\n * add stake value for this paymaster.\n * cancel any pending unlock\n */\n function addStake(uint32 _unstakeDelayBlocks) public payable {\n require(_unstakeDelayBlocks >= stakes[msg.sender].unstakeDelayBlocks, \"cannot decrease unstake blocks\");\n uint96 stake = uint96(stakes[msg.sender].stake + msg.value + stakes[msg.sender].withdrawStake);\n stakes[msg.sender] = StakeInfo(\n stake,\n _unstakeDelayBlocks,\n 0,\n 0);\n emit StakeAdded(msg.sender, stake, _unstakeDelayBlocks);\n }\n\n function unlockStake() external {\n StakeInfo storage info = stakes[msg.sender];\n require(info.withdrawBlock == 0, \"already pending\");\n require(info.stake != 0 && info.unstakeDelayBlocks != 0, \"no stake to unlock\");\n uint32 withdrawBlock = uint32(block.number) + info.unstakeDelayBlocks;\n info.withdrawBlock = withdrawBlock;\n info.withdrawStake = info.stake;\n info.stake = 0;\n emit StakeUnlocking(msg.sender, withdrawBlock);\n }\n\n function withdrawStake(address payable withdrawAddress) external {\n StakeInfo memory info = stakes[msg.sender];\n if (info.unstakeDelayBlocks != 0) {\n require(info.withdrawStake > 0, \"no unlocked stake\");\n require(info.withdrawBlock <= block.number, \"Withdrawal is not due\");\n }\n uint256 amount = info.withdrawStake + info.stake;\n stakes[msg.sender] = StakeInfo(0, info.unstakeDelayBlocks, 0, 0);\n withdrawAddress.transfer(amount);\n emit StakeWithdrawn(msg.sender, withdrawAddress, amount);\n }\n\n function isStaked(address paymaster, uint requiredStake, uint requiredDelayBlocks) public view returns (bool) {\n StakeInfo memory stakeInfo = stakes[paymaster];\n return stakeInfo.stake >= requiredStake && stakeInfo.unstakeDelayBlocks >= requiredDelayBlocks;\n }\n}\n"
+ },
+ "contracts/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.7;\n\nimport \"hardhat/console.sol\";\n\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint callGas;\n uint verificationGas;\n uint preVerificationGas;\n uint maxFeePerGas;\n uint maxPriorityFeePerGas;\n address paymaster;\n bytes paymasterData;\n bytes signature;\n }\n\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal view returns (address ret) {\n assembly {ret := calldataload(userOp)}\n }\n\n //relayer/miner might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint) {\n unchecked {\n return min(userOp.maxFeePerGas, userOp.maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function requiredGas(UserOperation calldata userOp) internal pure returns (uint) {\n unchecked {\n return userOp.callGas + userOp.verificationGas + userOp.preVerificationGas;\n }\n }\n\n function requiredPreFund(UserOperation calldata userOp, uint overhead) internal view returns (uint prefund) {\n return (requiredGas(userOp) + overhead) * gasPrice(userOp);\n }\n\n function hasPaymaster(UserOperation calldata userOp) internal pure returns (bool) {\n return userOp.paymaster != address(0);\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n //lighter signature scheme. must match UserOp.ts#packUserOp\n bytes calldata sig = userOp.signature;\n assembly {\n let ofs := userOp\n let len := sub(sub(sig.offset, ofs), 32)\n ret := mload(0x40)\n mstore(0x40, add(ret, add(len, 32)))\n mstore(ret, len)\n calldatacopy(add(ret, 32), ofs, len)\n }\n return ret;\n\n //TODO: eip712-style ?\n return abi.encode(\n userOp.sender,\n userOp.nonce,\n keccak256(userOp.initCode),\n keccak256(userOp.callData),\n userOp.callGas,\n userOp.verificationGas,\n userOp.preVerificationGas,\n userOp.maxFeePerGas,\n userOp.maxPriorityFeePerGas,\n userOp.paymaster,\n keccak256(userOp.paymasterData)\n );\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\",\n keccak256(pack(userOp))));\n }\n\n function min(uint a, uint b) internal pure returns (uint) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/IWallet.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.7;\n\nimport \"./UserOperation.sol\";\n\ninterface IWallet {\n\n // validate user's signature and nonce\n // @param requiredPrefund how much this wallet should pre-fund the transaction.\n // @note that after execution, the excess is sent back to the wallet.\n // @note if requiredPrefund is zero, the wallet MUST NOT send anything (the paymaster pays)\n function verifyUserOp(UserOperation calldata userOp, uint requiredPrefund) external;\n}\n"
+ },
+ "contracts/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.7;\n\nimport \"./UserOperation.sol\";\n\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now its a 2nd call, after user's op was deliberately reverted.\n }\n // payment validation: check if paymaster agree to pay (using its stake)\n // revert to reject this request.\n // actual payment is done after postOp is called, by deducting actual call cost form the paymaster's stake.\n // @param userOp the user operation\n // @param maxcost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n // @returns context value to send to a postOp\n // zero length to signify postOp is not required.\n function verifyPaymasterUserOp(UserOperation calldata userOp, uint maxcost) external view returns (bytes memory context);\n\n // post-operation handler.\n // @param mode\n // opSucceeded - user operation succeeded.\n // opReverted - user op reverted. still has to pay for gas.\n // postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n // Now this is the 2nd call, after user's op was deliberately reverted.\n // @param context - the context value returned by verifyPaymasterUserOp\n // @param actualGasCost - actual gas used so far (without this postOp call).\n function postOp(PostOpMode mode, bytes calldata context, uint actualGasCost) external;\n}\n"
+ },
+ "hardhat/console.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity >= 0.4.22 <0.9.0;\n\nlibrary console {\n\taddress constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67);\n\n\tfunction _sendLogPayload(bytes memory payload) private view {\n\t\tuint256 payloadLength = payload.length;\n\t\taddress consoleAddress = CONSOLE_ADDRESS;\n\t\tassembly {\n\t\t\tlet payloadStart := add(payload, 32)\n\t\t\tlet r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0)\n\t\t}\n\t}\n\n\tfunction log() internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log()\"));\n\t}\n\n\tfunction logInt(int p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(int)\", p0));\n\t}\n\n\tfunction logUint(uint p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n\t}\n\n\tfunction logString(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction logBool(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction logAddress(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction logBytes(bytes memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n\t}\n\n\tfunction logBytes1(bytes1 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n\t}\n\n\tfunction logBytes2(bytes2 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n\t}\n\n\tfunction logBytes3(bytes3 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n\t}\n\n\tfunction logBytes4(bytes4 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n\t}\n\n\tfunction logBytes5(bytes5 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n\t}\n\n\tfunction logBytes6(bytes6 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n\t}\n\n\tfunction logBytes7(bytes7 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n\t}\n\n\tfunction logBytes8(bytes8 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n\t}\n\n\tfunction logBytes9(bytes9 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n\t}\n\n\tfunction logBytes10(bytes10 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n\t}\n\n\tfunction logBytes11(bytes11 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n\t}\n\n\tfunction logBytes12(bytes12 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n\t}\n\n\tfunction logBytes13(bytes13 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n\t}\n\n\tfunction logBytes14(bytes14 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n\t}\n\n\tfunction logBytes15(bytes15 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n\t}\n\n\tfunction logBytes16(bytes16 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n\t}\n\n\tfunction logBytes17(bytes17 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n\t}\n\n\tfunction logBytes18(bytes18 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n\t}\n\n\tfunction logBytes19(bytes19 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n\t}\n\n\tfunction logBytes20(bytes20 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n\t}\n\n\tfunction logBytes21(bytes21 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n\t}\n\n\tfunction logBytes22(bytes22 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n\t}\n\n\tfunction logBytes23(bytes23 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\", p0));\n\t}\n\n\tfunction logBytes24(bytes24 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes24)\", p0));\n\t}\n\n\tfunction logBytes25(bytes25 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes25)\", p0));\n\t}\n\n\tfunction logBytes26(bytes26 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes26)\", p0));\n\t}\n\n\tfunction logBytes27(bytes27 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes27)\", p0));\n\t}\n\n\tfunction logBytes28(bytes28 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes28)\", p0));\n\t}\n\n\tfunction logBytes29(bytes29 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes29)\", p0));\n\t}\n\n\tfunction logBytes30(bytes30 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes30)\", p0));\n\t}\n\n\tfunction logBytes31(bytes31 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes31)\", p0));\n\t}\n\n\tfunction logBytes32(bytes32 p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bytes32)\", p0));\n\t}\n\n\tfunction log(uint p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint)\", p0));\n\t}\n\n\tfunction log(string memory p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n\t}\n\n\tfunction log(bool p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n\t}\n\n\tfunction log(address p0) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n\t}\n\n\tfunction log(uint p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool)\", p0, p1));\n\t}\n\n\tfunction log(string memory p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool)\", p0, p1));\n\t}\n\n\tfunction log(bool p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address)\", p0, p1));\n\t}\n\n\tfunction log(address p0, uint p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint)\", p0, p1));\n\t}\n\n\tfunction log(address p0, string memory p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string)\", p0, p1));\n\t}\n\n\tfunction log(address p0, bool p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool)\", p0, p1));\n\t}\n\n\tfunction log(address p0, address p1) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address)\", p0, p1));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(bool p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, uint p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, bool p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, uint p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, bool p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool)\", p0, p1, p2));\n\t}\n\n\tfunction log(address p0, address p1, address p2) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address)\", p0, p1, p2));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(uint p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(uint,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(string memory p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(string,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(bool p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(bool,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, uint p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,uint,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, string memory p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,string,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, bool p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,bool,address,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, uint p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,uint,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, string memory p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,string,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, bool p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,bool,address)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, uint p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,uint)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, string memory p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,string)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, bool p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,bool)\", p0, p1, p2, p3));\n\t}\n\n\tfunction log(address p0, address p1, address p2, address p3) internal view {\n\t\t_sendLogPayload(abi.encodeWithSignature(\"log(address,address,address,address)\", p0, p1, p2, p3));\n\t}\n\n}\n"
+ },
+ "contracts/samples/VerifyingPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.7;\n\nimport \"../IPaymaster.sol\";\nimport \"../EntryPoint.sol\";\n\n/**\n * A sample paymaster that uses external service to decide whether to pay for the UserOp.\n * The paymaster trusts an external signer to sign the transaction.\n * The calling user must pass the UserOp to that external signer first, which performs\n * whatever off-chain verification before signing the UserOp.\n * Note that this signature is NOT a replacement for wallet signature:\n * - the paymaster signs to agree to PAY for GAS.\n * - the wallet signs to prove identity and wallet ownership.\n */\ncontract VerifyingPaymaster is IPaymaster {\n\n using UserOperationLib for UserOperation;\n\n EntryPoint public immutable entryPoint;\n address public immutable verifyingSigner;\n\n constructor(EntryPoint _entryPoint, address _verifyingSigner) {\n entryPoint = _entryPoint;\n verifyingSigner = _verifyingSigner;\n }\n\n function addStake() external payable {\n entryPoint.addStake{value : msg.value}(entryPoint.unstakeDelayBlocks());\n }\n\n // verify our external signer signed this request.\n // the \"paymasterData\" is supposed to be a signature over the entire request params\n function verifyPaymasterUserOp(UserOperation calldata userOp, uint requiredPreFund) external view override returns (bytes memory context) {\n (requiredPreFund);\n\n bytes32 hash = userOp.hash();\n require( userOp.paymasterData.length >= 65, \"VerifyingPaymaster: invalid signature length in paymasterData\");\n (bytes32 r, bytes32 s) = abi.decode(userOp.paymasterData, (bytes32, bytes32));\n uint8 v = uint8(userOp.paymasterData[64]);\n require(verifyingSigner == ecrecover(hash, v, r, s), \"VerifyingPaymaster: wrong signature\");\n\n //no other on-chain validation: entire UserOp should have been checked by the external service,\n // prior signing it.\n return \"\";\n }\n\n function postOp(PostOpMode, bytes calldata, uint) external pure override {\n //should never get called. returned \"0\" from verifyPaymasterUserOp\n revert();\n }\n}\n"
+ },
+ "contracts/samples/TokenPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"../IPaymaster.sol\";\nimport \"../EntryPoint.sol\";\nimport \"./SimpleWalletForTokens.sol\";\nimport \"hardhat/console.sol\";\n\n/**\n * A sample paymaster that define itself as a token to pay for gas.\n * The paymaster IS the token to use, since a paymaster cannot use an external contract.\n * also, the exchange rate has to be fixed, since it can't refernce external Uniswap os other exchange contract.\n */\ncontract TokenPaymaster is Ownable, ERC20, IPaymaster {\n\n //calculated cost of the postOp\n uint COST_OF_POST = 3000;\n\n EntryPoint entryPoint;\n bytes32 immutable knownWallet;\n\n constructor(string memory _symbol, EntryPoint _entryPoint) ERC20(_symbol, _symbol) {\n entryPoint = _entryPoint;\n knownWallet = keccak256(type(SimpleWallet).creationCode);\n// knownWallets[keccak256(type(SimpleWallet).creationCode)] = true;\n approve(owner(), type(uint).max);\n }\n\n //helpers for owner, to mint and withdraw tokens.\n function mintTokens(address recipient, uint amount) external onlyOwner {\n _mint(recipient, amount);\n }\n\n //owner should call and put eth into it.\n function addStake() external payable {\n entryPoint.addStake{value : msg.value}(entryPoint.unstakeDelayBlocks());\n }\n\n //TODO: this method assumes a fixed ratio of token-to-eth. should use oracle.\n function ethToToken(uint valueEth) internal pure returns (uint valueToken) {\n return valueEth / 100;\n }\n\n // verify that the user has enough tokens.\n function verifyPaymasterUserOp(UserOperation calldata userOp, uint requiredPreFund) external view override returns (bytes memory context) {\n uint tokenPrefund = ethToToken(requiredPreFund);\n\n if (userOp.initCode.length != 0) {\n bytes32 bytecodeHash = keccak256(userOp.initCode[0:userOp.initCode.length-64]);\n require(knownWallet == bytecodeHash, \"TokenPaymaster: unknown wallet constructor\");\n\n //verify the token constructor params:\n // first param (of 2) should be our entryPoint\n bytes32 entryPointParam = bytes32(userOp.initCode[userOp.initCode.length-64:]);\n require( address(uint160(uint256(entryPointParam))) == address(entryPoint), \"wrong paymaster in constructor\");\n\n //TODO: must also whitelist init function (callData), since that what will call \"token.approve(paymaster)\"\n //no \"allowance\" check during creation (we trust known constructor/init function)\n require(balanceOf(userOp.sender) > tokenPrefund, \"TokenPaymaster: no balance (pre-create)\");\n } else {\n\n require(balanceOf(userOp.sender) > tokenPrefund, \"TokenPaymaster: no balance\");\n }\n\n //since we ARE the token, we don't need approval to _transfer() value from user's balance.\n // if (token.allowance(userOp.sender, address(this)) < tokenPrefund) {\n //\n // //TODO: allowance too low. just before reverting, can check if current operation is \"token.approve(paymaster)\"\n // // this is a multi-step operation: first, verify \"callData\" is exec(token, innerData)\n // // (this requires knowing the \"execute\" signature of the wallet\n // // then verify that \"innerData\" is approve(paymaster,-1)\n // revert(\"TokenPaymaster: no allowance\");\n // }\n return abi.encode(userOp.sender);\n }\n\n //actual charge of user.\n // this method will be called just after the user's TX with postRevert=false.\n // BUT: if the user changed its balance and that postOp reverted, then it gets called again, after reverting\n // the user's TX\n function postOp(PostOpMode mode, bytes calldata context, uint actualGasCost) external override {\n //we don't really care about the mode, we just pay the gas with the user's tokens.\n (mode);\n address sender = abi.decode(context, (address));\n uint charge = ethToToken(actualGasCost + COST_OF_POST);\n //actualGasCost is known to be no larger than the above requiredPreFund, so the transfer should succeed.\n _transfer(sender, address(this), charge);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/access/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _setOwner(_msgSender());\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _setOwner(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _setOwner(newOwner);\n }\n\n function _setOwner(address newOwner) private {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n unchecked {\n _approve(sender, _msgSender(), currentAllowance - amount);\n }\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(\n address sender,\n address recipient,\n uint256 amount\n ) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[sender] = senderBalance - amount;\n }\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n\n _afterTokenTransfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n }\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n"
+ },
+ "contracts/samples/SimpleWalletForTokens.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.7;\n\nimport \"./SimpleWallet.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\n//in order to be created with tokens, the wallet has to have allowance to the paymaster in advance.\n// the simplest strategy is assign the allowance in the constructor or init function\ncontract SimpleWalletForTokens is SimpleWallet {\n\n constructor(EntryPoint _entryPoint, address _owner, IERC20 token, address paymaster) SimpleWallet(_entryPoint, _owner) {\n token.approve(paymaster, type(uint).max);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address sender,\n address recipient,\n uint256 amount\n ) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
+ },
+ "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n"
+ },
+ "contracts/samples/SimpleWallet.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.7;\n\nimport \"../IWallet.sol\";\nimport \"../EntryPoint.sol\";\n\nimport \"hardhat/console.sol\";\n\n//minimal wallet\n// this is sample minimal wallet.\n// has execute, eth handling methods\n// has a single signer that can send requests through the entryPoint.\ncontract SimpleWallet is IWallet {\n using UserOperationLib for UserOperation;\n struct OwnerNonce {\n uint96 nonce;\n address owner;\n }\n OwnerNonce ownerNonce;\n EntryPoint public entryPoint;\n\n function nonce() public view returns (uint) {\n return ownerNonce.nonce;\n }\n\n function owner() public view returns(address) {\n return ownerNonce.owner;\n }\n\n event EntryPointChanged(EntryPoint oldEntryPoint, EntryPoint newEntryPoint);\n\n receive() external payable {}\n\n constructor(EntryPoint _entryPoint, address _owner) {\n entryPoint = _entryPoint;\n ownerNonce.owner = _owner;\n }\n\n modifier onlyOwner() {\n _onlyOwner();\n _;\n }\n\n function _onlyOwner() internal view {\n //directly from EOA owner, or through the entryPoint (which gets redirected through execFromEntryPoint)\n require(msg.sender == ownerNonce.owner || msg.sender == address(this), \"only owner\");\n }\n\n function transfer(address payable dest, uint amount) external onlyOwner {\n dest.transfer(amount);\n }\n\n function exec(address dest, uint value, bytes calldata func) external onlyOwner {\n _call(dest, value, func);\n }\n\n function updateEntryPoint(EntryPoint _entryPoint) external onlyOwner {\n emit EntryPointChanged(entryPoint, _entryPoint);\n entryPoint = _entryPoint;\n }\n\n function _requireFromEntryPoint() internal view {\n require(msg.sender == address(entryPoint), \"wallet: not from EntryPoint\");\n }\n\n function verifyUserOp(UserOperation calldata userOp, uint requiredPrefund) external override {\n _requireFromEntryPoint();\n _validateSignature(userOp);\n _validateAndIncrementNonce(userOp);\n _payPrefund(requiredPrefund);\n }\n\n function _payPrefund(uint requiredPrefund) internal {\n if (requiredPrefund != 0) {\n (bool success) = payable(msg.sender).send(requiredPrefund);\n (success);\n //ignore failure (its EntryPoint's job to verify, not wallet.)\n }\n }\n\n //called by entryPoint, only after verifyUserOp succeeded.\n function execFromEntryPoint(address dest, uint value, bytes calldata func) external {\n _requireFromEntryPoint();\n _call(dest, value, func);\n }\n\n function _validateAndIncrementNonce(UserOperation calldata userOp) internal {\n //during construction, the \"nonce\" field hold the salt.\n // if we assert it is zero, then we allow only a single wallet per owner.\n if (userOp.initCode.length == 0) {\n require(ownerNonce.nonce++ == userOp.nonce, \"wallet: invalid nonce\");\n }\n }\n\n function _validateSignature(UserOperation calldata userOp) internal view {\n\n bytes32 hash = userOp.hash();\n (bytes32 r, bytes32 s, uint8 v) = _rsv(userOp.signature);\n\n require(owner() == _ecrecover(hash, v, r, s), \"wallet: wrong signature\");\n }\n\n function _rsv(bytes calldata signature) internal pure returns (bytes32 r, bytes32 s, uint8 v) {\n\n require(signature.length == 65, \"wallet: invalid signature length\");\n assembly {\n r := calldataload(signature.offset)\n s := calldataload(add(signature.offset, 0x20))\n v := byte(0, calldataload(add(signature.offset, 0x40)))\n }\n }\n\n function _ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\n return ecrecover(hash, v, r, s);\n }\n\n function _call(address sender, uint value, bytes memory data) internal {\n (bool success, bytes memory result) = sender.call{value : value}(data);\n if (!success) {\n assembly {\n revert(result, add(result, 32))\n }\n }\n }\n\n function addDeposit() public payable {\n entryPoint.addDeposit{value : msg.value}();\n }\n\n function withdrawDeposit(address payable withdrawAddress) public {\n entryPoint.withdrawStake(withdrawAddress);\n }\n}\n"
+ },
+ "contracts/samples/TestToken.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor ()\n ERC20(\"TST\", \"TestToken\") {\n }\n\n function mint(address sender, uint amount) external {\n _mint(sender, amount);\n }\n}\n"
+ },
+ "contracts/test/TestUtil.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.7;\n\nimport \"../UserOperation.sol\";\nimport \"../IWallet.sol\";\n\ncontract TestUtil {\n using UserOperationLib for UserOperation;\n\n function packUserOp(UserOperation calldata op) external pure returns (bytes memory){\n return op.pack();\n }\n\n function prefund(UserOperation calldata op) public view returns (uint) {\n return op.requiredPreFund(0);\n }\n\n}"
+ },
+ "contracts/test/TestCounter.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.7;\n\nimport \"../UserOperation.sol\";\nimport \"../IWallet.sol\";\n\n//sample \"receiver\" contract, for testing \"exec\" from wallet.\ncontract TestCounter {\n mapping(address => uint) public counters;\n\n function count() public {\n counters[msg.sender] = counters[msg.sender] + 1;\n\n }\n\n //helper method to waste gas\n // repeat - waste gas on writing storage in a loop\n // junk - dynamic buffer to stress the function size.\n mapping(uint => uint) xxx;\n uint offset;\n\n function gasWaster(uint repeat, string calldata /*junk*/) external {\n for (uint i = 1; i <= repeat; i++) {\n offset++;\n xxx[offset] = i;\n }\n }\n}"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/.chainId b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/.chainId
new file mode 100644
index 00000000..56a6051c
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/.chainId
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/EntryPoint.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/EntryPoint.json
new file mode 100644
index 00000000..037750fb
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/EntryPoint.json
@@ -0,0 +1,1318 @@
+{
+ "address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "paid",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bool",
+ "name": "targetSuccess",
+ "type": "bool"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetResult",
+ "type": "bytes"
+ }
+ ],
+ "name": "ExecutionResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "opIndex",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "reason",
+ "type": "string"
+ }
+ ],
+ "name": "FailedOp",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "SenderAddressResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureValidationFailed",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "stakeInfo",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IEntryPoint.AggregatorStakeInfo",
+ "name": "aggregatorInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResultWithAggregation",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "factory",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ }
+ ],
+ "name": "AccountDeployed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "BeforeExecution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalDeposit",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposited",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureAggregatorChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalStaked",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeLocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "withdrawTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeUnlocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeWithdrawn",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "success",
+ "type": "bool"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasUsed",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserOperationEvent",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "revertReason",
+ "type": "bytes"
+ }
+ ],
+ "name": "UserOperationRevertReason",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawn",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "SIG_VALIDATION_FAILED",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ }
+ ],
+ "name": "_validateSenderAndPaymaster",
+ "outputs": [],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ }
+ ],
+ "name": "addStake",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deposits",
+ "outputs": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "getDepositInfo",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "internalType": "struct IStakeManager.DepositInfo",
+ "name": "info",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "getNonce",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ }
+ ],
+ "name": "getSenderAddress",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "getUserOpHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "userOps",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "contract IAggregator",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.UserOpsPerAggregator[]",
+ "name": "opsPerAggregator",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleAggregatedOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "ops",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "incrementNonce",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.MemoryUserOp",
+ "name": "mUserOp",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "contextOffset",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.UserOpInfo",
+ "name": "opInfo",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes",
+ "name": "context",
+ "type": "bytes"
+ }
+ ],
+ "name": "innerHandleOp",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "",
+ "type": "uint192"
+ }
+ ],
+ "name": "nonceSequenceNumber",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "op",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetCallData",
+ "type": "bytes"
+ }
+ ],
+ "name": "simulateHandleOp",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "simulateValidation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unlockStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ }
+ ],
+ "name": "withdrawStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "withdrawAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdrawTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "args": [],
+ "numDeployments": 2,
+ "solcInputHash": "a4c52f0671aad8941c53d6ead2063803",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"targetSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"targetResult\",\"type\":\"bytes\"}],\"name\":\"ExecutionResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"opIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"FailedOp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderAddressResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureValidationFailed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResult\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"type\":\"tuple\"}],\"internalType\":\"struct IEntryPoint.AggregatorStakeInfo\",\"name\":\"aggregatorInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResultWithAggregation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"}],\"name\":\"AccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"BeforeExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalDeposit\",\"type\":\"uint256\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureAggregatorChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStaked\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"name\":\"StakeLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"StakeWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasUsed\",\"type\":\"uint256\"}],\"name\":\"UserOperationEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"revertReason\",\"type\":\"bytes\"}],\"name\":\"UserOperationRevertReason\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SIG_VALIDATION_FAILED\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"}],\"name\":\"_validateSenderAndPaymaster\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"}],\"name\":\"addStake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getDepositInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"internalType\":\"struct IStakeManager.DepositInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"getSenderAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"getUserOpHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"userOps\",\"type\":\"tuple[]\"},{\"internalType\":\"contract IAggregator\",\"name\":\"aggregator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.UserOpsPerAggregator[]\",\"name\":\"opsPerAggregator\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleAggregatedOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"incrementNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.MemoryUserOp\",\"name\":\"mUserOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contextOffset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.UserOpInfo\",\"name\":\"opInfo\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"name\":\"innerHandleOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"name\":\"nonceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCallData\",\"type\":\"bytes\"}],\"name\":\"simulateHandleOp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"simulateValidation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"}],\"name\":\"withdrawStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"withdrawAmount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"FailedOp(uint256,string)\":[{\"params\":{\"opIndex\":\"- index into the array of ops to the failed one (in simulateValidation, this is always zero)\",\"reason\":\"- revert reason The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues, so a failure can be attributed to the correct entity. Should be caught in off-chain handleOps simulation and not happen on-chain. Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\"}}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"params\":{\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"params\":{\"aggregatorInfo\":\"signature aggregation info (if the account requires signature aggregator) bundler MUST use it to verify the signature, or reject the UserOperation\",\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}]},\"kind\":\"dev\",\"methods\":{\"addStake(uint32)\":{\"params\":{\"unstakeDelaySec\":\"the new lock duration before the deposit can be withdrawn.\"}},\"getDepositInfo(address)\":{\"returns\":{\"info\":\"- full deposit information of given account\"}},\"getNonce(address,uint192)\":{\"params\":{\"key\":\"the high 192 bit of the nonce\",\"sender\":\"the account address\"},\"returns\":{\"nonce\":\"a full nonce to pass for next UserOp with this sender.\"}},\"getSenderAddress(bytes)\":{\"params\":{\"initCode\":\"the constructor code to be passed into the UserOperation.\"}},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"opsPerAggregator\":\"the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\"}},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"ops\":\"the operations to execute\"}},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"params\":{\"op\":\"the UserOperation to simulate\",\"target\":\"if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult are set to the return from that call.\",\"targetCallData\":\"callData to pass to target address\"}},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"details\":\"this method always revert. Successful result is ValidationResult error. other errors are failures.The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\",\"params\":{\"userOp\":\"the user operation to validate.\"}},\"withdrawStake(address)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\"}},\"withdrawTo(address,uint256)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\",\"withdrawAmount\":\"the amount to withdraw.\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"ExecutionResult(uint256,uint256,uint48,uint48,bool,bytes)\":[{\"notice\":\"return value of simulateHandleOp\"}],\"FailedOp(uint256,string)\":[{\"notice\":\"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.\"}],\"SenderAddressResult(address)\":[{\"notice\":\"return value of getSenderAddress\"}],\"SignatureValidationFailed(address)\":[{\"notice\":\"error case when a signature aggregator fails to verify the aggregated signature it had created.\"}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"notice\":\"Successful result from simulateValidation.\"}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"notice\":\"Successful result from simulateValidation, if the account returns a signature aggregator\"}]},\"events\":{\"AccountDeployed(bytes32,address,address,address)\":{\"notice\":\"account \\\"sender\\\" was deployed.\"},\"BeforeExecution()\":{\"notice\":\"an event emitted by handleOps(), before starting the execution loop. any event emitted before this event, is part of the validation.\"},\"SignatureAggregatorChanged(address)\":{\"notice\":\"signature aggregator used by the following UserOperationEvents within this bundle.\"},\"StakeLocked(address,uint256,uint256)\":{\"notice\":\"Emitted when stake or unstake delay are modified\"},\"StakeUnlocked(address,uint256)\":{\"notice\":\"Emitted once a stake is scheduled for withdrawal\"},\"UserOperationRevertReason(bytes32,address,uint256,bytes)\":{\"notice\":\"An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\"}},\"kind\":\"user\",\"methods\":{\"SIG_VALIDATION_FAILED()\":{\"notice\":\"for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value in case of signature failure, instead of revert.\"},\"_validateSenderAndPaymaster(bytes,address,bytes)\":{\"notice\":\"Called only during simulation. This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\"},\"addStake(uint32)\":{\"notice\":\"add to the account's stake - amount and delay any pending unstake is first cancelled.\"},\"balanceOf(address)\":{\"notice\":\"return the deposit (for gas payment) of the account\"},\"depositTo(address)\":{\"notice\":\"add to the deposit of the given account\"},\"deposits(address)\":{\"notice\":\"maps paymaster to their deposits and stakes\"},\"getNonce(address,uint192)\":{\"notice\":\"Return the next nonce for this sender. Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) But UserOp with different keys can come with arbitrary order.\"},\"getSenderAddress(bytes)\":{\"notice\":\"Get counterfactual sender address. Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. this method always revert, and returns the address in SenderAddressResult error\"},\"getUserOpHash((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"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.\"},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperation with Aggregators\"},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperations. no signature aggregator is used. if any account requires an aggregator (that is, it returned an aggregator when performing simulateValidation), then handleAggregatedOps() must be used instead.\"},\"incrementNonce(uint192)\":{\"notice\":\"Manually increment the nonce of the sender. This method is exposed just for completeness.. Account does NOT need to call it, neither during validation, nor elsewhere, as the EntryPoint will update the nonce regardless. Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future UserOperations will not pay extra for the first transaction with a given key.\"},\"innerHandleOp(bytes,((address,uint256,uint256,uint256,uint256,address,uint256,uint256),bytes32,uint256,uint256,uint256),bytes)\":{\"notice\":\"inner function to handle a UserOperation. Must be declared \\\"external\\\" to open a call context, but it can only be called by handleOps.\"},\"nonceSequenceNumber(address,uint192)\":{\"notice\":\"The next valid sequence number for a given nonce key.\"},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"notice\":\"simulate full execution of a UserOperation (including both validation and target execution) this method will always revert with \\\"ExecutionResult\\\". it performs full validation of the UserOperation, but ignores signature error. an optional target address is called after the userop succeeds, and its value is returned (before the entire call is reverted) Note that in order to collect the the success/failure of the target call, it must be executed with trace enabled to track the emitted events.\"},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\"},\"unlockStake()\":{\"notice\":\"attempt to unlock the stake. the value can be withdrawn (using withdrawStake) after the unstake delay.\"},\"withdrawStake(address)\":{\"notice\":\"withdraw from the (unlocked) stake. must first call unlockStake and wait for the unstakeDelay to pass\"},\"withdrawTo(address,uint256)\":{\"notice\":\"withdraw from the deposit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/core/EntryPoint.sol\":\"EntryPoint\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0x190dd6f8d592b7e4e930feb7f4313aeb8e1c4ad3154c27ce1cf6a512fc30d8cc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ce8dfb62d0c4fa260d6eec8f1cd47f5f2a044e11bde5b31d18072fa6e7d9010\",\"dweb:/ipfs/QmTyFztU3tLEcEDnqqiaW4UJetqsU77LXc6pjc9oTXCK5u\"]},\"contracts/core/EntryPoint.sol\":{\"keccak256\":\"0x04f86318b47f052d7308795ffae6ecec0d023d2458b4e17751b89a0e4acfcdc6\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://c9f6e359c8dbe875ad974d3a0fb7b3d62319a6b115c44bac1e4587ae2ad2edaf\",\"dweb:/ipfs/QmTSWTov2rUeYk8cwzrtsd3uVXokCYok4gMiZ1sPs9tycH\"]},\"contracts/core/Helpers.sol\":{\"keccak256\":\"0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746\",\"dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU\"]},\"contracts/core/NonceManager.sol\":{\"keccak256\":\"0xa17a4a6fde70088ab18ffe6df830f3efa31f1cd0e1a7160336c96e3c94984d25\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://b38615df9f80c56282b72888e9ba1eb1a9413fa67a0dbf094deda7af9feb38e7\",\"dweb:/ipfs/QmSzcXetEJRH4UHuUmZiSgX6bFgfqHWfmyuxVnh4NosMk1\"]},\"contracts/core/SenderCreator.sol\":{\"keccak256\":\"0x44b9449fec82d6cdfb01d52fdd5a72f90099c651316123810cf9633f00b018c2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a9c0487390e72638681d175c45bc92425c802fffdca4bd0ae8457782ee284612\",\"dweb:/ipfs/QmVbzuehCUWJWqEHyMWuc6cRVbxfcMdFsmGL9o4Wz7WY2x\"]},\"contracts/core/StakeManager.sol\":{\"keccak256\":\"0x21aa0956382bd000b1b8c3b1d19ca6ebcd6c9029eebb19c612fb38ee5dd2430a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0a625c8795354d9f429367f9c1d14eb8af7db9c7f2c2a2033e2066ced76a573a\",\"dweb:/ipfs/Qmd1j6UarUg54q1G2HCNCLQz8XGVZR1qxX7eQ6cytHpQPN\"]},\"contracts/interfaces/IAccount.sol\":{\"keccak256\":\"0x556a0e5980de18e90b115553ed502408155ba35f58642823010d9288047bc418\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a0f420134b79596db8737173c7b933ae0a33059e107b6327c43aa40d4744a9e4\",\"dweb:/ipfs/QmRo8s1AhXmEMV7uPYnbpYwU19e9Bk6jmYBJTiPx3Fo85W\"]},\"contracts/interfaces/IAggregator.sol\":{\"keccak256\":\"0x060e9ddb0152250c269ba0640dc5753834ac44cf182a2837d508c0c529cae26a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://20ed837bc5909c89ff1910246bf245a5dad6840aa939382e1694964eb7dbd37b\",\"dweb:/ipfs/QmTMybRq5yyghPDDs1ZCNAVB9sSJ4WHe6Q9mejuKPTAdNP\"]},\"contracts/interfaces/IEntryPoint.sol\":{\"keccak256\":\"0x3a90bf308819ed125fa4202f880999caff8a8686633b8ddb79a30ca240d5b8f8\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://d2d21cc92c2fdab2b58d21bc25d4cd0e8c284b922528a186b087b818d54bc6cf\",\"dweb:/ipfs/QmT1qrfuBjsv2rmRCDn8mgPXHp94hARJwzbcDuBLDTbFWd\"]},\"contracts/interfaces/INonceManager.sol\":{\"keccak256\":\"0x509871e6c63663cdcc3eba19920fe84e991f38b289b1377ac3c3a6d9f22d7e12\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://00fe21b4349b24c50df60e1a705179293982bd9e7a32b78d4bac9620f89e7fe2\",\"dweb:/ipfs/QmSFFYGfUwQbVa6hASjU7YxTvgi2HkfrPr4X5oPHscHg8b\"]},\"contracts/interfaces/IPaymaster.sol\":{\"keccak256\":\"0x36858ba8685024974f533530420688da3454d29996ebc42e410673a1ed2ec456\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://616cbcf51778b1961b7f20a547bec7efae6d1d565df0f651926241ed8bde9ad8\",\"dweb:/ipfs/QmaVsgffUUmeUJYgStvRr8cNZ1LBbrc3FYNLW4JT1dVLia\"]},\"contracts/interfaces/IStakeManager.sol\":{\"keccak256\":\"0xd227b02888cd4ac68daebcdfd992ec00f9fff66fa3b3bb16f656cd582fa3480f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://b389da4714a138be63704a576a482505eab2855e263b38a93706395d8d42e7c3\",\"dweb:/ipfs/QmeeAZpdHwUXxqP8pxA7GNtoCGBmmH4FaqLLwScVKGxtxZ\"]},\"contracts/interfaces/UserOperation.sol\":{\"keccak256\":\"0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c\",\"dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN\"]},\"contracts/utils/Exec.sol\":{\"keccak256\":\"0x5b232117afbc2939f3ffc92745614867e9e1d475a3e1e5443adae13c200174f1\",\"license\":\"LGPL-3.0-only\",\"urls\":[\"bzz-raw://62e7365379a06ead7b47637945bcaee095d51aab1d3ac00ddec69443e6cbe9fe\",\"dweb:/ipfs/QmctG3aw4U3KMSMeJKoLJ1NJewjMWfppnd1m3kxNTe39Uy\"]}},\"version\":1}",
+ "bytecode": "0x60a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033",
+ "deployedBytecode": "0x60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c63430008110033"
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/SimpleAccountFactory.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/SimpleAccountFactory.json
new file mode 100644
index 00000000..4559ec0a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/SimpleAccountFactory.json
@@ -0,0 +1,107 @@
+{
+ "address": "0x9406Cc6185a346906296840746125a0E44976454",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "contract IEntryPoint",
+ "name": "_entryPoint",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "constructor"
+ },
+ {
+ "inputs": [],
+ "name": "accountImplementation",
+ "outputs": [
+ {
+ "internalType": "contract SimpleAccount",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "salt",
+ "type": "uint256"
+ }
+ ],
+ "name": "createAccount",
+ "outputs": [
+ {
+ "internalType": "contract SimpleAccount",
+ "name": "ret",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "salt",
+ "type": "uint256"
+ }
+ ],
+ "name": "getAddress",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+ ],
+ "args": [
+ "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
+ ],
+ "numDeployments": 1,
+ "solcInputHash": "02113a2ed1850c3774563305ee607f11",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.15+commit.e14f2714\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"contract IEntryPoint\",\"name\":\"_entryPoint\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"accountImplementation\",\"outputs\":[{\"internalType\":\"contract SimpleAccount\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"salt\",\"type\":\"uint256\"}],\"name\":\"createAccount\",\"outputs\":[{\"internalType\":\"contract SimpleAccount\",\"name\":\"ret\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"salt\",\"type\":\"uint256\"}],\"name\":\"getAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAccount(address,uint256)\":{\"notice\":\"create an account, and return its address. returns the address even if the account is already deployed. Note that during UserOperation execution, this method is called only if the account is not deployed. This method returns an existing account address so that entryPoint.getSenderAddress() would work even after account creation\"},\"getAddress(address,uint256)\":{\"notice\":\"calculate the counterfactual address of this account as it would be returned by createAccount()\"}},\"notice\":\"A sample factory contract for SimpleAccount A UserOperations \\\"initCode\\\" holds the address of the factory, and a method call (to createAccount, in this sample factory). The factory's createAccount returns the target account address even if it is already installed. This way, the entryPoint.getSenderAddress() can be called either before or after the account is created.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/samples/SimpleAccountFactory.sol\":\"SimpleAccountFactory\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\\n * proxy whose upgrades are fully controlled by the current implementation.\\n */\\ninterface IERC1822Proxiable {\\n /**\\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\\n * address.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy.\\n */\\n function proxiableUUID() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x1d4afe6cb24200cc4545eed814ecf5847277dfe5d613a1707aad5fceecebcfff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Proxy.sol\\\";\\nimport \\\"./ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\\n * implementation address that can be changed. This address is stored in storage in the location specified by\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\\n * implementation behind the proxy.\\n */\\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\\n /**\\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\\n *\\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\\n */\\n constructor(address _logic, bytes memory _data) payable {\\n _upgradeToAndCall(_logic, _data, false);\\n }\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _implementation() internal view virtual override returns (address impl) {\\n return ERC1967Upgrade._getImplementation();\\n }\\n}\\n\",\"keccak256\":\"0xa2b22da3032e50b55f95ec1d13336102d675f341167aa76db571ef7f8bb7975d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../beacon/IBeacon.sol\\\";\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\nimport \\\"../../utils/StorageSlot.sol\\\";\\n\\n/**\\n * @dev This abstract contract provides getters and event emitting update functions for\\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\\n *\\n * _Available since v4.1._\\n *\\n * @custom:oz-upgrades-unsafe-allow delegatecall\\n */\\nabstract contract ERC1967Upgrade {\\n // This is the keccak-256 hash of \\\"eip1967.proxy.rollback\\\" subtracted by 1\\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\\n\\n /**\\n * @dev Storage slot with the address of the current implementation.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.implementation\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n\\n /**\\n * @dev Emitted when the implementation is upgraded.\\n */\\n event Upgraded(address indexed implementation);\\n\\n /**\\n * @dev Returns the current implementation address.\\n */\\n function _getImplementation() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 implementation slot.\\n */\\n function _setImplementation(address newImplementation) private {\\n require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n }\\n\\n /**\\n * @dev Perform implementation upgrade\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeTo(address newImplementation) internal {\\n _setImplementation(newImplementation);\\n emit Upgraded(newImplementation);\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCall(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _upgradeTo(newImplementation);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(newImplementation, data);\\n }\\n }\\n\\n /**\\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function _upgradeToAndCallUUPS(\\n address newImplementation,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n // Upgrades from old implementations will perform a rollback test. This test requires the new\\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\\n // this special case will break upgrade paths from old UUPS implementation to new ones.\\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\\n _setImplementation(newImplementation);\\n } else {\\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\\n require(slot == _IMPLEMENTATION_SLOT, \\\"ERC1967Upgrade: unsupported proxiableUUID\\\");\\n } catch {\\n revert(\\\"ERC1967Upgrade: new implementation is not UUPS\\\");\\n }\\n _upgradeToAndCall(newImplementation, data, forceCall);\\n }\\n }\\n\\n /**\\n * @dev Storage slot with the admin of the contract.\\n * This is the keccak-256 hash of \\\"eip1967.proxy.admin\\\" subtracted by 1, and is\\n * validated in the constructor.\\n */\\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\\n\\n /**\\n * @dev Emitted when the admin account has changed.\\n */\\n event AdminChanged(address previousAdmin, address newAdmin);\\n\\n /**\\n * @dev Returns the current admin.\\n */\\n function _getAdmin() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new address in the EIP1967 admin slot.\\n */\\n function _setAdmin(address newAdmin) private {\\n require(newAdmin != address(0), \\\"ERC1967: new admin is the zero address\\\");\\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\\n }\\n\\n /**\\n * @dev Changes the admin of the proxy.\\n *\\n * Emits an {AdminChanged} event.\\n */\\n function _changeAdmin(address newAdmin) internal {\\n emit AdminChanged(_getAdmin(), newAdmin);\\n _setAdmin(newAdmin);\\n }\\n\\n /**\\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\\n */\\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\\n\\n /**\\n * @dev Emitted when the beacon is upgraded.\\n */\\n event BeaconUpgraded(address indexed beacon);\\n\\n /**\\n * @dev Returns the current beacon.\\n */\\n function _getBeacon() internal view returns (address) {\\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\\n }\\n\\n /**\\n * @dev Stores a new beacon in the EIP1967 beacon slot.\\n */\\n function _setBeacon(address newBeacon) private {\\n require(Address.isContract(newBeacon), \\\"ERC1967: new beacon is not a contract\\\");\\n require(\\n Address.isContract(IBeacon(newBeacon).implementation()),\\n \\\"ERC1967: beacon implementation is not a contract\\\"\\n );\\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\\n }\\n\\n /**\\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\\n *\\n * Emits a {BeaconUpgraded} event.\\n */\\n function _upgradeBeaconToAndCall(\\n address newBeacon,\\n bytes memory data,\\n bool forceCall\\n ) internal {\\n _setBeacon(newBeacon);\\n emit BeaconUpgraded(newBeacon);\\n if (data.length > 0 || forceCall) {\\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xabf3f59bc0e5423eae45e459dbe92e7052c6983628d39008590edc852a62f94a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/Proxy.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\\n * be specified by overriding the virtual {_implementation} function.\\n *\\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\\n * different contract through the {_delegate} function.\\n *\\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\\n */\\nabstract contract Proxy {\\n /**\\n * @dev Delegates the current call to `implementation`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _delegate(address implementation) internal virtual {\\n assembly {\\n // Copy msg.data. We take full control of memory in this inline assembly\\n // block because it will not return to Solidity code. We overwrite the\\n // Solidity scratch pad at memory position 0.\\n calldatacopy(0, 0, calldatasize())\\n\\n // Call the implementation.\\n // out and outsize are 0 because we don't know the size yet.\\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\\n\\n // Copy the returned data.\\n returndatacopy(0, 0, returndatasize())\\n\\n switch result\\n // delegatecall returns 0 on error.\\n case 0 {\\n revert(0, returndatasize())\\n }\\n default {\\n return(0, returndatasize())\\n }\\n }\\n }\\n\\n /**\\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\\n * and {_fallback} should delegate.\\n */\\n function _implementation() internal view virtual returns (address);\\n\\n /**\\n * @dev Delegates the current call to the address returned by `_implementation()`.\\n *\\n * This function does not return to its internal call site, it will return directly to the external caller.\\n */\\n function _fallback() internal virtual {\\n _beforeFallback();\\n _delegate(_implementation());\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\\n * function in the contract matches the call data.\\n */\\n fallback() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\\n * is empty.\\n */\\n receive() external payable virtual {\\n _fallback();\\n }\\n\\n /**\\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\\n * call, or as part of the Solidity `fallback` or `receive` functions.\\n *\\n * If overridden should call `super._beforeFallback()`.\\n */\\n function _beforeFallback() internal virtual {}\\n}\\n\",\"keccak256\":\"0xc130fe33f1b2132158531a87734153293f6d07bc263ff4ac90e85da9c82c0e27\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/beacon/IBeacon.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\\n */\\ninterface IBeacon {\\n /**\\n * @dev Must return an address that can be used as a delegate call target.\\n *\\n * {BeaconProxy} will check that this address is a contract.\\n */\\n function implementation() external view returns (address);\\n}\\n\",\"keccak256\":\"0xd50a3421ac379ccb1be435fa646d66a65c986b4924f0849839f08692f39dde61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.2;\\n\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n * @custom:oz-retyped-from bool\\n */\\n uint8 private _initialized;\\n\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool private _initializing;\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint8 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\\n * constructor.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n bool isTopLevelCall = !_initializing;\\n require(\\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\\n \\\"Initializable: contract is already initialized\\\"\\n );\\n _initialized = 1;\\n if (isTopLevelCall) {\\n _initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n _initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: setting the version to 255 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint8 version) {\\n require(!_initializing && _initialized < version, \\\"Initializable: contract is already initialized\\\");\\n _initialized = version;\\n _initializing = true;\\n _;\\n _initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n require(_initializing, \\\"Initializable: contract is not initializing\\\");\\n _;\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n require(!_initializing, \\\"Initializable: contract is initializing\\\");\\n if (_initialized < type(uint8).max) {\\n _initialized = type(uint8).max;\\n emit Initialized(type(uint8).max);\\n }\\n }\\n\\n /**\\n * @dev Internal function that returns the initialized version. Returns `_initialized`\\n */\\n function _getInitializedVersion() internal view returns (uint8) {\\n return _initialized;\\n }\\n\\n /**\\n * @dev Internal function that returns the initialized version. Returns `_initializing`\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _initializing;\\n }\\n}\\n\",\"keccak256\":\"0xcee5467d5d873fb75dae6f98c01a8d25dd609f9d0374c7d39217bd5f9539a2d6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../interfaces/draft-IERC1822.sol\\\";\\nimport \\\"../ERC1967/ERC1967Upgrade.sol\\\";\\n\\n/**\\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\\n *\\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\\n * `UUPSUpgradeable` with a custom implementation of upgrades.\\n *\\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\\n *\\n * _Available since v4.1._\\n */\\nabstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {\\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\\n address private immutable __self = address(this);\\n\\n /**\\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\\n * fail.\\n */\\n modifier onlyProxy() {\\n require(address(this) != __self, \\\"Function must be called through delegatecall\\\");\\n require(_getImplementation() == __self, \\\"Function must be called through active proxy\\\");\\n _;\\n }\\n\\n /**\\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\\n * callable on the implementing contract but not through proxies.\\n */\\n modifier notDelegated() {\\n require(address(this) == __self, \\\"UUPSUpgradeable: must not be called through delegatecall\\\");\\n _;\\n }\\n\\n /**\\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\\n *\\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\\n */\\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\\n return _IMPLEMENTATION_SLOT;\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function upgradeTo(address newImplementation) external virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\\n }\\n\\n /**\\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\\n * encoded in `data`.\\n *\\n * Calls {_authorizeUpgrade}.\\n *\\n * Emits an {Upgraded} event.\\n */\\n function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {\\n _authorizeUpgrade(newImplementation);\\n _upgradeToAndCallUUPS(newImplementation, data, true);\\n }\\n\\n /**\\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\\n * {upgradeTo} and {upgradeToAndCall}.\\n *\\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\\n *\\n * ```solidity\\n * function _authorizeUpgrade(address) internal override onlyOwner {}\\n * ```\\n */\\n function _authorizeUpgrade(address newImplementation) internal virtual;\\n}\\n\",\"keccak256\":\"0x85cc5aca68692044586dc5ca19a9868d3288f6b35d1085c620dd0278ed0abdaa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev _Available since v3.1._\\n */\\ninterface IERC1155Receiver is IERC165 {\\n /**\\n * @dev Handles the receipt of a single ERC1155 token type. This function is\\n * called at the end of a `safeTransferFrom` after the balance has been updated.\\n *\\n * NOTE: To accept the transfer, this must return\\n * `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))`\\n * (i.e. 0xf23a6e61, or its own function selector).\\n *\\n * @param operator The address which initiated the transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param id The ID of the token being transferred\\n * @param value The amount of tokens being transferred\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155Received(address,address,uint256,uint256,bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155Received(\\n address operator,\\n address from,\\n uint256 id,\\n uint256 value,\\n bytes calldata data\\n ) external returns (bytes4);\\n\\n /**\\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\\n * is called at the end of a `safeBatchTransferFrom` after the balances have\\n * been updated.\\n *\\n * NOTE: To accept the transfer(s), this must return\\n * `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))`\\n * (i.e. 0xbc197c81, or its own function selector).\\n *\\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\\n * @param from The address which previously owned the token\\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\\n * @param data Additional data with no specified format\\n * @return `bytes4(keccak256(\\\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\\\"))` if transfer is allowed\\n */\\n function onERC1155BatchReceived(\\n address operator,\\n address from,\\n uint256[] calldata ids,\\n uint256[] calldata values,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xeb373f1fdc7b755c6a750123a9b9e3a8a02c1470042fd6505d875000a80bde0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0xa82b58eca1ee256be466e536706850163d2ec7821945abd6b4778cfb3bee37da\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\\n *\\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\\n * contract implement this interface (contract holders can be their own\\n * implementer) and registering it on the\\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\\n *\\n * See {IERC1820Registry} and {ERC1820Implementer}.\\n */\\ninterface IERC777Recipient {\\n /**\\n * @dev Called by an {IERC777} token contract whenever tokens are being\\n * moved or created into a registered account (`to`). The type of operation\\n * is conveyed by `from` being the zero address or not.\\n *\\n * This call occurs _after_ the token contract's state is updated, so\\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\\n *\\n * This function may revert to prevent the operation from being executed.\\n */\\n function tokensReceived(\\n address operator,\\n address from,\\n address to,\\n uint256 amount,\\n bytes calldata userData,\\n bytes calldata operatorData\\n ) external;\\n}\\n\",\"keccak256\":\"0x1a5d61db2733202ba361e6d6741cd2e662380e22b80e987eacfc91973f2267dc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.1;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n *\\n * [IMPORTANT]\\n * ====\\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\\n *\\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\\n * constructor.\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize/address.code.length, which returns 0\\n // for contracts in construction, since the code is only stored at the end\\n // of the constructor execution.\\n\\n return account.code.length > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\\n *\\n * _Available since v4.8._\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n if (success) {\\n if (returndata.length == 0) {\\n // only check isContract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n }\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason or using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n _revert(returndata, errorMessage);\\n }\\n }\\n\\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Create2.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Create2.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.\\n * `CREATE2` can be used to compute in advance the address where a smart\\n * contract will be deployed, which allows for interesting new mechanisms known\\n * as 'counterfactual interactions'.\\n *\\n * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more\\n * information.\\n */\\nlibrary Create2 {\\n /**\\n * @dev Deploys a contract using `CREATE2`. The address where the contract\\n * will be deployed can be known in advance via {computeAddress}.\\n *\\n * The bytecode for a contract can be obtained from Solidity with\\n * `type(contractName).creationCode`.\\n *\\n * Requirements:\\n *\\n * - `bytecode` must not be empty.\\n * - `salt` must have not been used for `bytecode` already.\\n * - the factory must have a balance of at least `amount`.\\n * - if `amount` is non-zero, `bytecode` must have a `payable` constructor.\\n */\\n function deploy(\\n uint256 amount,\\n bytes32 salt,\\n bytes memory bytecode\\n ) internal returns (address addr) {\\n require(address(this).balance >= amount, \\\"Create2: insufficient balance\\\");\\n require(bytecode.length != 0, \\\"Create2: bytecode length is zero\\\");\\n /// @solidity memory-safe-assembly\\n assembly {\\n addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)\\n }\\n require(addr != address(0), \\\"Create2: Failed on deploy\\\");\\n }\\n\\n /**\\n * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the\\n * `bytecodeHash` or `salt` will result in a new destination address.\\n */\\n function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {\\n return computeAddress(salt, bytecodeHash, address(this));\\n }\\n\\n /**\\n * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at\\n * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.\\n */\\n function computeAddress(\\n bytes32 salt,\\n bytes32 bytecodeHash,\\n address deployer\\n ) internal pure returns (address addr) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40) // Get free memory pointer\\n\\n // | | \\u2193 ptr ... \\u2193 ptr + 0x0B (start) ... \\u2193 ptr + 0x20 ... \\u2193 ptr + 0x40 ... |\\n // |-------------------|---------------------------------------------------------------------------|\\n // | bytecodeHash | CCCCCCCCCCCCC...CC |\\n // | salt | BBBBBBBBBBBBB...BB |\\n // | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA |\\n // | 0xFF | FF |\\n // |-------------------|---------------------------------------------------------------------------|\\n // | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |\\n // | keccak(start, 85) | \\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191\\u2191 |\\n\\n mstore(add(ptr, 0x40), bytecodeHash)\\n mstore(add(ptr, 0x20), salt)\\n mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes\\n let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff\\n mstore8(start, 0xff)\\n addr := keccak256(start, 85)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xafc07f37809f74d9c66d6461cc0f85fb5147ab855acd0acc30af4b2272130c61\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/StorageSlot.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for reading and writing primitive types to specific storage slots.\\n *\\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\\n * This library helps with reading and writing to such slots without the need for inline assembly.\\n *\\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\\n *\\n * Example usage to set ERC1967 implementation slot:\\n * ```\\n * contract ERC1967 {\\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\\n *\\n * function _getImplementation() internal view returns (address) {\\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\\n * }\\n *\\n * function _setImplementation(address newImplementation) internal {\\n * require(Address.isContract(newImplementation), \\\"ERC1967: new implementation is not a contract\\\");\\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\\n * }\\n * }\\n * ```\\n *\\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\\n */\\nlibrary StorageSlot {\\n struct AddressSlot {\\n address value;\\n }\\n\\n struct BooleanSlot {\\n bool value;\\n }\\n\\n struct Bytes32Slot {\\n bytes32 value;\\n }\\n\\n struct Uint256Slot {\\n uint256 value;\\n }\\n\\n /**\\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\\n */\\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\\n */\\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\\n */\\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n\\n /**\\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\\n */\\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n r.slot := slot\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd5c50c54bf02740ebd122ff06832546cb5fa84486d52695a9ccfd11666e0c81d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./math/Math.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xa4d1d62251f8574deb032a35fc948386a9b4de74b812d4f545a1ac120486b48a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV // Deprecated in v4.8\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n /// @solidity memory-safe-assembly\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from `s`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", Strings.toString(s.length), s));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xda898fa084aa1ddfdb346e6a40459e00a59d87071cce7c315a46d648dd71d0ba\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n /**\\n * @dev Returns true if this contract implements the interface defined by\\n * `interfaceId`. See the corresponding\\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n * to learn more about how these ids are created.\\n *\\n * This function call must use less than 30 000 gas.\\n */\\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x447a5f3ddc18419d41ff92b3773fb86471b1db25773e07f877f548918a185bf1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n enum Rounding {\\n Down, // Toward negative infinity\\n Up, // Toward infinity\\n Zero // Toward zero\\n }\\n\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\\n * with further edits by Uniswap Labs also under MIT license.\\n */\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 denominator\\n ) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod0 := mul(x, y)\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n require(denominator > prod1);\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\\n // See https://cs.stackexchange.com/q/138556/92363.\\n\\n // Does not overflow because the denominator cannot be zero at this stage in the function.\\n uint256 twos = denominator & (~denominator + 1);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\\n // in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(\\n uint256 x,\\n uint256 y,\\n uint256 denominator,\\n Rounding rounding\\n ) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10**64) {\\n value /= 10**64;\\n result += 64;\\n }\\n if (value >= 10**32) {\\n value /= 10**32;\\n result += 32;\\n }\\n if (value >= 10**16) {\\n value /= 10**16;\\n result += 16;\\n }\\n if (value >= 10**8) {\\n value /= 10**8;\\n result += 8;\\n }\\n if (value >= 10**4) {\\n value /= 10**4;\\n result += 4;\\n }\\n if (value >= 10**2) {\\n value /= 10**2;\\n result += 2;\\n }\\n if (value >= 10**1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256, rounded down, of a positive value.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\"},\"contracts/core/BaseAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"../interfaces/IAccount.sol\\\";\\nimport \\\"../interfaces/IEntryPoint.sol\\\";\\nimport \\\"./Helpers.sol\\\";\\n\\n/**\\n * Basic account implementation.\\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\\n * specific account implementation should inherit it and provide the account-specific logic\\n */\\nabstract contract BaseAccount is IAccount {\\n using UserOperationLib for UserOperation;\\n\\n //return value in case of signature failure, with no time-range.\\n // equivalent to _packValidationData(true,0,0);\\n uint256 constant internal SIG_VALIDATION_FAILED = 1;\\n\\n /**\\n * Return the account nonce.\\n * This method returns the next sequential nonce.\\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\\n */\\n function getNonce() public view virtual returns (uint256) {\\n return entryPoint().getNonce(address(this), 0);\\n }\\n\\n /**\\n * return the entryPoint used by this account.\\n * subclass should return the current entryPoint used by this account.\\n */\\n function entryPoint() public view virtual returns (IEntryPoint);\\n\\n /**\\n * Validate user's signature and nonce.\\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\\n */\\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\\n external override virtual returns (uint256 validationData) {\\n _requireFromEntryPoint();\\n validationData = _validateSignature(userOp, userOpHash);\\n _validateNonce(userOp.nonce);\\n _payPrefund(missingAccountFunds);\\n }\\n\\n /**\\n * ensure the request comes from the known entrypoint.\\n */\\n function _requireFromEntryPoint() internal virtual view {\\n require(msg.sender == address(entryPoint()), \\\"account: not from EntryPoint\\\");\\n }\\n\\n /**\\n * validate the signature is valid for this message.\\n * @param userOp validate the userOp.signature field\\n * @param userOpHash convenient field: the hash of the request, to check the signature against\\n * (also hashes the entrypoint and chain id)\\n * @return validationData signature and time-range of this operation\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)\\n internal virtual returns (uint256 validationData);\\n\\n /**\\n * Validate the nonce of the UserOperation.\\n * This method may validate the nonce requirement of this account.\\n * e.g.\\n * To limit the nonce to use sequenced UserOps only (no \\\"out of order\\\" UserOps):\\n * `require(nonce < type(uint64).max)`\\n * For a hypothetical account that *requires* the nonce to be out-of-order:\\n * `require(nonce & type(uint64).max == 0)`\\n *\\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\\n * action is needed by the account itself.\\n *\\n * @param nonce to validate\\n *\\n * solhint-disable-next-line no-empty-blocks\\n */\\n function _validateNonce(uint256 nonce) internal view virtual {\\n }\\n\\n /**\\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\\n * subclass MAY override this method for better funds management\\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\\n * it will not be required to send again)\\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\\n */\\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\\n if (missingAccountFunds != 0) {\\n (bool success,) = payable(msg.sender).call{value : missingAccountFunds, gas : type(uint256).max}(\\\"\\\");\\n (success);\\n //ignore failure (its EntryPoint's job to verify, not account.)\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5eb3253b32fd8ba8ae7b9d83da8e9924254a4d3d17a8772b41280e8572974b3c\",\"license\":\"GPL-3.0\"},\"contracts/core/Helpers.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\n/**\\n * returned data from validateUserOp.\\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\\n * @param aggregator - address(0) - the account validated the signature by itself.\\n * address(1) - the account failed to validate the signature.\\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\\n * @param validAfter - this UserOp is valid only after this timestamp.\\n * @param validaUntil - this UserOp is valid only up to this timestamp.\\n */\\n struct ValidationData {\\n address aggregator;\\n uint48 validAfter;\\n uint48 validUntil;\\n }\\n\\n//extract sigFailed, validAfter, validUntil.\\n// also convert zero validUntil to type(uint48).max\\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\\n address aggregator = address(uint160(validationData));\\n uint48 validUntil = uint48(validationData >> 160);\\n if (validUntil == 0) {\\n validUntil = type(uint48).max;\\n }\\n uint48 validAfter = uint48(validationData >> (48 + 160));\\n return ValidationData(aggregator, validAfter, validUntil);\\n }\\n\\n// intersect account and paymaster ranges.\\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\\n ValidationData memory accountValidationData = _parseValidationData(validationData);\\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\\n address aggregator = accountValidationData.aggregator;\\n if (aggregator == address(0)) {\\n aggregator = pmValidationData.aggregator;\\n }\\n uint48 validAfter = accountValidationData.validAfter;\\n uint48 validUntil = accountValidationData.validUntil;\\n uint48 pmValidAfter = pmValidationData.validAfter;\\n uint48 pmValidUntil = pmValidationData.validUntil;\\n\\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\\n return ValidationData(aggregator, validAfter, validUntil);\\n }\\n\\n/**\\n * helper to pack the return value for validateUserOp\\n * @param data - the ValidationData to pack\\n */\\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\\n }\\n\\n/**\\n * helper to pack the return value for validateUserOp, when not using an aggregator\\n * @param sigFailed - true for signature failure, false for success\\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\\n * @param validAfter first timestamp this UserOperation is valid\\n */\\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\\n }\\n\\n/**\\n * keccak function over calldata.\\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\\n */\\n function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\\n assembly {\\n let mem := mload(0x40)\\n let len := data.length\\n calldatacopy(mem, data.offset, len)\\n ret := keccak256(mem, len)\\n }\\n }\\n\\n\",\"keccak256\":\"0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\ninterface IAccount {\\n\\n /**\\n * Validate user's signature and nonce\\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\\n * This allows making a \\\"simulation call\\\" without a valid signature\\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\\n *\\n * @dev Must validate caller is the entryPoint.\\n * Must validate the signature and nonce\\n * @param userOp the operation that is about to be executed.\\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\\n * The excess is left as a deposit in the entrypoint, for future calls.\\n * can be withdrawn anytime using \\\"entryPoint.withdrawTo()\\\"\\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\\n * otherwise, an address of an \\\"authorizer\\\" contract.\\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \\\"indefinite\\\"\\n * <6-byte> validAfter - first timestamp this operation is valid\\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\\n */\\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\\n external returns (uint256 validationData);\\n}\\n\",\"keccak256\":\"0x556a0e5980de18e90b115553ed502408155ba35f58642823010d9288047bc418\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IAggregator.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"./UserOperation.sol\\\";\\n\\n/**\\n * Aggregated Signatures validator.\\n */\\ninterface IAggregator {\\n\\n /**\\n * validate aggregated signature.\\n * revert if the aggregated signature does not match the given list of operations.\\n */\\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\\n\\n /**\\n * validate signature of a single userOp\\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\\n * @param userOp the userOperation received from the user.\\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\\n * (usually empty, unless account and aggregator support some kind of \\\"multisig\\\"\\n */\\n function validateUserOpSignature(UserOperation calldata userOp)\\n external view returns (bytes memory sigForUserOp);\\n\\n /**\\n * aggregate multiple signatures into a single value.\\n * This method is called off-chain to calculate the signature to pass with handleOps()\\n * bundler MAY use optimized custom code perform this aggregation\\n * @param userOps array of UserOperations to collect the signatures from.\\n * @return aggregatedSignature the aggregated signature\\n */\\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\\n}\\n\",\"keccak256\":\"0x060e9ddb0152250c269ba0640dc5753834ac44cf182a2837d508c0c529cae26a\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IEntryPoint.sol\":{\"content\":\"/**\\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\\n ** Only one instance required on each chain.\\n **/\\n// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"./UserOperation.sol\\\";\\nimport \\\"./IStakeManager.sol\\\";\\nimport \\\"./IAggregator.sol\\\";\\nimport \\\"./INonceManager.sol\\\";\\n\\ninterface IEntryPoint is IStakeManager, INonceManager {\\n\\n /***\\n * An event emitted after each successful request\\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\\n * @param sender - the account that generates this request.\\n * @param paymaster - if non-null, the paymaster that pays for this request.\\n * @param nonce - the nonce value from the request.\\n * @param success - true if the sender transaction succeeded, false if reverted.\\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\\n */\\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\\n\\n /**\\n * account \\\"sender\\\" was deployed.\\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\\n * @param sender the account that is deployed\\n * @param factory the factory used to deploy this account (in the initCode)\\n * @param paymaster the paymaster used by this UserOp\\n */\\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\\n\\n /**\\n * An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\\n * @param userOpHash the request unique identifier.\\n * @param sender the sender of this request\\n * @param nonce the nonce used in the request\\n * @param revertReason - the return bytes from the (reverted) call to \\\"callData\\\".\\n */\\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\\n\\n /**\\n * an event emitted by handleOps(), before starting the execution loop.\\n * any event emitted before this event, is part of the validation.\\n */\\n event BeforeExecution();\\n\\n /**\\n * signature aggregator used by the following UserOperationEvents within this bundle.\\n */\\n event SignatureAggregatorChanged(address indexed aggregator);\\n\\n /**\\n * a custom revert error of handleOps, to identify the offending op.\\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\\n * @param reason - revert reason\\n * The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues,\\n * so a failure can be attributed to the correct entity.\\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\\n */\\n error FailedOp(uint256 opIndex, string reason);\\n\\n /**\\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\\n */\\n error SignatureValidationFailed(address aggregator);\\n\\n /**\\n * Successful result from simulateValidation.\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n */\\n error ValidationResult(ReturnInfo returnInfo,\\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\\n\\n /**\\n * Successful result from simulateValidation, if the account returns a signature aggregator\\n * @param returnInfo gas and time-range returned values\\n * @param senderInfo stake information about the sender\\n * @param factoryInfo stake information about the factory (if any)\\n * @param paymasterInfo stake information about the paymaster (if any)\\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\\n * bundler MUST use it to verify the signature, or reject the UserOperation\\n */\\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\\n AggregatorStakeInfo aggregatorInfo);\\n\\n /**\\n * return value of getSenderAddress\\n */\\n error SenderAddressResult(address sender);\\n\\n /**\\n * return value of simulateHandleOp\\n */\\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\\n\\n //UserOps handled, per aggregator\\n struct UserOpsPerAggregator {\\n UserOperation[] userOps;\\n\\n // aggregator address\\n IAggregator aggregator;\\n // aggregated signature\\n bytes signature;\\n }\\n\\n /**\\n * Execute a batch of UserOperation.\\n * no signature aggregator is used.\\n * if any account requires an aggregator (that is, it returned an aggregator when\\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\\n * @param ops the operations to execute\\n * @param beneficiary the address to receive the fees\\n */\\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\\n\\n /**\\n * Execute a batch of UserOperation with Aggregators\\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\\n * @param beneficiary the address to receive the fees\\n */\\n function handleAggregatedOps(\\n UserOpsPerAggregator[] calldata opsPerAggregator,\\n address payable beneficiary\\n ) external;\\n\\n /**\\n * generate a request Id - unique identifier for this request.\\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\\n */\\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\\n\\n /**\\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\\n * @param userOp the user operation to validate.\\n */\\n function simulateValidation(UserOperation calldata userOp) external;\\n\\n /**\\n * gas and return values during simulation\\n * @param preOpGas the gas used for validation (including preValidationGas)\\n * @param prefund the required prefund for this operation\\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\\n */\\n struct ReturnInfo {\\n uint256 preOpGas;\\n uint256 prefund;\\n bool sigFailed;\\n uint48 validAfter;\\n uint48 validUntil;\\n bytes paymasterContext;\\n }\\n\\n /**\\n * returned aggregated signature info.\\n * the aggregator returned by the account, and its current stake.\\n */\\n struct AggregatorStakeInfo {\\n address aggregator;\\n StakeInfo stakeInfo;\\n }\\n\\n /**\\n * Get counterfactual sender address.\\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\\n * this method always revert, and returns the address in SenderAddressResult error\\n * @param initCode the constructor code to be passed into the UserOperation.\\n */\\n function getSenderAddress(bytes memory initCode) external;\\n\\n\\n /**\\n * simulate full execution of a UserOperation (including both validation and target execution)\\n * this method will always revert with \\\"ExecutionResult\\\".\\n * it performs full validation of the UserOperation, but ignores signature error.\\n * an optional target address is called after the userop succeeds, and its value is returned\\n * (before the entire call is reverted)\\n * Note that in order to collect the the success/failure of the target call, it must be executed\\n * with trace enabled to track the emitted events.\\n * @param op the UserOperation to simulate\\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\\n * are set to the return from that call.\\n * @param targetCallData callData to pass to target address\\n */\\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\\n}\\n\\n\",\"keccak256\":\"0x3a90bf308819ed125fa4202f880999caff8a8686633b8ddb79a30ca240d5b8f8\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/INonceManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\ninterface INonceManager {\\n\\n /**\\n * Return the next nonce for this sender.\\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\\n * But UserOp with different keys can come with arbitrary order.\\n *\\n * @param sender the account address\\n * @param key the high 192 bit of the nonce\\n * @return nonce a full nonce to pass for next UserOp with this sender.\\n */\\n function getNonce(address sender, uint192 key)\\n external view returns (uint256 nonce);\\n\\n /**\\n * Manually increment the nonce of the sender.\\n * This method is exposed just for completeness..\\n * Account does NOT need to call it, neither during validation, nor elsewhere,\\n * as the EntryPoint will update the nonce regardless.\\n * Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future\\n * UserOperations will not pay extra for the first transaction with a given key.\\n */\\n function incrementNonce(uint192 key) external;\\n}\\n\",\"keccak256\":\"0x509871e6c63663cdcc3eba19920fe84e991f38b289b1377ac3c3a6d9f22d7e12\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/IStakeManager.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity ^0.8.12;\\n\\n/**\\n * manage deposits and stakes.\\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\\n * stake is value locked for at least \\\"unstakeDelay\\\" by the staked entity.\\n */\\ninterface IStakeManager {\\n\\n event Deposited(\\n address indexed account,\\n uint256 totalDeposit\\n );\\n\\n event Withdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /// Emitted when stake or unstake delay are modified\\n event StakeLocked(\\n address indexed account,\\n uint256 totalStaked,\\n uint256 unstakeDelaySec\\n );\\n\\n /// Emitted once a stake is scheduled for withdrawal\\n event StakeUnlocked(\\n address indexed account,\\n uint256 withdrawTime\\n );\\n\\n event StakeWithdrawn(\\n address indexed account,\\n address withdrawAddress,\\n uint256 amount\\n );\\n\\n /**\\n * @param deposit the entity's deposit\\n * @param staked true if this entity is staked.\\n * @param stake actual amount of ether staked for this entity.\\n * @param unstakeDelaySec minimum delay to withdraw the stake.\\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\\n * and the rest fit into a 2nd cell.\\n * 112 bit allows for 10^15 eth\\n * 48 bit for full timestamp\\n * 32 bit allows 150 years for unstake delay\\n */\\n struct DepositInfo {\\n uint112 deposit;\\n bool staked;\\n uint112 stake;\\n uint32 unstakeDelaySec;\\n uint48 withdrawTime;\\n }\\n\\n //API struct used by getStakeInfo and simulateValidation\\n struct StakeInfo {\\n uint256 stake;\\n uint256 unstakeDelaySec;\\n }\\n\\n /// @return info - full deposit information of given account\\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\\n\\n /// @return the deposit (for gas payment) of the account\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * add to the deposit of the given account\\n */\\n function depositTo(address account) external payable;\\n\\n /**\\n * add to the account's stake - amount and delay\\n * any pending unstake is first cancelled.\\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\\n */\\n function addStake(uint32 _unstakeDelaySec) external payable;\\n\\n /**\\n * attempt to unlock the stake.\\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\\n */\\n function unlockStake() external;\\n\\n /**\\n * withdraw from the (unlocked) stake.\\n * must first call unlockStake and wait for the unstakeDelay to pass\\n * @param withdrawAddress the address to send withdrawn value.\\n */\\n function withdrawStake(address payable withdrawAddress) external;\\n\\n /**\\n * withdraw from the deposit.\\n * @param withdrawAddress the address to send withdrawn value.\\n * @param withdrawAmount the amount to withdraw.\\n */\\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\\n}\\n\",\"keccak256\":\"0xd227b02888cd4ac68daebcdfd992ec00f9fff66fa3b3bb16f656cd582fa3480f\",\"license\":\"GPL-3.0-only\"},\"contracts/interfaces/UserOperation.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-inline-assembly */\\n\\nimport {calldataKeccak} from \\\"../core/Helpers.sol\\\";\\n\\n/**\\n * User Operation struct\\n * @param sender the sender account of this request.\\n * @param nonce unique value the sender uses to verify it is not a replay.\\n * @param initCode if set, the account contract will be created by this constructor/\\n * @param callData the method call to execute on this account.\\n * @param callGasLimit the gas limit passed to the callData method call.\\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\\n * @param maxFeePerGas same as EIP-1559 gas parameter.\\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\\n */\\n struct UserOperation {\\n\\n address sender;\\n uint256 nonce;\\n bytes initCode;\\n bytes callData;\\n uint256 callGasLimit;\\n uint256 verificationGasLimit;\\n uint256 preVerificationGas;\\n uint256 maxFeePerGas;\\n uint256 maxPriorityFeePerGas;\\n bytes paymasterAndData;\\n bytes signature;\\n }\\n\\n/**\\n * Utility functions helpful when working with UserOperation structs.\\n */\\nlibrary UserOperationLib {\\n\\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\\n address data;\\n //read sender from userOp, which is first userOp member (saves 800 gas...)\\n assembly {data := calldataload(userOp)}\\n return address(uint160(data));\\n }\\n\\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\\n // pay above what he signed for.\\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\\n unchecked {\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n if (maxFeePerGas == maxPriorityFeePerGas) {\\n //legacy mode (for networks that don't support basefee opcode)\\n return maxFeePerGas;\\n }\\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\\n }\\n }\\n\\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\\n address sender = getSender(userOp);\\n uint256 nonce = userOp.nonce;\\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\\n bytes32 hashCallData = calldataKeccak(userOp.callData);\\n uint256 callGasLimit = userOp.callGasLimit;\\n uint256 verificationGasLimit = userOp.verificationGasLimit;\\n uint256 preVerificationGas = userOp.preVerificationGas;\\n uint256 maxFeePerGas = userOp.maxFeePerGas;\\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\\n\\n return abi.encode(\\n sender, nonce,\\n hashInitCode, hashCallData,\\n callGasLimit, verificationGasLimit, preVerificationGas,\\n maxFeePerGas, maxPriorityFeePerGas,\\n hashPaymasterAndData\\n );\\n }\\n\\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\\n return keccak256(pack(userOp));\\n }\\n\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n}\\n\",\"keccak256\":\"0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c\",\"license\":\"GPL-3.0\"},\"contracts/samples/SimpleAccount.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable avoid-low-level-calls */\\n/* solhint-disable no-inline-assembly */\\n/* solhint-disable reason-string */\\n\\nimport \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport \\\"@openzeppelin/contracts/proxy/utils/Initializable.sol\\\";\\nimport \\\"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\\\";\\n\\nimport \\\"../core/BaseAccount.sol\\\";\\nimport \\\"./callback/TokenCallbackHandler.sol\\\";\\n\\n/**\\n * minimal account.\\n * this is sample minimal account.\\n * has execute, eth handling methods\\n * has a single signer that can send requests through the entryPoint.\\n */\\ncontract SimpleAccount is BaseAccount, TokenCallbackHandler, UUPSUpgradeable, Initializable {\\n using ECDSA for bytes32;\\n\\n address public owner;\\n\\n IEntryPoint private immutable _entryPoint;\\n\\n event SimpleAccountInitialized(IEntryPoint indexed entryPoint, address indexed owner);\\n\\n modifier onlyOwner() {\\n _onlyOwner();\\n _;\\n }\\n\\n /// @inheritdoc BaseAccount\\n function entryPoint() public view virtual override returns (IEntryPoint) {\\n return _entryPoint;\\n }\\n\\n\\n // solhint-disable-next-line no-empty-blocks\\n receive() external payable {}\\n\\n constructor(IEntryPoint anEntryPoint) {\\n _entryPoint = anEntryPoint;\\n _disableInitializers();\\n }\\n\\n function _onlyOwner() internal view {\\n //directly from EOA owner, or through the account itself (which gets redirected through execute())\\n require(msg.sender == owner || msg.sender == address(this), \\\"only owner\\\");\\n }\\n\\n /**\\n * execute a transaction (called directly from owner, or by entryPoint)\\n */\\n function execute(address dest, uint256 value, bytes calldata func) external {\\n _requireFromEntryPointOrOwner();\\n _call(dest, value, func);\\n }\\n\\n /**\\n * execute a sequence of transactions\\n */\\n function executeBatch(address[] calldata dest, bytes[] calldata func) external {\\n _requireFromEntryPointOrOwner();\\n require(dest.length == func.length, \\\"wrong array lengths\\\");\\n for (uint256 i = 0; i < dest.length; i++) {\\n _call(dest[i], 0, func[i]);\\n }\\n }\\n\\n /**\\n * @dev The _entryPoint member is immutable, to reduce gas consumption. To upgrade EntryPoint,\\n * a new implementation of SimpleAccount must be deployed with the new EntryPoint address, then upgrading\\n * the implementation by calling `upgradeTo()`\\n */\\n function initialize(address anOwner) public virtual initializer {\\n _initialize(anOwner);\\n }\\n\\n function _initialize(address anOwner) internal virtual {\\n owner = anOwner;\\n emit SimpleAccountInitialized(_entryPoint, owner);\\n }\\n\\n // Require the function call went through EntryPoint or owner\\n function _requireFromEntryPointOrOwner() internal view {\\n require(msg.sender == address(entryPoint()) || msg.sender == owner, \\\"account: not Owner or EntryPoint\\\");\\n }\\n\\n /// implement template method of BaseAccount\\n function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)\\n internal override virtual returns (uint256 validationData) {\\n bytes32 hash = userOpHash.toEthSignedMessageHash();\\n if (owner != hash.recover(userOp.signature))\\n return SIG_VALIDATION_FAILED;\\n return 0;\\n }\\n\\n function _call(address target, uint256 value, bytes memory data) internal {\\n (bool success, bytes memory result) = target.call{value : value}(data);\\n if (!success) {\\n assembly {\\n revert(add(result, 32), mload(result))\\n }\\n }\\n }\\n\\n /**\\n * check current account deposit in the entryPoint\\n */\\n function getDeposit() public view returns (uint256) {\\n return entryPoint().balanceOf(address(this));\\n }\\n\\n /**\\n * deposit more funds for this account in the entryPoint\\n */\\n function addDeposit() public payable {\\n entryPoint().depositTo{value : msg.value}(address(this));\\n }\\n\\n /**\\n * withdraw value from the account's deposit\\n * @param withdrawAddress target to send to\\n * @param amount to withdraw\\n */\\n function withdrawDepositTo(address payable withdrawAddress, uint256 amount) public onlyOwner {\\n entryPoint().withdrawTo(withdrawAddress, amount);\\n }\\n\\n function _authorizeUpgrade(address newImplementation) internal view override {\\n (newImplementation);\\n _onlyOwner();\\n }\\n}\\n\\n\",\"keccak256\":\"0x295bb73ecafb78a11e7418cc91d5f3c7f5fd5b2eba5e063d1e7d6bb6163192d4\",\"license\":\"GPL-3.0\"},\"contracts/samples/SimpleAccountFactory.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\nimport \\\"@openzeppelin/contracts/utils/Create2.sol\\\";\\nimport \\\"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\\\";\\n\\nimport \\\"./SimpleAccount.sol\\\";\\n\\n/**\\n * A sample factory contract for SimpleAccount\\n * A UserOperations \\\"initCode\\\" holds the address of the factory, and a method call (to createAccount, in this sample factory).\\n * The factory's createAccount returns the target account address even if it is already installed.\\n * This way, the entryPoint.getSenderAddress() can be called either before or after the account is created.\\n */\\ncontract SimpleAccountFactory {\\n SimpleAccount public immutable accountImplementation;\\n\\n constructor(IEntryPoint _entryPoint) {\\n accountImplementation = new SimpleAccount(_entryPoint);\\n }\\n\\n /**\\n * create an account, and return its address.\\n * returns the address even if the account is already deployed.\\n * Note that during UserOperation execution, this method is called only if the account is not deployed.\\n * This method returns an existing account address so that entryPoint.getSenderAddress() would work even after account creation\\n */\\n function createAccount(address owner,uint256 salt) public returns (SimpleAccount ret) {\\n address addr = getAddress(owner, salt);\\n uint codeSize = addr.code.length;\\n if (codeSize > 0) {\\n return SimpleAccount(payable(addr));\\n }\\n ret = SimpleAccount(payable(new ERC1967Proxy{salt : bytes32(salt)}(\\n address(accountImplementation),\\n abi.encodeCall(SimpleAccount.initialize, (owner))\\n )));\\n }\\n\\n /**\\n * calculate the counterfactual address of this account as it would be returned by createAccount()\\n */\\n function getAddress(address owner,uint256 salt) public view returns (address) {\\n return Create2.computeAddress(bytes32(salt), keccak256(abi.encodePacked(\\n type(ERC1967Proxy).creationCode,\\n abi.encode(\\n address(accountImplementation),\\n abi.encodeCall(SimpleAccount.initialize, (owner))\\n )\\n )));\\n }\\n}\\n\",\"keccak256\":\"0xf2cb4f3889e79edb11aab8d8451e379691813fc6b945ca0b5c3a08017c27b5ed\",\"license\":\"GPL-3.0\"},\"contracts/samples/callback/TokenCallbackHandler.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\npragma solidity ^0.8.12;\\n\\n/* solhint-disable no-empty-blocks */\\n\\nimport \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\\\";\\n\\n/**\\n * Token callback handler.\\n * Handles supported tokens' callbacks, allowing account receiving these tokens.\\n */\\ncontract TokenCallbackHandler is IERC777Recipient, IERC721Receiver, IERC1155Receiver {\\n function tokensReceived(\\n address,\\n address,\\n address,\\n uint256,\\n bytes calldata,\\n bytes calldata\\n ) external pure override {\\n }\\n\\n function onERC721Received(\\n address,\\n address,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC721Receiver.onERC721Received.selector;\\n }\\n\\n function onERC1155Received(\\n address,\\n address,\\n uint256,\\n uint256,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155Received.selector;\\n }\\n\\n function onERC1155BatchReceived(\\n address,\\n address,\\n uint256[] calldata,\\n uint256[] calldata,\\n bytes calldata\\n ) external pure override returns (bytes4) {\\n return IERC1155Receiver.onERC1155BatchReceived.selector;\\n }\\n\\n function supportsInterface(bytes4 interfaceId) external view virtual override returns (bool) {\\n return\\n interfaceId == type(IERC721Receiver).interfaceId ||\\n interfaceId == type(IERC1155Receiver).interfaceId ||\\n interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xfff3df5f5211d71158bb017ff791dc4fa85db53890f7bd72bac3a43d89e83752\",\"license\":\"GPL-3.0\"}},\"version\":1}",
+ "bytecode": "0x60a060405234801561001057600080fd5b5060405161336238038061336283398101604081905261002f91610088565b8060405161003c9061007b565b6001600160a01b039091168152602001604051809103906000f080158015610068573d6000803e3d6000fd5b506001600160a01b0316608052506100b8565b6125dc80610d8683390190565b60006020828403121561009a57600080fd5b81516001600160a01b03811681146100b157600080fd5b9392505050565b608051610ca66100e060003960008181604b0152818161011401526102580152610ca66000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806311464fbe146100465780635fbfb9cf146100965780638cb84e18146100a9575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61006d6100a436600461039d565b6100bc565b61006d6100b736600461039d565b6101ee565b6000806100c984846101ee565b905073ffffffffffffffffffffffffffffffffffffffff81163b80156100f1575090506101e8565b60405173ffffffffffffffffffffffffffffffffffffffff8616602482015284907f000000000000000000000000000000000000000000000000000000000000000090604401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc4d66de800000000000000000000000000000000000000000000000000000000179052516101b790610390565b6101c2929190610412565b8190604051809103906000f59050801580156101e2573d6000803e3d6000fd5b50925050505b92915050565b60006103578260001b6040518060200161020790610390565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604081905273ffffffffffffffffffffffffffffffffffffffff871660248201527f000000000000000000000000000000000000000000000000000000000000000090604401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc4d66de800000000000000000000000000000000000000000000000000000000179052905161030093929101610412565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261033c9291602001610480565b6040516020818303038152906040528051906020012061035e565b9392505050565b60006103578383306000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b6107c1806104b083390190565b600080604083850312156103b057600080fd5b823573ffffffffffffffffffffffffffffffffffffffff811681146103d457600080fd5b946020939093013593505050565b60005b838110156103fd5781810151838201526020016103e5565b8381111561040c576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000825180604084015261044d8160608501602087016103e2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b600083516104928184602088016103e2565b8351908301906104a68183602088016103e2565b0194935050505056fe60806040526040516107c13803806107c183398101604081905261002291610321565b61002e82826000610035565b505061043e565b61003e8361006b565b60008251118061004b5750805b156100665761006483836100ab60201b6100291760201c565b505b505050565b610074816100d7565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606100d0838360405180606001604052806027815260200161079a602791396101a9565b9392505050565b6100ea8161022260201b6100551760201c565b6101515760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084015b60405180910390fd5b806101887f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b61023160201b6100711760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b6060600080856001600160a01b0316856040516101c691906103ef565b600060405180830381855af49150503d8060008114610201576040519150601f19603f3d011682016040523d82523d6000602084013e610206565b606091505b50909250905061021886838387610234565b9695505050505050565b6001600160a01b03163b151590565b90565b606083156102a357825160000361029c576001600160a01b0385163b61029c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610148565b50816102ad565b6102ad83836102b5565b949350505050565b8151156102c55781518083602001fd5b8060405162461bcd60e51b8152600401610148919061040b565b634e487b7160e01b600052604160045260246000fd5b60005b838110156103105781810151838201526020016102f8565b838111156100645750506000910152565b6000806040838503121561033457600080fd5b82516001600160a01b038116811461034b57600080fd5b60208401519092506001600160401b038082111561036857600080fd5b818501915085601f83011261037c57600080fd5b81518181111561038e5761038e6102df565b604051601f8201601f19908116603f011681019083821181831017156103b6576103b66102df565b816040528281528860208487010111156103cf57600080fd5b6103e08360208301602088016102f5565b80955050505050509250929050565b600082516104018184602087016102f5565b9190910192915050565b602081526000825180602084015261042a8160408501602087016102f5565b601f01601f19169190910160400192915050565b61034d8061044d6000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610074565b6100b9565b565b606061004e83836040518060600160405280602781526020016102f1602791396100dd565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b90565b60006100b47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b3660008037600080366000845af43d6000803e8080156100d8573d6000f35b3d6000fd5b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516101079190610283565b600060405180830381855af49150503d8060008114610142576040519150601f19603f3d011682016040523d82523d6000602084013e610147565b606091505b509150915061015886838387610162565b9695505050505050565b606083156101fd5782516000036101f65773ffffffffffffffffffffffffffffffffffffffff85163b6101f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610207565b610207838361020f565b949350505050565b81511561021f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ed919061029f565b60005b8381101561026e578181015183820152602001610256565b8381111561027d576000848401525b50505050565b60008251610295818460208701610253565b9190910192915050565b60208152600082518060208401526102be816040850160208701610253565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212201cd78ab6a31213989661cff2d7d05fc9b9c38b1a848e8249e2e398659a9eb7e364736f6c634300080f0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122070aa03035a81441673770173c347020a4af1bf8f651ceebc066752c059bdbac764736f6c634300080f003360c0604052306080523480156200001557600080fd5b50604051620025dc380380620025dc833981016040819052620000389162000118565b6001600160a01b03811660a0526200004f62000056565b506200014a565b600054610100900460ff1615620000c35760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116101562000116576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6000602082840312156200012b57600080fd5b81516001600160a01b03811681146200014357600080fd5b9392505050565b60805160a05161241f620001bd6000396000818161032f015281816108810152818161092801528181610d4c01528181610f9d01528181610fe40152818161133601526115f501526000818161066b0152818161071b015281816109ec01528181610a9c0152610be5015261241f6000f3fe60806040526004361061012c5760003560e01c806352d1902d116100a5578063bc197c8111610074578063c4d66de811610059578063c4d66de8146103d0578063d087d288146103f0578063f23a6e611461040557600080fd5b8063bc197c8114610373578063c399ec88146103bb57600080fd5b806352d1902d146102b35780638da5cb5b146102c8578063b0d691fe14610320578063b61d27f61461035357600080fd5b80633659cfe6116100fc5780634a58db19116100e15780634a58db19146102785780634d44560d146102805780634f1ef286146102a057600080fd5b80633659cfe61461022a5780633a871cdd1461024a57600080fd5b806223de291461013857806301ffc9a71461015f578063150b7a021461019457806318dfb3c71461020a57600080fd5b3661013357005b600080fd5b34801561014457600080fd5b5061015d610153366004611cbf565b5050505050505050565b005b34801561016b57600080fd5b5061017f61017a366004611d70565b61044b565b60405190151581526020015b60405180910390f35b3480156101a057600080fd5b506101d96101af366004611db2565b7f150b7a020000000000000000000000000000000000000000000000000000000095945050505050565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161018b565b34801561021657600080fd5b5061015d610225366004611e6a565b610530565b34801561023657600080fd5b5061015d610245366004611ed6565b610654565b34801561025657600080fd5b5061026a610265366004611ef3565b610859565b60405190815260200161018b565b61015d61087f565b34801561028c57600080fd5b5061015d61029b366004611f47565b61091e565b61015d6102ae366004611fa2565b6109d5565b3480156102bf57600080fd5b5061026a610bcb565b3480156102d457600080fd5b506000546102fb9062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018b565b34801561032c57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006102fb565b34801561035f57600080fd5b5061015d61036e366004612084565b610cb7565b34801561037f57600080fd5b506101d961038e3660046120d4565b7fbc197c810000000000000000000000000000000000000000000000000000000098975050505050505050565b3480156103c757600080fd5b5061026a610d06565b3480156103dc57600080fd5b5061015d6103eb366004611ed6565b610dbd565b3480156103fc57600080fd5b5061026a610f50565b34801561041157600080fd5b506101d9610420366004612172565b7ff23a6e61000000000000000000000000000000000000000000000000000000009695505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f150b7a020000000000000000000000000000000000000000000000000000000014806104de57507fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e000000000000000000000000000000000000000000000000000000000145b8061052a57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b610538610fcc565b8281146105a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f77726f6e67206172726179206c656e677468730000000000000000000000000060448201526064015b60405180910390fd5b60005b8381101561064d5761063b8585838181106105c6576105c66121ee565b90506020020160208101906105db9190611ed6565b60008585858181106105ef576105ef6121ee565b9050602002810190610601919061221d565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061109592505050565b8061064581612282565b9150506105a9565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163003610719576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c0000000000000000000000000000000000000000606482015260840161059d565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661078e7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614610831576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f78790000000000000000000000000000000000000000606482015260840161059d565b61083a81611112565b604080516000808252602082019092526108569183919061111a565b50565b600061086361131e565b61086d84846113bd565b9050610878826114a3565b9392505050565b7f00000000000000000000000000000000000000000000000000000000000000006040517fb760faf900000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff919091169063b760faf99034906024016000604051808303818588803b15801561090a57600080fd5b505af115801561064d573d6000803e3d6000fd5b61092661150e565b7f00000000000000000000000000000000000000000000000000000000000000006040517f205c287800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015260248201849052919091169063205c287890604401600060405180830381600087803b1580156109b957600080fd5b505af11580156109cd573d6000803e3d6000fd5b505050505050565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163003610a9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c0000000000000000000000000000000000000000606482015260840161059d565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16610b0f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1614610bb2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f78790000000000000000000000000000000000000000606482015260840161059d565b610bbb82611112565b610bc78282600161111a565b5050565b60003073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610c92576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000606482015260840161059d565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b610cbf610fcc565b610d00848484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061109592505050565b50505050565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a08231906024015b602060405180830381865afa158015610d94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db891906122e1565b905090565b600054610100900460ff1615808015610ddd5750600054600160ff909116105b80610df75750303b158015610df7575060005460ff166001145b610e83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161059d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610ee157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b610eea8261159f565b8015610bc757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6040517f35567e1a0000000000000000000000000000000000000000000000000000000081523060048201526000602482018190529073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906335567e1a90604401610d77565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148061102d575060005462010000900473ffffffffffffffffffffffffffffffffffffffff1633145b611093576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f6163636f756e743a206e6f74204f776e6572206f7220456e747279506f696e74604482015260640161059d565b565b6000808473ffffffffffffffffffffffffffffffffffffffff1684846040516110be9190612326565b60006040518083038185875af1925050503d80600081146110fb576040519150601f19603f3d011682016040523d82523d6000602084013e611100565b606091505b50915091508161064d57805160208201fd5b61085661150e565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156111525761114d8361163e565b505050565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156111d7575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526111d4918101906122e1565b60015b611263576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f742055555053000000000000000000000000000000000000606482015260840161059d565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114611312576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c65555549440000000000000000000000000000000000000000000000606482015260840161059d565b5061114d838383611748565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611093576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6163636f756e743a206e6f742066726f6d20456e747279506f696e7400000000604482015260640161059d565b600080611417836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905061146761142a61014086018661221d565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250859392505061176d9050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff90811691161461149957600191505061052a565b5060009392505050565b80156108565760405160009033907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90849084818181858888f193505050503d806000811461064d576040519150601f19603f3d011682016040523d82523d6000602084013e61064d565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633148061153957503330145b611093576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6f6e6c79206f776e657200000000000000000000000000000000000000000000604482015260640161059d565b600080547fffffffffffffffffffff0000000000000000000000000000000000000000ffff166201000073ffffffffffffffffffffffffffffffffffffffff8481168202929092178084556040519190048216927f0000000000000000000000000000000000000000000000000000000000000000909216917f47e55c76e7a6f1fd8996a1da8008c1ea29699cca35e7bcd057f2dec313b6e5de91a350565b73ffffffffffffffffffffffffffffffffffffffff81163b6116e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161059d565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61175183611791565b60008251118061175e5750805b1561114d57610d0083836117de565b600080600061177c8585611803565b9150915061178981611848565b509392505050565b61179a8161163e565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b606061087883836040518060600160405280602781526020016123c3602791396119fb565b60008082516041036118395760208301516040840151606085015160001a61182d87828585611a80565b94509450505050611841565b506000905060025b9250929050565b600081600481111561185c5761185c612342565b036118645750565b600181600481111561187857611878612342565b036118df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161059d565b60028160048111156118f3576118f3612342565b0361195a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161059d565b600381600481111561196e5761196e612342565b03610856576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015260840161059d565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051611a259190612326565b600060405180830381855af49150503d8060008114611a60576040519150601f19603f3d011682016040523d82523d6000602084013e611a65565b606091505b5091509150611a7686838387611b6f565b9695505050505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611ab75750600090506003611b66565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611b0b573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116611b5f57600060019250925050611b66565b9150600090505b94509492505050565b60608315611c05578251600003611bfe5773ffffffffffffffffffffffffffffffffffffffff85163b611bfe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161059d565b5081611c0f565b611c0f8383611c17565b949350505050565b815115611c275781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161059d9190612371565b73ffffffffffffffffffffffffffffffffffffffff8116811461085657600080fd5b60008083601f840112611c8f57600080fd5b50813567ffffffffffffffff811115611ca757600080fd5b60208301915083602082850101111561184157600080fd5b60008060008060008060008060c0898b031215611cdb57600080fd5b8835611ce681611c5b565b97506020890135611cf681611c5b565b96506040890135611d0681611c5b565b955060608901359450608089013567ffffffffffffffff80821115611d2a57600080fd5b611d368c838d01611c7d565b909650945060a08b0135915080821115611d4f57600080fd5b50611d5c8b828c01611c7d565b999c989b5096995094979396929594505050565b600060208284031215611d8257600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461087857600080fd5b600080600080600060808688031215611dca57600080fd5b8535611dd581611c5b565b94506020860135611de581611c5b565b935060408601359250606086013567ffffffffffffffff811115611e0857600080fd5b611e1488828901611c7d565b969995985093965092949392505050565b60008083601f840112611e3757600080fd5b50813567ffffffffffffffff811115611e4f57600080fd5b6020830191508360208260051b850101111561184157600080fd5b60008060008060408587031215611e8057600080fd5b843567ffffffffffffffff80821115611e9857600080fd5b611ea488838901611e25565b90965094506020870135915080821115611ebd57600080fd5b50611eca87828801611e25565b95989497509550505050565b600060208284031215611ee857600080fd5b813561087881611c5b565b600080600060608486031215611f0857600080fd5b833567ffffffffffffffff811115611f1f57600080fd5b84016101608187031215611f3257600080fd5b95602085013595506040909401359392505050565b60008060408385031215611f5a57600080fd5b8235611f6581611c5b565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60008060408385031215611fb557600080fd5b8235611fc081611c5b565b9150602083013567ffffffffffffffff80821115611fdd57600080fd5b818501915085601f830112611ff157600080fd5b81358181111561200357612003611f73565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561204957612049611f73565b8160405282815288602084870101111561206257600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6000806000806060858703121561209a57600080fd5b84356120a581611c5b565b935060208501359250604085013567ffffffffffffffff8111156120c857600080fd5b611eca87828801611c7d565b60008060008060008060008060a0898b0312156120f057600080fd5b88356120fb81611c5b565b9750602089013561210b81611c5b565b9650604089013567ffffffffffffffff8082111561212857600080fd5b6121348c838d01611e25565b909850965060608b013591508082111561214d57600080fd5b6121598c838d01611e25565b909650945060808b0135915080821115611d4f57600080fd5b60008060008060008060a0878903121561218b57600080fd5b863561219681611c5b565b955060208701356121a681611c5b565b94506040870135935060608701359250608087013567ffffffffffffffff8111156121d057600080fd5b6121dc89828a01611c7d565b979a9699509497509295939492505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261225257600080fd5b83018035915067ffffffffffffffff82111561226d57600080fd5b60200191503681900382131561184157600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036122da577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b6000602082840312156122f357600080fd5b5051919050565b60005b838110156123155781810151838201526020016122fd565b83811115610d005750506000910152565b600082516123388184602087016122fa565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60208152600082518060208401526123908160408501602087016122fa565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e7edcd8c7b9333c2bbdd5f8fa69f1cd2cb0f5cbfa76648b9830bcf0cbfef288e64736f6c634300080f0033",
+ "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806311464fbe146100465780635fbfb9cf146100965780638cb84e18146100a9575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61006d6100a436600461039d565b6100bc565b61006d6100b736600461039d565b6101ee565b6000806100c984846101ee565b905073ffffffffffffffffffffffffffffffffffffffff81163b80156100f1575090506101e8565b60405173ffffffffffffffffffffffffffffffffffffffff8616602482015284907f000000000000000000000000000000000000000000000000000000000000000090604401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc4d66de800000000000000000000000000000000000000000000000000000000179052516101b790610390565b6101c2929190610412565b8190604051809103906000f59050801580156101e2573d6000803e3d6000fd5b50925050505b92915050565b60006103578260001b6040518060200161020790610390565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082820381018352601f90910116604081905273ffffffffffffffffffffffffffffffffffffffff871660248201527f000000000000000000000000000000000000000000000000000000000000000090604401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fc4d66de800000000000000000000000000000000000000000000000000000000179052905161030093929101610412565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261033c9291602001610480565b6040516020818303038152906040528051906020012061035e565b9392505050565b60006103578383306000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b6107c1806104b083390190565b600080604083850312156103b057600080fd5b823573ffffffffffffffffffffffffffffffffffffffff811681146103d457600080fd5b946020939093013593505050565b60005b838110156103fd5781810151838201526020016103e5565b8381111561040c576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000825180604084015261044d8160608501602087016103e2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b600083516104928184602088016103e2565b8351908301906104a68183602088016103e2565b0194935050505056fe60806040526040516107c13803806107c183398101604081905261002291610321565b61002e82826000610035565b505061043e565b61003e8361006b565b60008251118061004b5750805b156100665761006483836100ab60201b6100291760201c565b505b505050565b610074816100d7565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606100d0838360405180606001604052806027815260200161079a602791396101a9565b9392505050565b6100ea8161022260201b6100551760201c565b6101515760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084015b60405180910390fd5b806101887f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b61023160201b6100711760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b6060600080856001600160a01b0316856040516101c691906103ef565b600060405180830381855af49150503d8060008114610201576040519150601f19603f3d011682016040523d82523d6000602084013e610206565b606091505b50909250905061021886838387610234565b9695505050505050565b6001600160a01b03163b151590565b90565b606083156102a357825160000361029c576001600160a01b0385163b61029c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610148565b50816102ad565b6102ad83836102b5565b949350505050565b8151156102c55781518083602001fd5b8060405162461bcd60e51b8152600401610148919061040b565b634e487b7160e01b600052604160045260246000fd5b60005b838110156103105781810151838201526020016102f8565b838111156100645750506000910152565b6000806040838503121561033457600080fd5b82516001600160a01b038116811461034b57600080fd5b60208401519092506001600160401b038082111561036857600080fd5b818501915085601f83011261037c57600080fd5b81518181111561038e5761038e6102df565b604051601f8201601f19908116603f011681019083821181831017156103b6576103b66102df565b816040528281528860208487010111156103cf57600080fd5b6103e08360208301602088016102f5565b80955050505050509250929050565b600082516104018184602087016102f5565b9190910192915050565b602081526000825180602084015261042a8160408501602087016102f5565b601f01601f19169190910160400192915050565b61034d8061044d6000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610074565b6100b9565b565b606061004e83836040518060600160405280602781526020016102f1602791396100dd565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b90565b60006100b47f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b3660008037600080366000845af43d6000803e8080156100d8573d6000f35b3d6000fd5b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516101079190610283565b600060405180830381855af49150503d8060008114610142576040519150601f19603f3d011682016040523d82523d6000602084013e610147565b606091505b509150915061015886838387610162565b9695505050505050565b606083156101fd5782516000036101f65773ffffffffffffffffffffffffffffffffffffffff85163b6101f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610207565b610207838361020f565b949350505050565b81511561021f5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101ed919061029f565b60005b8381101561026e578181015183820152602001610256565b8381111561027d576000848401525b50505050565b60008251610295818460208701610253565b9190910192915050565b60208152600082518060208401526102be816040850160208701610253565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212201cd78ab6a31213989661cff2d7d05fc9b9c38b1a848e8249e2e398659a9eb7e364736f6c634300080f0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122070aa03035a81441673770173c347020a4af1bf8f651ceebc066752c059bdbac764736f6c634300080f0033",
+ "devdoc": {
+ "kind": "dev",
+ "methods": {},
+ "version": 1
+ },
+ "userdoc": {
+ "kind": "user",
+ "methods": {
+ "createAccount(address,uint256)": {
+ "notice": "create an account, and return its address. returns the address even if the account is already deployed. Note that during UserOperation execution, this method is called only if the account is not deployed. This method returns an existing account address so that entryPoint.getSenderAddress() would work even after account creation"
+ },
+ "getAddress(address,uint256)": {
+ "notice": "calculate the counterfactual address of this account as it would be returned by createAccount()"
+ }
+ },
+ "notice": "A sample factory contract for SimpleAccount A UserOperations \"initCode\" holds the address of the factory, and a method call (to createAccount, in this sample factory). The factory's createAccount returns the target account address even if it is already installed. This way, the entryPoint.getSenderAddress() can be called either before or after the account is created.",
+ "version": 1
+ },
+ "storageLayout": {
+ "storage": [],
+ "types": null
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/solcInputs/02113a2ed1850c3774563305ee607f11.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/solcInputs/02113a2ed1850c3774563305ee607f11.json
new file mode 100644
index 00000000..0df6e957
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/solcInputs/02113a2ed1850c3774563305ee607f11.json
@@ -0,0 +1,329 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@gnosis.pm/safe-contracts/contracts/base/Executor.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\n\n/// @title Executor - A contract that can execute transactions\n/// @author Richard Meissner - \ncontract Executor {\n function execute(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 txGas\n ) internal returns (bool success) {\n if (operation == Enum.Operation.DelegateCall) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n } else {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/base/FallbackManager.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract FallbackManager is SelfAuthorized {\n event ChangedFallbackHandler(address handler);\n\n // keccak256(\"fallback_manager.handler.address\")\n bytes32 internal constant FALLBACK_HANDLER_STORAGE_SLOT = 0x6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5;\n\n function internalSetFallbackHandler(address handler) internal {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, handler)\n }\n }\n\n /// @dev Allows to add a contract to handle fallback calls.\n /// Only fallback calls without value and with data will be forwarded.\n /// This can only be done via a Safe transaction.\n /// @param handler contract to handle fallbacks calls.\n function setFallbackHandler(address handler) public authorized {\n internalSetFallbackHandler(handler);\n emit ChangedFallbackHandler(handler);\n }\n\n // solhint-disable-next-line payable-fallback,no-complex-fallback\n fallback() external {\n bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let handler := sload(slot)\n if iszero(handler) {\n return(0, 0)\n }\n calldatacopy(0, 0, calldatasize())\n // The msg.sender address is shifted to the left by 12 bytes to remove the padding\n // Then the address without padding is stored right after the calldata\n mstore(calldatasize(), shl(96, caller()))\n // Add 20 bytes for the address appended add the end\n let success := call(gas(), handler, 0, 0, add(calldatasize(), 20), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if iszero(success) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/base/GuardManager.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\n\ninterface Guard {\n function checkTransaction(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures,\n address msgSender\n ) external;\n\n function checkAfterExecution(bytes32 txHash, bool success) external;\n}\n\n/// @title Fallback Manager - A contract that manages fallback calls made to this contract\n/// @author Richard Meissner - \ncontract GuardManager is SelfAuthorized {\n event ChangedGuard(address guard);\n // keccak256(\"guard_manager.guard.address\")\n bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8;\n\n /// @dev Set a guard that checks transactions before execution\n /// @param guard The address of the guard to be used or the 0 address to disable the guard\n function setGuard(address guard) external authorized {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n sstore(slot, guard)\n }\n emit ChangedGuard(guard);\n }\n\n function getGuard() internal view returns (address guard) {\n bytes32 slot = GUARD_STORAGE_SLOT;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n guard := sload(slot)\n }\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/base/ModuleManager.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/Enum.sol\";\nimport \"../common/SelfAuthorized.sol\";\nimport \"./Executor.sol\";\n\n/// @title Module Manager - A contract that manages modules that can execute transactions via this contract\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract ModuleManager is SelfAuthorized, Executor {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n address internal constant SENTINEL_MODULES = address(0x1);\n\n mapping(address => address) internal modules;\n\n function setupModules(address to, bytes memory data) internal {\n require(modules[SENTINEL_MODULES] == address(0), \"GS100\");\n modules[SENTINEL_MODULES] = SENTINEL_MODULES;\n if (to != address(0))\n // Setup has to complete successfully or transaction fails.\n require(execute(to, 0, data, Enum.Operation.DelegateCall, gasleft()), \"GS000\");\n }\n\n /// @dev Allows to add a module to the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Enables the module `module` for the Safe.\n /// @param module Module to be whitelisted.\n function enableModule(address module) public authorized {\n // Module address cannot be null or sentinel.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n // Module cannot be added twice.\n require(modules[module] == address(0), \"GS102\");\n modules[module] = modules[SENTINEL_MODULES];\n modules[SENTINEL_MODULES] = module;\n emit EnabledModule(module);\n }\n\n /// @dev Allows to remove a module from the whitelist.\n /// This can only be done via a Safe transaction.\n /// @notice Disables the module `module` for the Safe.\n /// @param prevModule Module that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) public authorized {\n // Validate module address and check that it corresponds to module index.\n require(module != address(0) && module != SENTINEL_MODULES, \"GS101\");\n require(modules[prevModule] == module, \"GS103\");\n modules[prevModule] = modules[module];\n modules[module] = address(0);\n emit DisabledModule(module);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public virtual returns (bool success) {\n // Only whitelisted modules are allowed.\n require(msg.sender != SENTINEL_MODULES && modules[msg.sender] != address(0), \"GS104\");\n // Execute transaction without further confirmations.\n success = execute(to, value, data, operation, gasleft());\n if (success) emit ExecutionFromModuleSuccess(msg.sender);\n else emit ExecutionFromModuleFailure(msg.sender);\n }\n\n /// @dev Allows a Module to execute a Safe transaction without any further confirmations and return data\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) public returns (bool success, bytes memory returnData) {\n success = execTransactionFromModule(to, value, data, operation);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // Load free memory location\n let ptr := mload(0x40)\n // We allocate memory for the return data by setting the free memory location to\n // current free memory location + data size + 32 bytes for data size value\n mstore(0x40, add(ptr, add(returndatasize(), 0x20)))\n // Store the size\n mstore(ptr, returndatasize())\n // Store the data\n returndatacopy(add(ptr, 0x20), 0, returndatasize())\n // Point the return data to the correct memory location\n returnData := ptr\n }\n }\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) public view returns (bool) {\n return SENTINEL_MODULES != module && modules[module] != address(0);\n }\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize) external view returns (address[] memory array, address next) {\n // Init array with max page size\n array = new address[](pageSize);\n\n // Populate return array\n uint256 moduleCount = 0;\n address currentModule = modules[start];\n while (currentModule != address(0x0) && currentModule != SENTINEL_MODULES && moduleCount < pageSize) {\n array[moduleCount] = currentModule;\n currentModule = modules[currentModule];\n moduleCount++;\n }\n next = currentModule;\n // Set correct size of returned array\n // solhint-disable-next-line no-inline-assembly\n assembly {\n mstore(array, moduleCount)\n }\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/base/OwnerManager.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"../common/SelfAuthorized.sol\";\n\n/// @title OwnerManager - Manages a set of owners and a threshold to perform actions.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract OwnerManager is SelfAuthorized {\n event AddedOwner(address owner);\n event RemovedOwner(address owner);\n event ChangedThreshold(uint256 threshold);\n\n address internal constant SENTINEL_OWNERS = address(0x1);\n\n mapping(address => address) internal owners;\n uint256 internal ownerCount;\n uint256 internal threshold;\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n function setupOwners(address[] memory _owners, uint256 _threshold) internal {\n // Threshold can only be 0 at initialization.\n // Check ensures that setup function can only be called once.\n require(threshold == 0, \"GS200\");\n // Validate that threshold is smaller than number of added owners.\n require(_threshold <= _owners.length, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n // Initializing Safe owners.\n address currentOwner = SENTINEL_OWNERS;\n for (uint256 i = 0; i < _owners.length; i++) {\n // Owner address cannot be null.\n address owner = _owners[i];\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this) && currentOwner != owner, \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[currentOwner] = owner;\n currentOwner = owner;\n }\n owners[currentOwner] = SENTINEL_OWNERS;\n ownerCount = _owners.length;\n threshold = _threshold;\n }\n\n /// @dev Allows to add a new owner to the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Adds the owner `owner` to the Safe and updates the threshold to `_threshold`.\n /// @param owner New owner address.\n /// @param _threshold New threshold.\n function addOwnerWithThreshold(address owner, uint256 _threshold) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(owner != address(0) && owner != SENTINEL_OWNERS && owner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[owner] == address(0), \"GS204\");\n owners[owner] = owners[SENTINEL_OWNERS];\n owners[SENTINEL_OWNERS] = owner;\n ownerCount++;\n emit AddedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to remove an owner from the Safe and update the threshold at the same time.\n /// This can only be done via a Safe transaction.\n /// @notice Removes the owner `owner` from the Safe and updates the threshold to `_threshold`.\n /// @param prevOwner Owner that pointed to the owner to be removed in the linked list\n /// @param owner Owner address to be removed.\n /// @param _threshold New threshold.\n function removeOwner(\n address prevOwner,\n address owner,\n uint256 _threshold\n ) public authorized {\n // Only allow to remove an owner, if threshold can still be reached.\n require(ownerCount - 1 >= _threshold, \"GS201\");\n // Validate owner address and check that it corresponds to owner index.\n require(owner != address(0) && owner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == owner, \"GS205\");\n owners[prevOwner] = owners[owner];\n owners[owner] = address(0);\n ownerCount--;\n emit RemovedOwner(owner);\n // Change threshold if threshold was changed.\n if (threshold != _threshold) changeThreshold(_threshold);\n }\n\n /// @dev Allows to swap/replace an owner from the Safe with another address.\n /// This can only be done via a Safe transaction.\n /// @notice Replaces the owner `oldOwner` in the Safe with `newOwner`.\n /// @param prevOwner Owner that pointed to the owner to be replaced in the linked list\n /// @param oldOwner Owner address to be replaced.\n /// @param newOwner New owner address.\n function swapOwner(\n address prevOwner,\n address oldOwner,\n address newOwner\n ) public authorized {\n // Owner address cannot be null, the sentinel or the Safe itself.\n require(newOwner != address(0) && newOwner != SENTINEL_OWNERS && newOwner != address(this), \"GS203\");\n // No duplicate owners allowed.\n require(owners[newOwner] == address(0), \"GS204\");\n // Validate oldOwner address and check that it corresponds to owner index.\n require(oldOwner != address(0) && oldOwner != SENTINEL_OWNERS, \"GS203\");\n require(owners[prevOwner] == oldOwner, \"GS205\");\n owners[newOwner] = owners[oldOwner];\n owners[prevOwner] = newOwner;\n owners[oldOwner] = address(0);\n emit RemovedOwner(oldOwner);\n emit AddedOwner(newOwner);\n }\n\n /// @dev Allows to update the number of required confirmations by Safe owners.\n /// This can only be done via a Safe transaction.\n /// @notice Changes the threshold of the Safe to `_threshold`.\n /// @param _threshold New threshold.\n function changeThreshold(uint256 _threshold) public authorized {\n // Validate that threshold is smaller than number of owners.\n require(_threshold <= ownerCount, \"GS201\");\n // There has to be at least one Safe owner.\n require(_threshold >= 1, \"GS202\");\n threshold = _threshold;\n emit ChangedThreshold(threshold);\n }\n\n function getThreshold() public view returns (uint256) {\n return threshold;\n }\n\n function isOwner(address owner) public view returns (bool) {\n return owner != SENTINEL_OWNERS && owners[owner] != address(0);\n }\n\n /// @dev Returns array of owners.\n /// @return Array of Safe owners.\n function getOwners() public view returns (address[] memory) {\n address[] memory array = new address[](ownerCount);\n\n // populate return array\n uint256 index = 0;\n address currentOwner = owners[SENTINEL_OWNERS];\n while (currentOwner != SENTINEL_OWNERS) {\n array[index] = currentOwner;\n currentOwner = owners[currentOwner];\n index++;\n }\n return array;\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/common/EtherPaymentFallback.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title EtherPaymentFallback - A contract that has a fallback to accept ether payments\n/// @author Richard Meissner - \ncontract EtherPaymentFallback {\n event SafeReceived(address indexed sender, uint256 value);\n\n /// @dev Fallback function accepts Ether transactions.\n receive() external payable {\n emit SafeReceived(msg.sender, msg.value);\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/common/SecuredTokenTransfer.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SecuredTokenTransfer - Secure token transfer\n/// @author Richard Meissner - \ncontract SecuredTokenTransfer {\n /// @dev Transfers a token and returns if it was a success\n /// @param token Token that should be transferred\n /// @param receiver Receiver to whom the token should be transferred\n /// @param amount The amount of tokens that should be transferred\n function transferToken(\n address token,\n address receiver,\n uint256 amount\n ) internal returns (bool transferred) {\n // 0xa9059cbb - keccack(\"transfer(address,uint256)\")\n bytes memory data = abi.encodeWithSelector(0xa9059cbb, receiver, amount);\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // We write the return value to scratch space.\n // See https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory\n let success := call(sub(gas(), 10000), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n switch returndatasize()\n case 0 {\n transferred := success\n }\n case 0x20 {\n transferred := iszero(or(iszero(success), iszero(mload(0))))\n }\n default {\n transferred := 0\n }\n }\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/common/SelfAuthorized.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SelfAuthorized - authorizes current contract to perform actions\n/// @author Richard Meissner - \ncontract SelfAuthorized {\n function requireSelfCall() private view {\n require(msg.sender == address(this), \"GS031\");\n }\n\n modifier authorized() {\n // This is a function call as it minimized the bytecode size\n requireSelfCall();\n _;\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/common/SignatureDecoder.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title SignatureDecoder - Decodes signatures that a encoded as bytes\n/// @author Richard Meissner - \ncontract SignatureDecoder {\n /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`.\n /// @notice Make sure to peform a bounds check for @param pos, to avoid out of bounds access on @param signatures\n /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access\n /// @param signatures concatenated rsv signatures\n function signatureSplit(bytes memory signatures, uint256 pos)\n internal\n pure\n returns (\n uint8 v,\n bytes32 r,\n bytes32 s\n )\n {\n // The signature format is a compact form of:\n // {bytes32 r}{bytes32 s}{uint8 v}\n // Compact means, uint8 is not padded to 32 bytes.\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let signaturePos := mul(0x41, pos)\n r := mload(add(signatures, add(signaturePos, 0x20)))\n s := mload(add(signatures, add(signaturePos, 0x40)))\n // Here we are loading the last 32 bytes, including 31 bytes\n // of 's'. There is no 'mload8' to do this.\n //\n // 'byte' is not working due to the Solidity parser, so lets\n // use the second best option, 'and'\n v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff)\n }\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/common/Singleton.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Singleton - Base for singleton contracts (should always be first super contract)\n/// This contract is tightly coupled to our proxy contract (see `proxies/GnosisSafeProxy.sol`)\n/// @author Richard Meissner - \ncontract Singleton {\n // singleton always needs to be first declared variable, to ensure that it is at the same location as in the Proxy contract.\n // It should also always be ensured that the address is stored alone (uses a full word)\n address private singleton;\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/common/StorageAccessible.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title StorageAccessible - generic base contract that allows callers to access all internal storage.\n/// @notice See https://github.com/gnosis/util-contracts/blob/bb5fe5fb5df6d8400998094fb1b32a178a47c3a1/contracts/StorageAccessible.sol\ncontract StorageAccessible {\n /**\n * @dev Reads `length` bytes of storage in the currents contract\n * @param offset - the offset in the current contract's storage in words to start reading from\n * @param length - the number of words (32 bytes) of data to read\n * @return the bytes that were read.\n */\n function getStorageAt(uint256 offset, uint256 length) public view returns (bytes memory) {\n bytes memory result = new bytes(length * 32);\n for (uint256 index = 0; index < length; index++) {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let word := sload(add(offset, index))\n mstore(add(add(result, 0x20), mul(index, 0x20)), word)\n }\n }\n return result;\n }\n\n /**\n * @dev Performs a delegetecall on a targetContract in the context of self.\n * Internally reverts execution to avoid side effects (making it static).\n *\n * This method reverts with data equal to `abi.encode(bool(success), bytes(response))`.\n * Specifically, the `returndata` after a call to this method will be:\n * `success:bool || response.length:uint256 || response:bytes`.\n *\n * @param targetContract Address of the contract containing the code to execute.\n * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).\n */\n function simulateAndRevert(address targetContract, bytes memory calldataPayload) external {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let success := delegatecall(gas(), targetContract, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0)\n\n mstore(0x00, success)\n mstore(0x20, returndatasize())\n returndatacopy(0x40, 0, returndatasize())\n revert(0, add(returndatasize(), 0x40))\n }\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/examples/libraries/GnosisSafeStorage.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title GnosisSafeStorage - Storage layout of the Safe contracts to be used in libraries\n/// @author Richard Meissner - \ncontract GnosisSafeStorage {\n // From /common/Singleton.sol\n address internal singleton;\n // From /common/ModuleManager.sol\n mapping(address => address) internal modules;\n // From /common/OwnerManager.sol\n mapping(address => address) internal owners;\n uint256 internal ownerCount;\n uint256 internal threshold;\n\n // From /GnosisSafe.sol\n bytes32 internal nonce;\n bytes32 internal domainSeparator;\n mapping(bytes32 => uint256) internal signedMessages;\n mapping(address => mapping(bytes32 => uint256)) internal approvedHashes;\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/external/GnosisSafeMath.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n * @title GnosisSafeMath\n * @dev Math operations with safety checks that revert on error\n * Renamed from SafeMath to GnosisSafeMath to avoid conflicts\n * TODO: remove once open zeppelin update to solc 0.5.0\n */\nlibrary GnosisSafeMath {\n /**\n * @dev Multiplies two numbers, reverts on overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n /**\n * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Adds two numbers, reverts on overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a);\n\n return c;\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./base/ModuleManager.sol\";\nimport \"./base/OwnerManager.sol\";\nimport \"./base/FallbackManager.sol\";\nimport \"./base/GuardManager.sol\";\nimport \"./common/EtherPaymentFallback.sol\";\nimport \"./common/Singleton.sol\";\nimport \"./common/SignatureDecoder.sol\";\nimport \"./common/SecuredTokenTransfer.sol\";\nimport \"./common/StorageAccessible.sol\";\nimport \"./interfaces/ISignatureValidator.sol\";\nimport \"./external/GnosisSafeMath.sol\";\n\n/// @title Gnosis Safe - A multisignature wallet with support for confirmations using signed messages based on ERC191.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafe is\n EtherPaymentFallback,\n Singleton,\n ModuleManager,\n OwnerManager,\n SignatureDecoder,\n SecuredTokenTransfer,\n ISignatureValidatorConstants,\n FallbackManager,\n StorageAccessible,\n GuardManager\n{\n using GnosisSafeMath for uint256;\n\n string public constant VERSION = \"1.3.0\";\n\n // keccak256(\n // \"EIP712Domain(uint256 chainId,address verifyingContract)\"\n // );\n bytes32 private constant DOMAIN_SEPARATOR_TYPEHASH = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218;\n\n // keccak256(\n // \"SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)\"\n // );\n bytes32 private constant SAFE_TX_TYPEHASH = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8;\n\n event SafeSetup(address indexed initiator, address[] owners, uint256 threshold, address initializer, address fallbackHandler);\n event ApproveHash(bytes32 indexed approvedHash, address indexed owner);\n event SignMsg(bytes32 indexed msgHash);\n event ExecutionFailure(bytes32 txHash, uint256 payment);\n event ExecutionSuccess(bytes32 txHash, uint256 payment);\n\n uint256 public nonce;\n bytes32 private _deprecatedDomainSeparator;\n // Mapping to keep track of all message hashes that have been approve by ALL REQUIRED owners\n mapping(bytes32 => uint256) public signedMessages;\n // Mapping to keep track of all hashes (message or transaction) that have been approve by ANY owners\n mapping(address => mapping(bytes32 => uint256)) public approvedHashes;\n\n // This constructor ensures that this contract can only be used as a master copy for Proxy contracts\n constructor() {\n // By setting the threshold it is not possible to call setup anymore,\n // so we create a Safe with 0 owners and threshold 1.\n // This is an unusable Safe, perfect for the singleton\n threshold = 1;\n }\n\n /// @dev Setup function sets initial storage of contract.\n /// @param _owners List of Safe owners.\n /// @param _threshold Number of required confirmations for a Safe transaction.\n /// @param to Contract address for optional delegate call.\n /// @param data Data payload for optional delegate call.\n /// @param fallbackHandler Handler for fallback calls to this contract\n /// @param paymentToken Token that should be used for the payment (0 is ETH)\n /// @param payment Value that should be paid\n /// @param paymentReceiver Adddress that should receive the payment (or 0 if tx.origin)\n function setup(\n address[] calldata _owners,\n uint256 _threshold,\n address to,\n bytes calldata data,\n address fallbackHandler,\n address paymentToken,\n uint256 payment,\n address payable paymentReceiver\n ) external {\n // setupOwners checks if the Threshold is already set, therefore preventing that this method is called twice\n setupOwners(_owners, _threshold);\n if (fallbackHandler != address(0)) internalSetFallbackHandler(fallbackHandler);\n // As setupOwners can only be called if the contract has not been initialized we don't need a check for setupModules\n setupModules(to, data);\n\n if (payment > 0) {\n // To avoid running into issues with EIP-170 we reuse the handlePayment function (to avoid adjusting code of that has been verified we do not adjust the method itself)\n // baseGas = 0, gasPrice = 1 and gas = payment => amount = (payment + 0) * 1 = payment\n handlePayment(payment, 0, 1, paymentToken, paymentReceiver);\n }\n emit SafeSetup(msg.sender, _owners, _threshold, to, fallbackHandler);\n }\n\n /// @dev Allows to execute a Safe transaction confirmed by required number of owners and then pays the account that submitted the transaction.\n /// Note: The fees are always transferred, even if the user transaction fails.\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @param safeTxGas Gas that should be used for the Safe transaction.\n /// @param baseGas Gas costs that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Gas price that should be used for the payment calculation.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param signatures Packed signature data ({bytes32 r}{bytes32 s}{uint8 v})\n function execTransaction(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver,\n bytes memory signatures\n ) public payable virtual returns (bool success) {\n bytes32 txHash;\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n bytes memory txHashData =\n encodeTransactionData(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n nonce\n );\n // Increase nonce and execute transaction.\n nonce++;\n txHash = keccak256(txHashData);\n checkSignatures(txHash, txHashData, signatures);\n }\n address guard = getGuard();\n {\n if (guard != address(0)) {\n Guard(guard).checkTransaction(\n // Transaction info\n to,\n value,\n data,\n operation,\n safeTxGas,\n // Payment info\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n // Signature info\n signatures,\n msg.sender\n );\n }\n }\n // We require some gas to emit the events (at least 2500) after the execution and some to perform code until the execution (500)\n // We also include the 1/64 in the check that is not send along with a call to counteract potential shortings because of EIP-150\n require(gasleft() >= ((safeTxGas * 64) / 63).max(safeTxGas + 2500) + 500, \"GS010\");\n // Use scope here to limit variable lifetime and prevent `stack too deep` errors\n {\n uint256 gasUsed = gasleft();\n // If the gasPrice is 0 we assume that nearly all available gas can be used (it is always more than safeTxGas)\n // We only substract 2500 (compared to the 3000 before) to ensure that the amount passed is still higher than safeTxGas\n success = execute(to, value, data, operation, gasPrice == 0 ? (gasleft() - 2500) : safeTxGas);\n gasUsed = gasUsed.sub(gasleft());\n // If no safeTxGas and no gasPrice was set (e.g. both are 0), then the internal tx is required to be successful\n // This makes it possible to use `estimateGas` without issues, as it searches for the minimum gas where the tx doesn't revert\n require(success || safeTxGas != 0 || gasPrice != 0, \"GS013\");\n // We transfer the calculated tx costs to the tx.origin to avoid sending it to intermediate contracts that have made calls\n uint256 payment = 0;\n if (gasPrice > 0) {\n payment = handlePayment(gasUsed, baseGas, gasPrice, gasToken, refundReceiver);\n }\n if (success) emit ExecutionSuccess(txHash, payment);\n else emit ExecutionFailure(txHash, payment);\n }\n {\n if (guard != address(0)) {\n Guard(guard).checkAfterExecution(txHash, success);\n }\n }\n }\n\n function handlePayment(\n uint256 gasUsed,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address payable refundReceiver\n ) private returns (uint256 payment) {\n // solhint-disable-next-line avoid-tx-origin\n address payable receiver = refundReceiver == address(0) ? payable(tx.origin) : refundReceiver;\n if (gasToken == address(0)) {\n // For ETH we will only adjust the gas price to not be higher than the actual used gas price\n payment = gasUsed.add(baseGas).mul(gasPrice < tx.gasprice ? gasPrice : tx.gasprice);\n require(receiver.send(payment), \"GS011\");\n } else {\n payment = gasUsed.add(baseGas).mul(gasPrice);\n require(transferToken(gasToken, receiver, payment), \"GS012\");\n }\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n */\n function checkSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures\n ) public view {\n // Load threshold to avoid multiple storage loads\n uint256 _threshold = threshold;\n // Check that a threshold is set\n require(_threshold > 0, \"GS001\");\n checkNSignatures(dataHash, data, signatures, _threshold);\n }\n\n /**\n * @dev Checks whether the signature provided is valid for the provided data, hash. Will revert otherwise.\n * @param dataHash Hash of the data (could be either a message hash or transaction hash)\n * @param data That should be signed (this is passed to an external validator contract)\n * @param signatures Signature data that should be verified. Can be ECDSA signature, contract signature (EIP-1271) or approved hash.\n * @param requiredSignatures Amount of required valid signatures.\n */\n function checkNSignatures(\n bytes32 dataHash,\n bytes memory data,\n bytes memory signatures,\n uint256 requiredSignatures\n ) public view {\n // Check that the provided signature data is not too short\n require(signatures.length >= requiredSignatures.mul(65), \"GS020\");\n // There cannot be an owner with address 0.\n address lastOwner = address(0);\n address currentOwner;\n uint8 v;\n bytes32 r;\n bytes32 s;\n uint256 i;\n for (i = 0; i < requiredSignatures; i++) {\n (v, r, s) = signatureSplit(signatures, i);\n if (v == 0) {\n // If v is 0 then it is a contract signature\n // When handling contract signatures the address of the contract is encoded into r\n currentOwner = address(uint160(uint256(r)));\n\n // Check that signature data pointer (s) is not pointing inside the static part of the signatures bytes\n // This check is not completely accurate, since it is possible that more signatures than the threshold are send.\n // Here we only check that the pointer is not pointing inside the part that is being processed\n require(uint256(s) >= requiredSignatures.mul(65), \"GS021\");\n\n // Check that signature data pointer (s) is in bounds (points to the length of data -> 32 bytes)\n require(uint256(s).add(32) <= signatures.length, \"GS022\");\n\n // Check if the contract signature is in bounds: start of data is s + 32 and end is start + signature length\n uint256 contractSignatureLen;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n contractSignatureLen := mload(add(add(signatures, s), 0x20))\n }\n require(uint256(s).add(32).add(contractSignatureLen) <= signatures.length, \"GS023\");\n\n // Check signature\n bytes memory contractSignature;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n // The signature data for contract signatures is appended to the concatenated signatures and the offset is stored in s\n contractSignature := add(add(signatures, s), 0x20)\n }\n require(ISignatureValidator(currentOwner).isValidSignature(data, contractSignature) == EIP1271_MAGIC_VALUE, \"GS024\");\n } else if (v == 1) {\n // If v is 1 then it is an approved hash\n // When handling approved hashes the address of the approver is encoded into r\n currentOwner = address(uint160(uint256(r)));\n // Hashes are automatically approved by the sender of the message or when they have been pre-approved via a separate transaction\n require(msg.sender == currentOwner || approvedHashes[currentOwner][dataHash] != 0, \"GS025\");\n } else if (v > 30) {\n // If v > 30 then default va (27,28) has been adjusted for eth_sign flow\n // To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before applying ecrecover\n currentOwner = ecrecover(keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", dataHash)), v - 4, r, s);\n } else {\n // Default is the ecrecover flow with the provided data hash\n // Use ecrecover with the messageHash for EOA signatures\n currentOwner = ecrecover(dataHash, v, r, s);\n }\n require(currentOwner > lastOwner && owners[currentOwner] != address(0) && currentOwner != SENTINEL_OWNERS, \"GS026\");\n lastOwner = currentOwner;\n }\n }\n\n /// @dev Allows to estimate a Safe transaction.\n /// This method is only meant for estimation purpose, therefore the call will always revert and encode the result in the revert data.\n /// Since the `estimateGas` function includes refunds, call this method to get an estimated of the costs that are deducted from the safe with `execTransaction`\n /// @param to Destination address of Safe transaction.\n /// @param value Ether value of Safe transaction.\n /// @param data Data payload of Safe transaction.\n /// @param operation Operation type of Safe transaction.\n /// @return Estimate without refunds and overhead fees (base transaction and payload data gas costs).\n /// @notice Deprecated in favor of common/StorageAccessible.sol and will be removed in next version.\n function requiredTxGas(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation\n ) external returns (uint256) {\n uint256 startGas = gasleft();\n // We don't provide an error message here, as we use it to return the estimate\n require(execute(to, value, data, operation, gasleft()));\n uint256 requiredGas = startGas - gasleft();\n // Convert response to string and return via error message\n revert(string(abi.encodePacked(requiredGas)));\n }\n\n /**\n * @dev Marks a hash as approved. This can be used to validate a hash that is used by a signature.\n * @param hashToApprove The hash that should be marked as approved for signatures that are verified by this contract.\n */\n function approveHash(bytes32 hashToApprove) external {\n require(owners[msg.sender] != address(0), \"GS030\");\n approvedHashes[msg.sender][hashToApprove] = 1;\n emit ApproveHash(hashToApprove, msg.sender);\n }\n\n /// @dev Returns the chain id used by this contract.\n function getChainId() public view returns (uint256) {\n uint256 id;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n id := chainid()\n }\n return id;\n }\n\n function domainSeparator() public view returns (bytes32) {\n return keccak256(abi.encode(DOMAIN_SEPARATOR_TYPEHASH, getChainId(), this));\n }\n\n /// @dev Returns the bytes that are hashed to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Gas that should be used for the safe transaction.\n /// @param baseGas Gas costs for that are independent of the transaction execution(e.g. base transaction fee, signature check, payment of the refund)\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash bytes.\n function encodeTransactionData(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes memory) {\n bytes32 safeTxHash =\n keccak256(\n abi.encode(\n SAFE_TX_TYPEHASH,\n to,\n value,\n keccak256(data),\n operation,\n safeTxGas,\n baseGas,\n gasPrice,\n gasToken,\n refundReceiver,\n _nonce\n )\n );\n return abi.encodePacked(bytes1(0x19), bytes1(0x01), domainSeparator(), safeTxHash);\n }\n\n /// @dev Returns hash to be signed by owners.\n /// @param to Destination address.\n /// @param value Ether value.\n /// @param data Data payload.\n /// @param operation Operation type.\n /// @param safeTxGas Fas that should be used for the safe transaction.\n /// @param baseGas Gas costs for data used to trigger the safe transaction.\n /// @param gasPrice Maximum gas price that should be used for this transaction.\n /// @param gasToken Token address (or 0 if ETH) that is used for the payment.\n /// @param refundReceiver Address of receiver of gas payment (or 0 if tx.origin).\n /// @param _nonce Transaction nonce.\n /// @return Transaction hash.\n function getTransactionHash(\n address to,\n uint256 value,\n bytes calldata data,\n Enum.Operation operation,\n uint256 safeTxGas,\n uint256 baseGas,\n uint256 gasPrice,\n address gasToken,\n address refundReceiver,\n uint256 _nonce\n ) public view returns (bytes32) {\n return keccak256(encodeTransactionData(to, value, data, operation, safeTxGas, baseGas, gasPrice, gasToken, refundReceiver, _nonce));\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/handler/DefaultCallbackHandler.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"../interfaces/ERC1155TokenReceiver.sol\";\nimport \"../interfaces/ERC721TokenReceiver.sol\";\nimport \"../interfaces/ERC777TokensRecipient.sol\";\nimport \"../interfaces/IERC165.sol\";\n\n/// @title Default Callback Handler - returns true for known token callbacks\n/// @author Richard Meissner - \ncontract DefaultCallbackHandler is ERC1155TokenReceiver, ERC777TokensRecipient, ERC721TokenReceiver, IERC165 {\n string public constant NAME = \"Default Callback Handler\";\n string public constant VERSION = \"1.0.0\";\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return 0xf23a6e61;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return 0xbc197c81;\n }\n\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return 0x150b7a02;\n }\n\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {\n // We implement this for completeness, doesn't really have any value\n }\n\n function supportsInterface(bytes4 interfaceId) external view virtual override returns (bool) {\n return\n interfaceId == type(ERC1155TokenReceiver).interfaceId ||\n interfaceId == type(ERC721TokenReceiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId;\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/interfaces/ERC1155TokenReceiver.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/**\n Note: The ERC-165 identifier for this interface is 0x4e2312e0.\n*/\ninterface ERC1155TokenReceiver {\n /**\n @notice Handle the receipt of a single ERC1155 token type.\n @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated. \n This function MUST return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` (i.e. 0xf23a6e61) if it accepts the transfer.\n This function MUST revert if it rejects the transfer.\n Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.\n @param _operator The address which initiated the transfer (i.e. msg.sender)\n @param _from The address which previously owned the token\n @param _id The ID of the token being transferred\n @param _value The amount of tokens being transferred\n @param _data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n */\n function onERC1155Received(\n address _operator,\n address _from,\n uint256 _id,\n uint256 _value,\n bytes calldata _data\n ) external returns (bytes4);\n\n /**\n @notice Handle the receipt of multiple ERC1155 token types.\n @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated. \n This function MUST return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` (i.e. 0xbc197c81) if it accepts the transfer(s).\n This function MUST revert if it rejects the transfer(s).\n Return of any other value than the prescribed keccak256 generated value MUST result in the transaction being reverted by the caller.\n @param _operator The address which initiated the batch transfer (i.e. msg.sender)\n @param _from The address which previously owned the token\n @param _ids An array containing ids of each token being transferred (order and length must match _values array)\n @param _values An array containing amounts of each token being transferred (order and length must match _ids array)\n @param _data Additional data with no specified format\n @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n */\n function onERC1155BatchReceived(\n address _operator,\n address _from,\n uint256[] calldata _ids,\n uint256[] calldata _values,\n bytes calldata _data\n ) external returns (bytes4);\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/interfaces/ERC721TokenReceiver.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02.\ninterface ERC721TokenReceiver {\n /// @notice Handle the receipt of an NFT\n /// @dev The ERC721 smart contract calls this function on the recipient\n /// after a `transfer`. This function MAY throw to revert and reject the\n /// transfer. Return of other than the magic value MUST result in the\n /// transaction being reverted.\n /// Note: the contract address is always the message sender.\n /// @param _operator The address which called `safeTransferFrom` function\n /// @param _from The address which previously owned the token\n /// @param _tokenId The NFT identifier which is being transferred\n /// @param _data Additional data with no specified format\n /// @return `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n /// unless throwing\n function onERC721Received(\n address _operator,\n address _from,\n uint256 _tokenId,\n bytes calldata _data\n ) external returns (bytes4);\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/interfaces/ERC777TokensRecipient.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\ninterface ERC777TokensRecipient {\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata data,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/interfaces/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @notice More details at https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/introspection/IERC165.sol\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/interfaces/ISignatureValidator.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\ncontract ISignatureValidatorConstants {\n // bytes4(keccak256(\"isValidSignature(bytes,bytes)\")\n bytes4 internal constant EIP1271_MAGIC_VALUE = 0x20c13b0b;\n}\n\nabstract contract ISignatureValidator is ISignatureValidatorConstants {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param _data Arbitrary length data signed on the behalf of address(this)\n * @param _signature Signature byte array associated with _data\n *\n * MUST return the bytes4 magic value 0x20c13b0b when function passes.\n * MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)\n * MUST allow external calls\n */\n function isValidSignature(bytes memory _data, bytes memory _signature) public view virtual returns (bytes4);\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxy.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title IProxy - Helper interface to access masterCopy of the Proxy on-chain\n/// @author Richard Meissner - \ninterface IProxy {\n function masterCopy() external view returns (address);\n}\n\n/// @title GnosisSafeProxy - Generic proxy contract allows to execute all transactions applying the code of a master contract.\n/// @author Stefan George - \n/// @author Richard Meissner - \ncontract GnosisSafeProxy {\n // singleton always needs to be first declared variable, to ensure that it is at the same location in the contracts to which calls are delegated.\n // To reduce deployment costs this variable is internal and needs to be retrieved via `getStorageAt`\n address internal singleton;\n\n /// @dev Constructor function sets address of singleton contract.\n /// @param _singleton Singleton address.\n constructor(address _singleton) {\n require(_singleton != address(0), \"Invalid singleton address provided\");\n singleton = _singleton;\n }\n\n /// @dev Fallback function forwards all transactions and returns all received return data.\n fallback() external payable {\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let _singleton := and(sload(0), 0xffffffffffffffffffffffffffffffffffffffff)\n // 0xa619486e == keccak(\"masterCopy()\"). The value is right padded to 32-bytes with 0s\n if eq(calldataload(0), 0xa619486e00000000000000000000000000000000000000000000000000000000) {\n mstore(0, _singleton)\n return(0, 0x20)\n }\n calldatacopy(0, 0, calldatasize())\n let success := delegatecall(gas(), _singleton, 0, calldatasize(), 0, 0)\n returndatacopy(0, 0, returndatasize())\n if eq(success, 0) {\n revert(0, returndatasize())\n }\n return(0, returndatasize())\n }\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"./GnosisSafeProxy.sol\";\nimport \"./IProxyCreationCallback.sol\";\n\n/// @title Proxy Factory - Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n/// @author Stefan George - \ncontract GnosisSafeProxyFactory {\n event ProxyCreation(GnosisSafeProxy proxy, address singleton);\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param singleton Address of singleton contract.\n /// @param data Payload for message call sent to new proxy contract.\n function createProxy(address singleton, bytes memory data) public returns (GnosisSafeProxy proxy) {\n proxy = new GnosisSafeProxy(singleton);\n if (data.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(data, 0x20), mload(data), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, singleton);\n }\n\n /// @dev Allows to retrieve the runtime code of a deployed Proxy. This can be used to check that the expected Proxy was deployed.\n function proxyRuntimeCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).runtimeCode;\n }\n\n /// @dev Allows to retrieve the creation code used for the Proxy deployment. With this it is easily possible to calculate predicted address.\n function proxyCreationCode() public pure returns (bytes memory) {\n return type(GnosisSafeProxy).creationCode;\n }\n\n /// @dev Allows to create new proxy contact using CREATE2 but it doesn't run the initializer.\n /// This method is only meant as an utility to be called from other methods\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function deployProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) internal returns (GnosisSafeProxy proxy) {\n // If the initializer changes the proxy address should change too. Hashing the initializer data is cheaper than just concatinating it\n bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce));\n bytes memory deploymentData = abi.encodePacked(type(GnosisSafeProxy).creationCode, uint256(uint160(_singleton)));\n // solhint-disable-next-line no-inline-assembly\n assembly {\n proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)\n }\n require(address(proxy) != address(0), \"Create2 call failed\");\n }\n\n /// @dev Allows to create new proxy contact and execute a message call to the new proxy within one transaction.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function createProxyWithNonce(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce\n ) public returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n if (initializer.length > 0)\n // solhint-disable-next-line no-inline-assembly\n assembly {\n if eq(call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0), 0) {\n revert(0, 0)\n }\n }\n emit ProxyCreation(proxy, _singleton);\n }\n\n /// @dev Allows to create new proxy contact, execute a message call to the new proxy and call a specified callback within one transaction\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n /// @param callback Callback that will be invoced after the new proxy contract has been successfully deployed and initialized.\n function createProxyWithCallback(\n address _singleton,\n bytes memory initializer,\n uint256 saltNonce,\n IProxyCreationCallback callback\n ) public returns (GnosisSafeProxy proxy) {\n uint256 saltNonceWithCallback = uint256(keccak256(abi.encodePacked(saltNonce, callback)));\n proxy = createProxyWithNonce(_singleton, initializer, saltNonceWithCallback);\n if (address(callback) != address(0)) callback.proxyCreated(proxy, _singleton, initializer, saltNonce);\n }\n\n /// @dev Allows to get the address for a new proxy contact created via `createProxyWithNonce`\n /// This method is only meant for address calculation purpose when you use an initializer that would revert,\n /// therefore the response is returned with a revert. When calling this method set `from` to the address of the proxy factory.\n /// @param _singleton Address of singleton contract.\n /// @param initializer Payload for message call sent to new proxy contract.\n /// @param saltNonce Nonce that will be used to generate the salt to calculate the address of the new proxy contract.\n function calculateCreateProxyWithNonceAddress(\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external returns (GnosisSafeProxy proxy) {\n proxy = deployProxyWithNonce(_singleton, initializer, saltNonce);\n revert(string(abi.encodePacked(proxy)));\n }\n}\n"
+ },
+ "@gnosis.pm/safe-contracts/contracts/proxies/IProxyCreationCallback.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\nimport \"./GnosisSafeProxy.sol\";\n\ninterface IProxyCreationCallback {\n function proxyCreated(\n GnosisSafeProxy proxy,\n address _singleton,\n bytes calldata initializer,\n uint256 saltNonce\n ) external;\n}\n"
+ },
+ "@openzeppelin/contracts/access/Ownable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n _checkOwner();\n _;\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n _transferOwnership(address(0));\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n"
+ },
+ "@openzeppelin/contracts/interfaces/draft-IERC1822.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n /**\n * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n * address.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy.\n */\n function proxiableUUID() external view returns (bytes32);\n}\n"
+ },
+ "@openzeppelin/contracts/interfaces/IERC1271.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC1271 standard signature validation method for\n * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].\n *\n * _Available since v4.1._\n */\ninterface IERC1271 {\n /**\n * @dev Should return whether the signature provided is valid for the provided data\n * @param hash Hash of the data to be signed\n * @param signature Signature byte array associated with _data\n */\n function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);\n}\n"
+ },
+ "@openzeppelin/contracts/proxy/beacon/IBeacon.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n /**\n * @dev Must return an address that can be used as a delegate call target.\n *\n * {BeaconProxy} will check that this address is a contract.\n */\n function implementation() external view returns (address);\n}\n"
+ },
+ "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Proxy.sol\";\nimport \"./ERC1967Upgrade.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy, ERC1967Upgrade {\n /**\n * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.\n *\n * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded\n * function call, and allows initializing the storage of the proxy like a Solidity constructor.\n */\n constructor(address _logic, bytes memory _data) payable {\n _upgradeToAndCall(_logic, _data, false);\n }\n\n /**\n * @dev Returns the current implementation address.\n */\n function _implementation() internal view virtual override returns (address impl) {\n return ERC1967Upgrade._getImplementation();\n }\n}\n"
+ },
+ "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../beacon/IBeacon.sol\";\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../../utils/Address.sol\";\nimport \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n *\n * _Available since v4.1._\n *\n * @custom:oz-upgrades-unsafe-allow delegatecall\n */\nabstract contract ERC1967Upgrade {\n // This is the keccak-256 hash of \"eip1967.proxy.rollback\" subtracted by 1\n bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;\n\n /**\n * @dev Storage slot with the address of the current implementation.\n * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n /**\n * @dev Emitted when the implementation is upgraded.\n */\n event Upgraded(address indexed implementation);\n\n /**\n * @dev Returns the current implementation address.\n */\n function _getImplementation() internal view returns (address) {\n return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 implementation slot.\n */\n function _setImplementation(address newImplementation) private {\n require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n }\n\n /**\n * @dev Perform implementation upgrade\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeTo(address newImplementation) internal {\n _setImplementation(newImplementation);\n emit Upgraded(newImplementation);\n }\n\n /**\n * @dev Perform implementation upgrade with additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCall(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n _upgradeTo(newImplementation);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(newImplementation, data);\n }\n }\n\n /**\n * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.\n *\n * Emits an {Upgraded} event.\n */\n function _upgradeToAndCallUUPS(\n address newImplementation,\n bytes memory data,\n bool forceCall\n ) internal {\n // Upgrades from old implementations will perform a rollback test. This test requires the new\n // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing\n // this special case will break upgrade paths from old UUPS implementation to new ones.\n if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {\n _setImplementation(newImplementation);\n } else {\n try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n require(slot == _IMPLEMENTATION_SLOT, \"ERC1967Upgrade: unsupported proxiableUUID\");\n } catch {\n revert(\"ERC1967Upgrade: new implementation is not UUPS\");\n }\n _upgradeToAndCall(newImplementation, data, forceCall);\n }\n }\n\n /**\n * @dev Storage slot with the admin of the contract.\n * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1, and is\n * validated in the constructor.\n */\n bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n /**\n * @dev Emitted when the admin account has changed.\n */\n event AdminChanged(address previousAdmin, address newAdmin);\n\n /**\n * @dev Returns the current admin.\n */\n function _getAdmin() internal view returns (address) {\n return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;\n }\n\n /**\n * @dev Stores a new address in the EIP1967 admin slot.\n */\n function _setAdmin(address newAdmin) private {\n require(newAdmin != address(0), \"ERC1967: new admin is the zero address\");\n StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;\n }\n\n /**\n * @dev Changes the admin of the proxy.\n *\n * Emits an {AdminChanged} event.\n */\n function _changeAdmin(address newAdmin) internal {\n emit AdminChanged(_getAdmin(), newAdmin);\n _setAdmin(newAdmin);\n }\n\n /**\n * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.\n */\n bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n /**\n * @dev Emitted when the beacon is upgraded.\n */\n event BeaconUpgraded(address indexed beacon);\n\n /**\n * @dev Returns the current beacon.\n */\n function _getBeacon() internal view returns (address) {\n return StorageSlot.getAddressSlot(_BEACON_SLOT).value;\n }\n\n /**\n * @dev Stores a new beacon in the EIP1967 beacon slot.\n */\n function _setBeacon(address newBeacon) private {\n require(Address.isContract(newBeacon), \"ERC1967: new beacon is not a contract\");\n require(\n Address.isContract(IBeacon(newBeacon).implementation()),\n \"ERC1967: beacon implementation is not a contract\"\n );\n StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;\n }\n\n /**\n * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does\n * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).\n *\n * Emits a {BeaconUpgraded} event.\n */\n function _upgradeBeaconToAndCall(\n address newBeacon,\n bytes memory data,\n bool forceCall\n ) internal {\n _setBeacon(newBeacon);\n emit BeaconUpgraded(newBeacon);\n if (data.length > 0 || forceCall) {\n Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/proxy/Proxy.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n /**\n * @dev Delegates the current call to `implementation`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _delegate(address implementation) internal virtual {\n assembly {\n // Copy msg.data. We take full control of memory in this inline assembly\n // block because it will not return to Solidity code. We overwrite the\n // Solidity scratch pad at memory position 0.\n calldatacopy(0, 0, calldatasize())\n\n // Call the implementation.\n // out and outsize are 0 because we don't know the size yet.\n let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n // Copy the returned data.\n returndatacopy(0, 0, returndatasize())\n\n switch result\n // delegatecall returns 0 on error.\n case 0 {\n revert(0, returndatasize())\n }\n default {\n return(0, returndatasize())\n }\n }\n }\n\n /**\n * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function\n * and {_fallback} should delegate.\n */\n function _implementation() internal view virtual returns (address);\n\n /**\n * @dev Delegates the current call to the address returned by `_implementation()`.\n *\n * This function does not return to its internal call site, it will return directly to the external caller.\n */\n function _fallback() internal virtual {\n _beforeFallback();\n _delegate(_implementation());\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n * function in the contract matches the call data.\n */\n fallback() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data\n * is empty.\n */\n receive() external payable virtual {\n _fallback();\n }\n\n /**\n * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`\n * call, or as part of the Solidity `fallback` or `receive` functions.\n *\n * If overridden should call `super._beforeFallback()`.\n */\n function _beforeFallback() internal virtual {}\n}\n"
+ },
+ "@openzeppelin/contracts/proxy/utils/Initializable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n * function initialize() initializer public {\n * __ERC20_init(\"MyToken\", \"MTK\");\n * }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n * function initializeV2() reinitializer(2) public {\n * __ERC20Permit_init(\"MyToken\");\n * }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n * _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n /**\n * @dev Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n * are added through upgrades and that require initialization.\n *\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n * cannot be nested. If one is invoked in the context of another, execution will revert.\n *\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n * a contract, executing them in the right order is up to the developer or operator.\n *\n * WARNING: setting the version to 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized < type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initialized`\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _initialized;\n }\n\n /**\n * @dev Internal function that returns the initialized version. Returns `_initializing`\n */\n function _isInitializing() internal view returns (bool) {\n return _initializing;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../interfaces/draft-IERC1822.sol\";\nimport \"../ERC1967/ERC1967Upgrade.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n *\n * _Available since v4.1._\n */\nabstract contract UUPSUpgradeable is IERC1822Proxiable, ERC1967Upgrade {\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment\n address private immutable __self = address(this);\n\n /**\n * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case\n * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n * fail.\n */\n modifier onlyProxy() {\n require(address(this) != __self, \"Function must be called through delegatecall\");\n require(_getImplementation() == __self, \"Function must be called through active proxy\");\n _;\n }\n\n /**\n * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n * callable on the implementing contract but not through proxies.\n */\n modifier notDelegated() {\n require(address(this) == __self, \"UUPSUpgradeable: must not be called through delegatecall\");\n _;\n }\n\n /**\n * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the\n * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n *\n * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n */\n function proxiableUUID() external view virtual override notDelegated returns (bytes32) {\n return _IMPLEMENTATION_SLOT;\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeTo(address newImplementation) external virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, new bytes(0), false);\n }\n\n /**\n * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n * encoded in `data`.\n *\n * Calls {_authorizeUpgrade}.\n *\n * Emits an {Upgraded} event.\n */\n function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy {\n _authorizeUpgrade(newImplementation);\n _upgradeToAndCallUUPS(newImplementation, data, true);\n }\n\n /**\n * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n * {upgradeTo} and {upgradeToAndCall}.\n *\n * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n *\n * ```solidity\n * function _authorizeUpgrade(address) internal override onlyOwner {}\n * ```\n */\n function _authorizeUpgrade(address newImplementation) internal virtual;\n}\n"
+ },
+ "@openzeppelin/contracts/security/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../../utils/introspection/IERC165.sol\";\n\n/**\n * @dev _Available since v3.1._\n */\ninterface IERC1155Receiver is IERC165 {\n /**\n * @dev Handles the receipt of a single ERC1155 token type. This function is\n * called at the end of a `safeTransferFrom` after the balance has been updated.\n *\n * NOTE: To accept the transfer, this must return\n * `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))`\n * (i.e. 0xf23a6e61, or its own function selector).\n *\n * @param operator The address which initiated the transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param id The ID of the token being transferred\n * @param value The amount of tokens being transferred\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155Received(address,address,uint256,uint256,bytes)\"))` if transfer is allowed\n */\n function onERC1155Received(\n address operator,\n address from,\n uint256 id,\n uint256 value,\n bytes calldata data\n ) external returns (bytes4);\n\n /**\n * @dev Handles the receipt of a multiple ERC1155 token types. This function\n * is called at the end of a `safeBatchTransferFrom` after the balances have\n * been updated.\n *\n * NOTE: To accept the transfer(s), this must return\n * `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))`\n * (i.e. 0xbc197c81, or its own function selector).\n *\n * @param operator The address which initiated the batch transfer (i.e. msg.sender)\n * @param from The address which previously owned the token\n * @param ids An array containing ids of each token being transferred (order and length must match values array)\n * @param values An array containing amounts of each token being transferred (order and length must match ids array)\n * @param data Additional data with no specified format\n * @return `bytes4(keccak256(\"onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)\"))` if transfer is allowed\n */\n function onERC1155BatchReceived(\n address operator,\n address from,\n uint256[] calldata ids,\n uint256[] calldata values,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts/token/ERC20/ERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\n * instead returning `false` on failure. This behavior is nonetheless\n * conventional and does not conflict with the expectations of ERC20\n * applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The default value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overridden;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on\n * `transferFrom`. This is semantically equivalent to an infinite approval.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * NOTE: Does not update the allowance if the current allowance\n * is the maximum `uint256`.\n *\n * Requirements:\n *\n * - `from` and `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `amount` of tokens from `from` to `to`.\n *\n * This internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(\n address owner,\n address spender,\n uint256 amount\n ) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(\n address from,\n address to,\n uint256 amount\n ) internal virtual {}\n}\n"
+ },
+ "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
+ },
+ "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n"
+ },
+ "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/draft-IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(\n IERC20 token,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(\n IERC20 token,\n address from,\n address to,\n uint256 value\n ) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(\n IERC20 token,\n address spender,\n uint256 value\n ) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) {\n // Return data is optional\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @title ERC721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC721 asset contracts.\n */\ninterface IERC721Receiver {\n /**\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n * by `operator` from `from`, this function is called.\n *\n * It must return its Solidity selector to confirm the token transfer.\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.\n *\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n */\n function onERC721Received(\n address operator,\n address from,\n uint256 tokenId,\n bytes calldata data\n ) external returns (bytes4);\n}\n"
+ },
+ "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.\n *\n * Accounts can be notified of {IERC777} tokens being sent to them by having a\n * contract implement this interface (contract holders can be their own\n * implementer) and registering it on the\n * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].\n *\n * See {IERC1820Registry} and {ERC1820Implementer}.\n */\ninterface IERC777Recipient {\n /**\n * @dev Called by an {IERC777} token contract whenever tokens are being\n * moved or created into a registered account (`to`). The type of operation\n * is conveyed by `from` being the zero address or not.\n *\n * This call occurs _after_ the token contract's state is updated, so\n * {IERC777-balanceOf}, etc., can be used to query the post-operation state.\n *\n * This function may revert to prevent the operation from being executed.\n */\n function tokensReceived(\n address operator,\n address from,\n address to,\n uint256 amount,\n bytes calldata userData,\n bytes calldata operatorData\n ) external;\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Address.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Context.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Create2.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Create2.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.\n * `CREATE2` can be used to compute in advance the address where a smart\n * contract will be deployed, which allows for interesting new mechanisms known\n * as 'counterfactual interactions'.\n *\n * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more\n * information.\n */\nlibrary Create2 {\n /**\n * @dev Deploys a contract using `CREATE2`. The address where the contract\n * will be deployed can be known in advance via {computeAddress}.\n *\n * The bytecode for a contract can be obtained from Solidity with\n * `type(contractName).creationCode`.\n *\n * Requirements:\n *\n * - `bytecode` must not be empty.\n * - `salt` must have not been used for `bytecode` already.\n * - the factory must have a balance of at least `amount`.\n * - if `amount` is non-zero, `bytecode` must have a `payable` constructor.\n */\n function deploy(\n uint256 amount,\n bytes32 salt,\n bytes memory bytecode\n ) internal returns (address addr) {\n require(address(this).balance >= amount, \"Create2: insufficient balance\");\n require(bytecode.length != 0, \"Create2: bytecode length is zero\");\n /// @solidity memory-safe-assembly\n assembly {\n addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)\n }\n require(addr != address(0), \"Create2: Failed on deploy\");\n }\n\n /**\n * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the\n * `bytecodeHash` or `salt` will result in a new destination address.\n */\n function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {\n return computeAddress(salt, bytecodeHash, address(this));\n }\n\n /**\n * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at\n * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.\n */\n function computeAddress(\n bytes32 salt,\n bytes32 bytecodeHash,\n address deployer\n ) internal pure returns (address addr) {\n /// @solidity memory-safe-assembly\n assembly {\n let ptr := mload(0x40) // Get free memory pointer\n\n // | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... |\n // |-------------------|---------------------------------------------------------------------------|\n // | bytecodeHash | CCCCCCCCCCCCC...CC |\n // | salt | BBBBBBBBBBBBB...BB |\n // | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA |\n // | 0xFF | FF |\n // |-------------------|---------------------------------------------------------------------------|\n // | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |\n // | keccak(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |\n\n mstore(add(ptr, 0x40), bytecodeHash)\n mstore(add(ptr, 0x20), salt)\n mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes\n let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff\n mstore8(start, 0xff)\n addr := keccak256(start, 85)\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/cryptography/ECDSA.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/cryptography/ECDSA.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../Strings.sol\";\n\n/**\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\n *\n * These functions can be used to verify that a message was signed by the holder\n * of the private keys of a given address.\n */\nlibrary ECDSA {\n enum RecoverError {\n NoError,\n InvalidSignature,\n InvalidSignatureLength,\n InvalidSignatureS,\n InvalidSignatureV // Deprecated in v4.8\n }\n\n function _throwError(RecoverError error) private pure {\n if (error == RecoverError.NoError) {\n return; // no error: do nothing\n } else if (error == RecoverError.InvalidSignature) {\n revert(\"ECDSA: invalid signature\");\n } else if (error == RecoverError.InvalidSignatureLength) {\n revert(\"ECDSA: invalid signature length\");\n } else if (error == RecoverError.InvalidSignatureS) {\n revert(\"ECDSA: invalid signature 's' value\");\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature` or error string. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n *\n * Documentation for signature generation:\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\n *\n * _Available since v4.3._\n */\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\n if (signature.length == 65) {\n bytes32 r;\n bytes32 s;\n uint8 v;\n // ecrecover takes the signature parameters, and the only way to get them\n // currently is to use assembly.\n /// @solidity memory-safe-assembly\n assembly {\n r := mload(add(signature, 0x20))\n s := mload(add(signature, 0x40))\n v := byte(0, mload(add(signature, 0x60)))\n }\n return tryRecover(hash, v, r, s);\n } else {\n return (address(0), RecoverError.InvalidSignatureLength);\n }\n }\n\n /**\n * @dev Returns the address that signed a hashed message (`hash`) with\n * `signature`. This address can then be used for verification purposes.\n *\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\n * this function rejects them by requiring the `s` value to be in the lower\n * half order, and the `v` value to be either 27 or 28.\n *\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\n * verification to be secure: it is possible to craft signatures that\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\n * this is by receiving a hash of the original message (which may otherwise\n * be too long), and then calling {toEthSignedMessageHash} on it.\n */\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, signature);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\n *\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address, RecoverError) {\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\n uint8 v = uint8((uint256(vs) >> 255) + 27);\n return tryRecover(hash, v, r, s);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\n *\n * _Available since v4.2._\n */\n function recover(\n bytes32 hash,\n bytes32 r,\n bytes32 vs\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\n * `r` and `s` signature fields separately.\n *\n * _Available since v4.3._\n */\n function tryRecover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address, RecoverError) {\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\n // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\n //\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\n // these malleable signatures as well.\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\n return (address(0), RecoverError.InvalidSignatureS);\n }\n\n // If the signature is valid (and not malleable), return the signer address\n address signer = ecrecover(hash, v, r, s);\n if (signer == address(0)) {\n return (address(0), RecoverError.InvalidSignature);\n }\n\n return (signer, RecoverError.NoError);\n }\n\n /**\n * @dev Overload of {ECDSA-recover} that receives the `v`,\n * `r` and `s` signature fields separately.\n */\n function recover(\n bytes32 hash,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal pure returns (address) {\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\n _throwError(error);\n return recovered;\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\n // 32 is the length in bytes of hash,\n // enforced by the type signature above\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash));\n }\n\n /**\n * @dev Returns an Ethereum Signed Message, created from `s`. This\n * produces hash corresponding to the one signed with the\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\n * JSON-RPC method as part of EIP-191.\n *\n * See {recover}.\n */\n function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19Ethereum Signed Message:\\n\", Strings.toString(s.length), s));\n }\n\n /**\n * @dev Returns an Ethereum Signed Typed Data, created from a\n * `domainSeparator` and a `structHash`. This produces hash corresponding\n * to the one signed with the\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\n * JSON-RPC method as part of EIP-712.\n *\n * See {recover}.\n */\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\n return keccak256(abi.encodePacked(\"\\x19\\x01\", domainSeparator, structHash));\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/introspection/IERC165.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
+ },
+ "@openzeppelin/contracts/utils/math/Math.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator\n ) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1);\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(\n uint256 x,\n uint256 y,\n uint256 denominator,\n Rounding rounding\n ) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10**64) {\n value /= 10**64;\n result += 64;\n }\n if (value >= 10**32) {\n value /= 10**32;\n result += 32;\n }\n if (value >= 10**16) {\n value /= 10**16;\n result += 16;\n }\n if (value >= 10**8) {\n value /= 10**8;\n result += 8;\n }\n if (value >= 10**4) {\n value /= 10**4;\n result += 4;\n }\n if (value >= 10**2) {\n value /= 10**2;\n result += 2;\n }\n if (value >= 10**1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/StorageSlot.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC1967 implementation slot:\n * ```\n * contract ERC1967 {\n * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n * function _getImplementation() internal view returns (address) {\n * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n * }\n *\n * function _setImplementation(address newImplementation) internal {\n * require(Address.isContract(newImplementation), \"ERC1967: new implementation is not a contract\");\n * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n * }\n * }\n * ```\n *\n * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._\n */\nlibrary StorageSlot {\n struct AddressSlot {\n address value;\n }\n\n struct BooleanSlot {\n bool value;\n }\n\n struct Bytes32Slot {\n bytes32 value;\n }\n\n struct Uint256Slot {\n uint256 value;\n }\n\n /**\n * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n */\n function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n}\n"
+ },
+ "@openzeppelin/contracts/utils/Strings.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n"
+ },
+ "contracts/core/BaseAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-empty-blocks */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Basic account implementation.\n * this contract provides the basic logic for implementing the IAccount interface - validateUserOp\n * specific account implementation should inherit it and provide the account-specific logic\n */\nabstract contract BaseAccount is IAccount {\n using UserOperationLib for UserOperation;\n\n //return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 constant internal SIG_VALIDATION_FAILED = 1;\n\n /**\n * Return the account nonce.\n * This method returns the next sequential nonce.\n * For a nonce of a specific key, use `entrypoint.getNonce(account, key)`\n */\n function getNonce() public view virtual returns (uint256) {\n return entryPoint().getNonce(address(this), 0);\n }\n\n /**\n * return the entryPoint used by this account.\n * subclass should return the current entryPoint used by this account.\n */\n function entryPoint() public view virtual returns (IEntryPoint);\n\n /**\n * Validate user's signature and nonce.\n * subclass doesn't need to override this method. Instead, it should override the specific internal validation methods.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external override virtual returns (uint256 validationData) {\n _requireFromEntryPoint();\n validationData = _validateSignature(userOp, userOpHash);\n _validateNonce(userOp.nonce);\n _payPrefund(missingAccountFunds);\n }\n\n /**\n * ensure the request comes from the known entrypoint.\n */\n function _requireFromEntryPoint() internal virtual view {\n require(msg.sender == address(entryPoint()), \"account: not from EntryPoint\");\n }\n\n /**\n * validate the signature is valid for this message.\n * @param userOp validate the userOp.signature field\n * @param userOpHash convenient field: the hash of the request, to check the signature against\n * (also hashes the entrypoint and chain id)\n * @return validationData signature and time-range of this operation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If the account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)\n internal virtual returns (uint256 validationData);\n\n /**\n * Validate the nonce of the UserOperation.\n * This method may validate the nonce requirement of this account.\n * e.g.\n * To limit the nonce to use sequenced UserOps only (no \"out of order\" UserOps):\n * `require(nonce < type(uint64).max)`\n * For a hypothetical account that *requires* the nonce to be out-of-order:\n * `require(nonce & type(uint64).max == 0)`\n *\n * The actual nonce uniqueness is managed by the EntryPoint, and thus no other\n * action is needed by the account itself.\n *\n * @param nonce to validate\n *\n * solhint-disable-next-line no-empty-blocks\n */\n function _validateNonce(uint256 nonce) internal view virtual {\n }\n\n /**\n * sends to the entrypoint (msg.sender) the missing funds for this transaction.\n * subclass MAY override this method for better funds management\n * (e.g. send to the entryPoint more than the minimum required, so that in future transactions\n * it will not be required to send again)\n * @param missingAccountFunds the minimum value this method should send the entrypoint.\n * this value MAY be zero, in case there is enough deposit, or the userOp has a paymaster.\n */\n function _payPrefund(uint256 missingAccountFunds) internal virtual {\n if (missingAccountFunds != 0) {\n (bool success,) = payable(msg.sender).call{value : missingAccountFunds, gas : type(uint256).max}(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n}\n"
+ },
+ "contracts/core/BasePaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n\n/* solhint-disable reason-string */\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"./Helpers.sol\";\n\n/**\n * Helper class for creating a paymaster.\n * provides helper methods for staking.\n * validates that the postOp is called only by the entryPoint\n */\nabstract contract BasePaymaster is IPaymaster, Ownable {\n\n IEntryPoint immutable public entryPoint;\n\n constructor(IEntryPoint _entryPoint) {\n entryPoint = _entryPoint;\n }\n\n /// @inheritdoc IPaymaster\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external override returns (bytes memory context, uint256 validationData) {\n _requireFromEntryPoint();\n return _validatePaymasterUserOp(userOp, userOpHash, maxCost);\n }\n\n function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n internal virtual returns (bytes memory context, uint256 validationData);\n\n /// @inheritdoc IPaymaster\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external override {\n _requireFromEntryPoint();\n _postOp(mode, context, actualGasCost);\n }\n\n /**\n * post-operation handler.\n * (verified to be called only through the entryPoint)\n * @dev if subclass returns a non-empty context from validatePaymasterUserOp, it must also implement this method.\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function _postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) internal virtual {\n\n (mode,context,actualGasCost); // unused params\n // subclass must override this method if validatePaymasterUserOp returns a context\n revert(\"must override\");\n }\n\n /**\n * add a deposit for this paymaster, used for paying for transaction fees\n */\n function deposit() public payable {\n entryPoint.depositTo{value : msg.value}(address(this));\n }\n\n /**\n * withdraw value from the deposit\n * @param withdrawAddress target to send to\n * @param amount to withdraw\n */\n function withdrawTo(address payable withdrawAddress, uint256 amount) public onlyOwner {\n entryPoint.withdrawTo(withdrawAddress, amount);\n }\n /**\n * add stake for this paymaster.\n * This method can also carry eth value to add to the current stake.\n * @param unstakeDelaySec - the unstake delay for this paymaster. Can only be increased.\n */\n function addStake(uint32 unstakeDelaySec) external payable onlyOwner {\n entryPoint.addStake{value : msg.value}(unstakeDelaySec);\n }\n\n /**\n * return current paymaster's deposit on the entryPoint.\n */\n function getDeposit() public view returns (uint256) {\n return entryPoint.balanceOf(address(this));\n }\n\n /**\n * unlock the stake, in order to withdraw it.\n * The paymaster can't serve requests once unlocked, until it calls addStake again\n */\n function unlockStake() external onlyOwner {\n entryPoint.unlockStake();\n }\n\n /**\n * withdraw the entire paymaster's stake.\n * stake must be unlocked first (and then wait for the unstakeDelay to be over)\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external onlyOwner {\n entryPoint.withdrawStake(withdrawAddress);\n }\n\n /// validate the call is made from a valid entrypoint\n function _requireFromEntryPoint() internal virtual {\n require(msg.sender == address(entryPoint), \"Sender not EntryPoint\");\n }\n}\n"
+ },
+ "contracts/core/EntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard {\n\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success,) = beneficiary.call{value : amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) public nonReentrant {\n\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(address(aggregator) != address(1), \"AA96 invalid aggregator\");\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {}\n catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {\n\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);\n }\n\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {\n return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(paymasterAndData.length >= 20, \"AA93 invalid paymasterAndData\");\n mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,\n sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));\n revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);\n }\n revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);\n\n }\n\n function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0) revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);\n if (sender1 == address(0)) revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender) revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0) revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0 : 20]));\n emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(UserOperation calldata userOp) internal view {\n // solhint-disable-next-line no-empty-blocks\n try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}\n catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0 : 20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)\n internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;\n }\n try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA23 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)\n internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(verificationGasLimit > gasUsedByValidateAccountPrepayment, \"AA41 too little verificationGas\");\n uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA33 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)\n private returns (uint256 validationData, uint256 paymasterValidationData) {\n\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |\n userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);\n (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}\n catch Error(string memory reason) {\n revert FailedOp(opIndex, string.concat(\"AA50 postOp reverted: \", reason));\n }\n catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {\n assembly {offset := data}\n }\n\n function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {\n assembly {data := offset}\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {mstore(0, number())}\n }\n}\n\n"
+ },
+ "contracts/core/Helpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\n struct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n }\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n// intersect account and paymaster ranges.\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(validationData);\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n }\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n }\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\n function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n }\n\n"
+ },
+ "contracts/core/NonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(address sender, uint192 key)\n public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(address sender, uint256 nonce) internal returns (bool) {\n\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n\n}\n"
+ },
+ "contracts/core/SenderCreator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(bytes calldata initCode) external returns (address sender) {\n address factory = address(bytes20(initCode[0 : 20]));\n bytes memory initCallData = initCode[20 :];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n"
+ },
+ "contracts/core/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(address account) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(unstakeDelaySec >= info.unstakeDelaySec, \"cannot decrease unstake time\");\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(info.withdrawTime <= block.timestamp, \"Stake withdrawal is not due\");\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success,) = withdrawAddress.call{value : stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success,) = withdrawAddress.call{value : withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n"
+ },
+ "contracts/interfaces/IAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external returns (uint256 validationData);\n}\n"
+ },
+ "contracts/interfaces/IAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\n}\n"
+ },
+ "contracts/interfaces/IEntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo);\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n\n"
+ },
+ "contracts/interfaces/INonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(address sender, uint192 key)\n external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n"
+ },
+ "contracts/interfaces/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;\n}\n"
+ },
+ "contracts/interfaces/IStakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n\n event Deposited(\n address indexed account,\n uint256 totalDeposit\n );\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(\n address indexed account,\n uint256 withdrawTime\n );\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
+ },
+ "contracts/interfaces/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n }\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {data := calldataload(userOp)}\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return abi.encode(\n sender, nonce,\n hashInitCode, hashCallData,\n callGasLimit, verificationGasLimit, preVerificationGas,\n maxFeePerGas, maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/samples/bls/BLSAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../SimpleAccount.sol\";\nimport \"./IBLSAccount.sol\";\n\n/**\n * Minimal BLS-based account that uses an aggregated signature.\n * The account must maintain its own BLS public key, and expose its trusted signature aggregator.\n * Note that unlike the \"standard\" SimpleAccount, this account can't be called directly\n * (normal SimpleAccount uses its \"signer\" address as both the ecrecover signer, and as a legitimate\n * Ethereum sender address. Obviously, a BLS public key is not a valid Ethereum sender address.)\n */\ncontract BLSAccount is SimpleAccount, IBLSAccount {\n address public immutable aggregator;\n uint256[4] private publicKey;\n\n // The constructor is used only for the \"implementation\" and only sets immutable values.\n // Mutable value slots for proxy accounts are set by the 'initialize' function.\n constructor(IEntryPoint anEntryPoint, address anAggregator) SimpleAccount(anEntryPoint) {\n aggregator = anAggregator;\n }\n\n /**\n * The initializer for the BLSAccount instance.\n * @param aPublicKey public key from a BLS keypair that will have a full ownership and control of this account.\n */\n function initialize(uint256[4] memory aPublicKey) public virtual initializer {\n super._initialize(address(0));\n _setBlsPublicKey(aPublicKey);\n }\n\n function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)\n internal override view returns (uint256 validationData) {\n\n (userOp, userOpHash);\n if (userOp.initCode.length != 0) {\n // BLSSignatureAggregator.getUserOpPublicKey() assumes that during account creation, the public key is\n // the suffix of the initCode.\n // The account MUST validate it\n bytes32 pubKeyHash = keccak256(abi.encode(getBlsPublicKey()));\n require(keccak256(userOp.initCode[userOp.initCode.length - 128 :]) == pubKeyHash, \"wrong pubkey\");\n }\n return _packValidationData(ValidationData(aggregator, 0,0));\n }\n\n /**\n * Allows the owner to set or change the BLS key.\n * @param newPublicKey public key from a BLS keypair that will have a full ownership and control of this account.\n */\n function setBlsPublicKey(uint256[4] memory newPublicKey) public onlyOwner {\n _setBlsPublicKey(newPublicKey);\n }\n\n function _setBlsPublicKey(uint256[4] memory newPublicKey) internal {\n emit PublicKeyChanged(publicKey, newPublicKey);\n publicKey = newPublicKey;\n }\n\n /// @inheritdoc IBLSAccount\n function getBlsPublicKey() public override view returns (uint256[4] memory) {\n return publicKey;\n }\n}\n"
+ },
+ "contracts/samples/bls/BLSAccountFactory.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/utils/Create2.sol\";\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\nimport \"../../interfaces/IEntryPoint.sol\";\nimport \"./BLSAccount.sol\";\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * Based on SimpleAccountFactory.\n * Cannot be a subclass since both constructor and createAccount depend on the\n * constructor and initializer of the actual account contract.\n */\ncontract BLSAccountFactory {\n BLSAccount public immutable accountImplementation;\n\n constructor(IEntryPoint entryPoint, address aggregator){\n accountImplementation = new BLSAccount(entryPoint, aggregator);\n }\n\n /**\n * create an account, and return its address.\n * returns the address even if the account is already deployed.\n * Note that during UserOperation execution, this method is called only if the account is not deployed.\n * This method returns an existing account address so that entryPoint.getSenderAddress() would work even after account creation\n * Also note that our BLSSignatureAggregator requires that the public key is the last parameter\n */\n function createAccount(uint256 salt, uint256[4] calldata aPublicKey) public returns (BLSAccount) {\n\n // the BLSSignatureAggregator depends on the public-key being the last 4 uint256 of msg.data.\n uint slot;\n assembly {slot := aPublicKey}\n require(slot == msg.data.length - 128, \"wrong pubkey offset\");\n\n address addr = getAddress(salt, aPublicKey);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return BLSAccount(payable(addr));\n }\n return BLSAccount(payable(new ERC1967Proxy{salt : bytes32(salt)}(\n address(accountImplementation),\n abi.encodeCall(BLSAccount.initialize, aPublicKey)\n )));\n }\n\n /**\n * calculate the counterfactual address of this account as it would be returned by createAccount()\n */\n function getAddress(uint256 salt, uint256[4] memory aPublicKey) public view returns (address) {\n return Create2.computeAddress(bytes32(salt), keccak256(abi.encodePacked(\n type(ERC1967Proxy).creationCode,\n abi.encode(\n address(accountImplementation),\n abi.encodeCall(BLSAccount.initialize, (aPublicKey))\n )\n )));\n }\n}\n"
+ },
+ "contracts/samples/bls/BLSHelper.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n// code taken from : https://github.com/witnet/elliptic-curve-solidity/blob/master/contracts/EllipticCurve.sol\n// missing core functions from \"thehubbleproject/bls\": jacAdd (and sum)\nlibrary BLSHelper {\n\n struct XY {\n uint x;\n uint y;\n }\n /**\n * sum all the points in the array\n * NOTE: the \"ecAdd\" (below) has a special case where x1==y2.\n * @param points an array of bytes32[2], representing an (x,y) of a point\n * @param _pp the modulus of the curve\n * @return ret the sum of all points\n */\n function sum(XY[] memory points, uint256 _pp) internal pure returns (XY memory ret){\n uint x = points[0].x;\n uint y = points[0].y;\n uint z = 1;\n\n for (uint i = 1; i < points.length; i++) {\n (x, y, z) = jacAdd(x, y, z, points[i].x, points[i].y, 1, _pp);\n }\n (x, y) = toAffine(x, y, z, _pp);\n ret.x = x;\n ret.y = y;\n }\n\n /// @dev Adds two points (x1, y1, z1) and (x2, y2, z2).\n /// @param _x1 coordinate x of P1\n /// @param _y1 coordinate y of P1\n /// @param _z1 coordinate z of P1\n /// @param _x2 coordinate x of square\n /// @param _y2 coordinate y of square\n /// @param _z2 coordinate z of square\n /// @param _pp the modulus\n /// @return (qx, qy, qz) P1+square in Jacobian\n function jacAdd(\n uint256 _x1,\n uint256 _y1,\n uint256 _z1,\n uint256 _x2,\n uint256 _y2,\n uint256 _z2,\n uint256 _pp)\n internal pure returns (uint256, uint256, uint256)\n {\n if (_x1 == 0 && _y1 == 0)\n return (_x2, _y2, _z2);\n if (_x2 == 0 && _y2 == 0)\n return (_x1, _y1, _z1);\n\n // We follow the equations described in https://pdfs.semanticscholar.org/5c64/29952e08025a9649c2b0ba32518e9a7fb5c2.pdf Section 5\n uint[4] memory zs;\n // z1^2, z1^3, z2^2, z2^3\n zs[0] = mulmod(_z1, _z1, _pp);\n zs[1] = mulmod(_z1, zs[0], _pp);\n zs[2] = mulmod(_z2, _z2, _pp);\n zs[3] = mulmod(_z2, zs[2], _pp);\n\n // u1, s1, u2, s2\n zs = [\n mulmod(_x1, zs[2], _pp),\n mulmod(_y1, zs[3], _pp),\n mulmod(_x2, zs[0], _pp),\n mulmod(_y2, zs[1], _pp)\n ];\n\n // In case of zs[0] == zs[2] && zs[1] == zs[3], double function should be used\n require(zs[0] != zs[2] || zs[1] != zs[3], \"Use jacDouble function instead\");\n\n uint[4] memory hr;\n //h\n hr[0] = addmod(zs[2], _pp - zs[0], _pp);\n //r\n hr[1] = addmod(zs[3], _pp - zs[1], _pp);\n //h^2\n hr[2] = mulmod(hr[0], hr[0], _pp);\n // h^3\n hr[3] = mulmod(hr[2], hr[0], _pp);\n // qx = -h^3 -2u1h^2+r^2\n uint256 qx = addmod(mulmod(hr[1], hr[1], _pp), _pp - hr[3], _pp);\n qx = addmod(qx, _pp - mulmod(2, mulmod(zs[0], hr[2], _pp), _pp), _pp);\n // qy = -s1*z1*h^3+r(u1*h^2 -x^3)\n uint256 qy = mulmod(hr[1], addmod(mulmod(zs[0], hr[2], _pp), _pp - qx, _pp), _pp);\n qy = addmod(qy, _pp - mulmod(zs[1], hr[3], _pp), _pp);\n // qz = h*z1*z2\n uint256 qz = mulmod(hr[0], mulmod(_z1, _z2, _pp), _pp);\n return (qx, qy, qz);\n }\n\n\n /// @dev Converts a point (x, y, z) expressed in Jacobian coordinates to affine coordinates (x', y', 1).\n /// @param _x coordinate x\n /// @param _y coordinate y\n /// @param _z coordinate z\n /// @param _pp the modulus\n /// @return (x', y') affine coordinates\n function toAffine(\n uint256 _x,\n uint256 _y,\n uint256 _z,\n uint256 _pp)\n internal pure returns (uint256, uint256)\n {\n uint256 zInv = invMod(_z, _pp);\n uint256 zInv2 = mulmod(zInv, zInv, _pp);\n uint256 x2 = mulmod(_x, zInv2, _pp);\n uint256 y2 = mulmod(_y, mulmod(zInv, zInv2, _pp), _pp);\n\n return (x2, y2);\n }\n\n\n /// @dev Modular euclidean inverse of a number (mod p).\n /// @param _x The number\n /// @param _pp The modulus\n /// @return q such that x*q = 1 (mod _pp)\n function invMod(uint256 _x, uint256 _pp) internal pure returns (uint256) {\n require(_x != 0 && _x != _pp && _pp != 0, \"Invalid number\");\n uint256 q = 0;\n uint256 newT = 1;\n uint256 r = _pp;\n uint256 t;\n while (_x != 0) {\n t = r / _x;\n (q, newT) = (newT, addmod(q, (_pp - mulmod(t, newT, _pp)), _pp));\n (r, _x) = (_x, r - t * _x);\n }\n\n return q;\n }\n\n /// @dev Doubles a point (x, y, z).\n /// @param _x coordinate x of P1\n /// @param _y coordinate y of P1\n /// @param _z coordinate z of P1\n /// @param _aa the a scalar in the curve equation\n /// @param _pp the modulus\n /// @return (qx, qy, qz) 2P in Jacobian\n function jacDouble(\n uint256 _x,\n uint256 _y,\n uint256 _z,\n uint256 _aa,\n uint256 _pp)\n internal pure returns (uint256, uint256, uint256)\n {\n if (_z == 0)\n return (_x, _y, _z);\n\n // We follow the equations described in https://pdfs.semanticscholar.org/5c64/29952e08025a9649c2b0ba32518e9a7fb5c2.pdf Section 5\n // Note: there is a bug in the paper regarding the m parameter, M=3*(x1^2)+a*(z1^4)\n // x, y, z at this point represent the squares of _x, _y, _z\n uint256 x = mulmod(_x, _x, _pp); //x1^2\n uint256 y = mulmod(_y, _y, _pp); //y1^2\n uint256 z = mulmod(_z, _z, _pp); //z1^2\n\n // s\n uint s = mulmod(4, mulmod(_x, y, _pp), _pp);\n // m\n uint m = addmod(mulmod(3, x, _pp), mulmod(_aa, mulmod(z, z, _pp), _pp), _pp);\n\n // x, y, z at this point will be reassigned and rather represent qx, qy, qz from the paper\n // This allows to reduce the gas cost and stack footprint of the algorithm\n // qx\n x = addmod(mulmod(m, m, _pp), _pp - addmod(s, s, _pp), _pp);\n // qy = -8*y1^4 + M(S-T)\n y = addmod(mulmod(m, addmod(s, _pp - x, _pp), _pp), _pp - mulmod(8, mulmod(y, y, _pp), _pp), _pp);\n // qz = 2*y1*z1\n z = mulmod(2, mulmod(_y, _z, _pp), _pp);\n\n return (x, y, z);\n }\n\n /// @dev Add two points (x1, y1) and (x2, y2) in affine coordinates.\n /// @param _x1 coordinate x of P1\n /// @param _y1 coordinate y of P1\n /// @param _x2 coordinate x of P2\n /// @param _y2 coordinate y of P2\n /// @param _aa constant of the curve\n /// @param _pp the modulus\n /// @return (qx, qy) = P1+P2 in affine coordinates\n function ecAdd(\n uint256 _x1,\n uint256 _y1,\n uint256 _x2,\n uint256 _y2,\n uint256 _aa,\n uint256 _pp)\n internal pure returns (uint256, uint256)\n {\n uint x = 0;\n uint y = 0;\n uint z = 0;\n\n // Double if x1==x2 else add\n if (_x1 == _x2) {\n // y1 = -y2 mod p\n if (addmod(_y1, _y2, _pp) == 0) {\n return (0, 0);\n } else {\n // P1 = P2\n (x, y, z) = jacDouble(\n _x1,\n _y1,\n 1,\n _aa,\n _pp);\n }\n } else {\n (x, y, z) = jacAdd(\n _x1,\n _y1,\n 1,\n _x2,\n _y2,\n 1,\n _pp);\n }\n // Get back to affine\n return toAffine(\n x,\n y,\n z,\n _pp);\n }\n\n}\n"
+ },
+ "contracts/samples/bls/BLSSignatureAggregator.sol": {
+ "content": "//SPDX-License-Identifier: Unlicense\npragma solidity >=0.8.4 <0.9.0;\npragma abicoder v2;\n\nimport \"../../interfaces/IAggregator.sol\";\nimport \"../../interfaces/IEntryPoint.sol\";\nimport {BLSOpen} from \"./lib/BLSOpen.sol\";\nimport \"./IBLSAccount.sol\";\nimport \"./BLSHelper.sol\";\n\n/**\n * A BLS-based signature aggregator, to validate aggregated signature of multiple UserOps if BLSAccount\n */\ncontract BLSSignatureAggregator is IAggregator {\n using UserOperationLib for UserOperation;\n\n bytes32 public constant BLS_DOMAIN = keccak256(\"eip4337.bls.domain\");\n\n //copied from BLS.sol\n uint256 public constant N = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n /**\n * @return publicKey - the public key from a BLS keypair the Aggregator will use to verify this UserOp;\n * normally public key will be queried from the deployed BLSAccount itself;\n * the public key will be read from the 'initCode' if the account is not deployed yet;\n */\n function getUserOpPublicKey(UserOperation memory userOp) public view returns (uint256[4] memory publicKey) {\n bytes memory initCode = userOp.initCode;\n if (initCode.length > 0) {\n publicKey = getTrailingPublicKey(initCode);\n } else {\n return IBLSAccount(userOp.sender).getBlsPublicKey{gas : 50000}();\n }\n }\n\n /**\n * return the trailing 4 words of input data\n */\n function getTrailingPublicKey(bytes memory data) public pure returns (uint256[4] memory publicKey) {\n uint len = data.length;\n require(len > 32 * 4, \"data too short for sig\");\n\n /* solhint-disable-next-line no-inline-assembly */\n assembly {\n // actual buffer starts at data+32, so last 128 bytes start at data+32+len-128 = data+len-96\n let ofs := sub(add(data, len), 96)\n mstore(publicKey, mload(ofs))\n mstore(add(publicKey, 32), mload(add(ofs, 32)))\n mstore(add(publicKey, 64), mload(add(ofs, 64)))\n mstore(add(publicKey, 96), mload(add(ofs, 96)))\n }\n }\n\n /// @inheritdoc IAggregator\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature)\n external view override {\n require(signature.length == 64, \"BLS: invalid signature\");\n (uint256[2] memory blsSignature) = abi.decode(signature, (uint256[2]));\n\n uint userOpsLen = userOps.length;\n uint256[4][] memory blsPublicKeys = new uint256[4][](userOpsLen);\n uint256[2][] memory messages = new uint256[2][](userOpsLen);\n for (uint256 i = 0; i < userOpsLen; i++) {\n\n UserOperation memory userOp = userOps[i];\n blsPublicKeys[i] = getUserOpPublicKey(userOp);\n\n messages[i] = _userOpToMessage(userOp, _getPublicKeyHash(blsPublicKeys[i]));\n }\n require(BLSOpen.verifyMultiple(blsSignature, blsPublicKeys, messages), \"BLS: validateSignatures failed\");\n }\n\n /**\n * get a hash of userOp\n * NOTE: this hash is not the same as UserOperation.hash()\n * (slightly less efficient, since it uses memory userOp)\n */\n function internalUserOpHash(UserOperation memory userOp) internal pure returns (bytes32) {\n return keccak256(abi.encode(\n userOp.sender,\n userOp.nonce,\n keccak256(userOp.initCode),\n keccak256(userOp.callData),\n userOp.callGasLimit,\n userOp.verificationGasLimit,\n userOp.preVerificationGas,\n userOp.maxFeePerGas,\n userOp.maxPriorityFeePerGas,\n keccak256(userOp.paymasterAndData)\n ));\n }\n\n /**\n * return the BLS \"message\" for the given UserOp.\n * the account checks the signature over this value using its public key\n */\n function userOpToMessage(UserOperation memory userOp) public view returns (uint256[2] memory) {\n bytes32 publicKeyHash = _getPublicKeyHash(getUserOpPublicKey(userOp));\n return _userOpToMessage(userOp, publicKeyHash);\n }\n\n function _userOpToMessage(UserOperation memory userOp, bytes32 publicKeyHash) internal view returns (uint256[2] memory) {\n bytes32 userOpHash = _getUserOpHash(userOp, publicKeyHash);\n return BLSOpen.hashToPoint(BLS_DOMAIN, abi.encodePacked(userOpHash));\n }\n\n // helper for test\n function getUserOpHash(UserOperation memory userOp) public view returns (bytes32) {\n bytes32 publicKeyHash = _getPublicKeyHash(getUserOpPublicKey(userOp));\n return _getUserOpHash(userOp, publicKeyHash);\n }\n\n function _getUserOpHash(UserOperation memory userOp, bytes32 publicKeyHash) internal view returns (bytes32) {\n return keccak256(abi.encode(internalUserOpHash(userOp), publicKeyHash, address(this), block.chainid));\n }\n\n function _getPublicKeyHash(uint256[4] memory publicKey) internal pure returns(bytes32) {\n return keccak256(abi.encode(publicKey));\n }\n /**\n * validate signature of a single userOp\n * This method is called after EntryPoint.simulateValidation() returns an aggregator.\n * First it validates the signature over the userOp. then it return data to be used when creating the handleOps:\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp) {\n uint256[2] memory signature = abi.decode(userOp.signature, (uint256[2]));\n uint256[4] memory pubkey = getUserOpPublicKey(userOp);\n uint256[2] memory message = _userOpToMessage(userOp, _getPublicKeyHash(pubkey));\n\n require(BLSOpen.verifySingle(signature, pubkey, message), \"BLS: wrong sig\");\n return \"\";\n }\n\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external pure returns (bytes memory aggregatedSignature) {\n BLSHelper.XY[] memory points = new BLSHelper.XY[](userOps.length);\n for (uint i = 0; i < points.length; i++) {\n (uint256 x, uint256 y) = abi.decode(userOps[i].signature, (uint256, uint256));\n points[i] = BLSHelper.XY(x, y);\n }\n BLSHelper.XY memory sum = BLSHelper.sum(points, N);\n return abi.encode(sum.x, sum.y);\n }\n\n /**\n * allow staking for this aggregator\n * there is no limit on stake or delay, but it is not a problem, since it is a permissionless\n * signature aggregator, which doesn't support unstaking.\n */\n function addStake(IEntryPoint entryPoint, uint32 delay) external payable {\n entryPoint.addStake{value : msg.value}(delay);\n }\n}\n"
+ },
+ "contracts/samples/bls/IBLSAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity >=0.7.6;\n\nimport \"../../interfaces/IAccount.sol\";\n\n/**\n * a BLS account should expose its own public key.\n */\ninterface IBLSAccount is IAccount {\n event PublicKeyChanged(uint256[4] oldPublicKey, uint256[4] newPublicKey);\n\n /**\n * @return public key from a BLS keypair that is used to verify the BLS signature, both separately and aggregated.\n */\n function getBlsPublicKey() external view returns (uint256[4] memory);\n}\n"
+ },
+ "contracts/samples/bls/lib/BLSOpen.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity >= 0.6.12;\n\nimport { BLS } from \"./hubble-contracts/contracts/libs/BLS.sol\";\n\nlibrary BLSOpen {\n function verifySingle(\n uint256[2] memory signature,\n uint256[4] memory pubkey,\n uint256[2] memory message\n ) external view returns (bool) {\n uint256[4][] memory pubkeys = new uint256[4][](1);\n uint256[2][] memory messages = new uint256[2][](1);\n pubkeys[0] = pubkey;\n messages[0] = message;\n\n (bool verified, bool callSuccess) = BLS.verifyMultiple(\n signature,\n pubkeys,\n messages\n );\n return callSuccess && verified;\n\n // // NB: (result, success) opposite of `call` convention (success, result).\n // (bool verified, bool callSuccess) = BLS.verifySingle(\n // signature,\n // pubkey,\n // message\n // );\n // return callSuccess && verified;\n }\n\n function verifyMultiple(\n uint256[2] memory signature,\n uint256[4][] memory pubkeys,\n uint256[2][] memory messages\n ) external view returns (bool) {\n (bool verified, bool callSuccess) = BLS.verifyMultiple(\n signature,\n pubkeys,\n messages\n );\n return callSuccess && verified;\n }\n\n function hashToPoint(\n bytes32 domain,\n bytes memory message\n ) external view returns (uint256[2] memory) {\n return BLS.hashToPoint(\n domain,\n message\n );\n }\n\n function isZeroBLSKey(uint256[4] memory blsKey) public pure returns (bool) {\n bool isZero = true;\n for (uint256 i=0; isZero && i<4; i++) {\n isZero = (blsKey[i] == 0);\n }\n return isZero;\n }\n\n}\n"
+ },
+ "contracts/samples/bls/lib/hubble-contracts/contracts/libs/BLS.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity >= 0.6.12;\n\nimport { ModexpInverse, ModexpSqrt } from \"./ModExp.sol\";\nimport {\n BNPairingPrecompileCostEstimator\n} from \"./BNPairingPrecompileCostEstimator.sol\";\n\n/**\n @title Boneh–Lynn–Shacham (BLS) signature scheme on Barreto-Naehrig 254 bit curve (BN-254)\n @notice We use BLS signature aggregation to reduce the size of signature data to store on chain.\n @dev We use G1 points for signatures and messages, and G2 points for public keys\n */\nlibrary BLS {\n // Field order\n // prettier-ignore\n uint256 private constant N = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n // Negated genarator of G2\n // prettier-ignore\n uint256 private constant N_G2_X1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;\n // prettier-ignore\n uint256 private constant N_G2_X0 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;\n // prettier-ignore\n uint256 private constant N_G2_Y1 = 17805874995975841540914202342111839520379459829704422454583296818431106115052;\n // prettier-ignore\n uint256 private constant N_G2_Y0 = 13392588948715843804641432497768002650278120570034223513918757245338268106653;\n\n // sqrt(-3)\n // prettier-ignore\n uint256 private constant Z0 = 0x0000000000000000b3c4d79d41a91759a9e4c7e359b6b89eaec68e62effffffd;\n // (sqrt(-3) - 1) / 2\n // prettier-ignore\n uint256 private constant Z1 = 0x000000000000000059e26bcea0d48bacd4f263f1acdb5c4f5763473177fffffe;\n\n // prettier-ignore\n uint256 private constant T24 = 0x1000000000000000000000000000000000000000000000000;\n // prettier-ignore\n uint256 private constant MASK24 = 0xffffffffffffffffffffffffffffffffffffffffffffffff;\n\n // estimator address\n// address private constant COST_ESTIMATOR_ADDRESS = new 0x22E4a5251C1F02de8369Dd6f192033F6CB7531A4;\n\n function verifySingle(\n uint256[2] memory signature,\n uint256[4] memory pubkey,\n uint256[2] memory message\n ) internal view returns (bool, bool) {\n uint256[12] memory input =\n [\n signature[0],\n signature[1],\n N_G2_X1,\n N_G2_X0,\n N_G2_Y1,\n N_G2_Y0,\n message[0],\n message[1],\n pubkey[1],\n pubkey[0],\n pubkey[3],\n pubkey[2]\n ];\n uint256[1] memory out;\n uint256 precompileGasCost = gasleft();\n// BNPairingPrecompileCostEstimator(COST_ESTIMATOR_ADDRESS).getGasCost(\n// 2\n// );\n bool callSuccess;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n callSuccess := staticcall(\n precompileGasCost,\n 8,\n input,\n 384,\n out,\n 0x20\n )\n }\n if (!callSuccess) {\n return (false, false);\n }\n return (out[0] != 0, true);\n }\n\n function verifyMultiple(\n uint256[2] memory signature,\n uint256[4][] memory pubkeys,\n uint256[2][] memory messages\n ) internal view returns (bool checkResult, bool callSuccess) {\n uint256 size = pubkeys.length;\n require(size > 0, \"BLS: number of public key is zero\");\n require(\n size == messages.length,\n \"BLS: number of public keys and messages must be equal\"\n );\n uint256 inputSize = (size + 1) * 6;\n uint256[] memory input = new uint256[](inputSize);\n input[0] = signature[0];\n input[1] = signature[1];\n input[2] = N_G2_X1;\n input[3] = N_G2_X0;\n input[4] = N_G2_Y1;\n input[5] = N_G2_Y0;\n for (uint256 i = 0; i < size; i++) {\n input[i * 6 + 6] = messages[i][0];\n input[i * 6 + 7] = messages[i][1];\n input[i * 6 + 8] = pubkeys[i][1];\n input[i * 6 + 9] = pubkeys[i][0];\n input[i * 6 + 10] = pubkeys[i][3];\n input[i * 6 + 11] = pubkeys[i][2];\n }\n uint256[1] memory out;\n\n // prettier-ignore\n uint256 precompileGasCost = gasleft();\n// uint256 precompileGasCost = BNPairingPrecompileCostEstimator(COST_ESTIMATOR_ADDRESS).getGasCost(size + 1);\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n callSuccess := staticcall(\n precompileGasCost,\n 8,\n add(input, 0x20),\n mul(inputSize, 0x20),\n out,\n 0x20\n )\n }\n if (!callSuccess) {\n return (false, false);\n }\n return (out[0] != 0, true);\n }\n\n /**\n @notice Fouque-Tibouchi Hash to Curve\n */\n function hashToPoint(bytes32 domain, bytes memory message)\n internal\n view\n returns (uint256[2] memory)\n {\n uint256[2] memory u = hashToField(domain, message);\n uint256[2] memory p0 = mapToPoint(u[0]);\n uint256[2] memory p1 = mapToPoint(u[1]);\n uint256[4] memory bnAddInput;\n bnAddInput[0] = p0[0];\n bnAddInput[1] = p0[1];\n bnAddInput[2] = p1[0];\n bnAddInput[3] = p1[1];\n bool success;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n success := staticcall(sub(gas(), 2000), 6, bnAddInput, 128, p0, 64)\n switch success\n case 0 {\n invalid()\n }\n }\n require(success, \"BLS: bn add call failed\");\n return p0;\n }\n\n function mapToPoint(uint256 _x)\n internal\n pure\n returns (uint256[2] memory p)\n {\n require(_x < N, \"mapToPointFT: invalid field element\");\n uint256 x = _x;\n\n (, bool decision) = sqrt(x);\n\n uint256 a0 = mulmod(x, x, N);\n a0 = addmod(a0, 4, N);\n uint256 a1 = mulmod(x, Z0, N);\n uint256 a2 = mulmod(a1, a0, N);\n a2 = inverse(a2);\n a1 = mulmod(a1, a1, N);\n a1 = mulmod(a1, a2, N);\n\n // x1\n a1 = mulmod(x, a1, N);\n x = addmod(Z1, N - a1, N);\n // check curve\n a1 = mulmod(x, x, N);\n a1 = mulmod(a1, x, N);\n a1 = addmod(a1, 3, N);\n bool found;\n (a1, found) = sqrt(a1);\n if (found) {\n if (!decision) {\n a1 = N - a1;\n }\n return [x, a1];\n }\n\n // x2\n x = N - addmod(x, 1, N);\n // check curve\n a1 = mulmod(x, x, N);\n a1 = mulmod(a1, x, N);\n a1 = addmod(a1, 3, N);\n (a1, found) = sqrt(a1);\n if (found) {\n if (!decision) {\n a1 = N - a1;\n }\n return [x, a1];\n }\n\n // x3\n x = mulmod(a0, a0, N);\n x = mulmod(x, x, N);\n x = mulmod(x, a2, N);\n x = mulmod(x, a2, N);\n x = addmod(x, 1, N);\n // must be on curve\n a1 = mulmod(x, x, N);\n a1 = mulmod(a1, x, N);\n a1 = addmod(a1, 3, N);\n (a1, found) = sqrt(a1);\n require(found, \"BLS: bad ft mapping implementation\");\n if (!decision) {\n a1 = N - a1;\n }\n return [x, a1];\n }\n\n function isValidSignature(uint256[2] memory signature)\n internal\n pure\n returns (bool)\n {\n if ((signature[0] >= N) || (signature[1] >= N)) {\n return false;\n } else {\n return isOnCurveG1(signature);\n }\n }\n\n function isOnCurveG1(uint256[2] memory point)\n internal\n pure\n returns (bool _isOnCurve)\n {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let t0 := mload(point)\n let t1 := mload(add(point, 32))\n let t2 := mulmod(t0, t0, N)\n t2 := mulmod(t2, t0, N)\n t2 := addmod(t2, 3, N)\n t1 := mulmod(t1, t1, N)\n _isOnCurve := eq(t1, t2)\n }\n }\n\n function isOnCurveG2(uint256[4] memory point)\n internal\n pure\n returns (bool _isOnCurve)\n {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n // x0, x1\n let t0 := mload(point)\n let t1 := mload(add(point, 32))\n // x0 ^ 2\n let t2 := mulmod(t0, t0, N)\n // x1 ^ 2\n let t3 := mulmod(t1, t1, N)\n // 3 * x0 ^ 2\n let t4 := add(add(t2, t2), t2)\n // 3 * x1 ^ 2\n let t5 := addmod(add(t3, t3), t3, N)\n // x0 * (x0 ^ 2 - 3 * x1 ^ 2)\n t2 := mulmod(add(t2, sub(N, t5)), t0, N)\n // x1 * (3 * x0 ^ 2 - x1 ^ 2)\n t3 := mulmod(add(t4, sub(N, t3)), t1, N)\n\n // x ^ 3 + b\n t0 := addmod(\n t2,\n 0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5,\n N\n )\n t1 := addmod(\n t3,\n 0x009713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2,\n N\n )\n\n // y0, y1\n t2 := mload(add(point, 64))\n t3 := mload(add(point, 96))\n // y ^ 2\n t4 := mulmod(addmod(t2, t3, N), addmod(t2, sub(N, t3), N), N)\n t3 := mulmod(shl(1, t2), t3, N)\n\n // y ^ 2 == x ^ 3 + b\n _isOnCurve := and(eq(t0, t4), eq(t1, t3))\n }\n }\n\n function sqrt(uint256 xx) internal pure returns (uint256 x, bool hasRoot) {\n x = ModexpSqrt.run(xx);\n hasRoot = mulmod(x, x, N) == xx;\n }\n\n function inverse(uint256 a) internal pure returns (uint256) {\n return ModexpInverse.run(a);\n }\n\n function hashToField(bytes32 domain, bytes memory messages)\n internal\n pure\n returns (uint256[2] memory)\n {\n bytes memory _msg = expandMsgTo96(domain, messages);\n uint256 u0;\n uint256 u1;\n uint256 a0;\n uint256 a1;\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let p := add(_msg, 24)\n u1 := and(mload(p), MASK24)\n p := add(_msg, 48)\n u0 := and(mload(p), MASK24)\n a0 := addmod(mulmod(u1, T24, N), u0, N)\n p := add(_msg, 72)\n u1 := and(mload(p), MASK24)\n p := add(_msg, 96)\n u0 := and(mload(p), MASK24)\n a1 := addmod(mulmod(u1, T24, N), u0, N)\n }\n return [a0, a1];\n }\n\n function expandMsgTo96(bytes32 domain, bytes memory message)\n internal\n pure\n returns (bytes memory)\n {\n // zero<64>|msg|lib_str<2>|I2OSP(0, 1)<1>|dst|dst_len<1>\n uint256 t0 = message.length;\n bytes memory msg0 = new bytes(32 + t0 + 64 + 4);\n bytes memory out = new bytes(96);\n // b0\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let p := add(msg0, 96)\n for {\n let z := 0\n } lt(z, t0) {\n z := add(z, 32)\n } {\n mstore(add(p, z), mload(add(message, add(z, 32))))\n }\n p := add(p, t0)\n\n mstore8(p, 0)\n p := add(p, 1)\n mstore8(p, 96)\n p := add(p, 1)\n mstore8(p, 0)\n p := add(p, 1)\n\n mstore(p, domain)\n p := add(p, 32)\n mstore8(p, 32)\n }\n bytes32 b0 = sha256(msg0);\n bytes32 bi;\n t0 = 32 + 34;\n\n // resize intermediate message\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n mstore(msg0, t0)\n }\n\n // b1\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n mstore(add(msg0, 32), b0)\n mstore8(add(msg0, 64), 1)\n mstore(add(msg0, 65), domain)\n mstore8(add(msg0, add(32, 65)), 32)\n }\n\n bi = sha256(msg0);\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n mstore(add(out, 32), bi)\n }\n\n // b2\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let t := xor(b0, bi)\n mstore(add(msg0, 32), t)\n mstore8(add(msg0, 64), 2)\n mstore(add(msg0, 65), domain)\n mstore8(add(msg0, add(32, 65)), 32)\n }\n\n bi = sha256(msg0);\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n mstore(add(out, 64), bi)\n }\n\n // b3\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let t := xor(b0, bi)\n mstore(add(msg0, 32), t)\n mstore8(add(msg0, 64), 3)\n mstore(add(msg0, 65), domain)\n mstore8(add(msg0, add(32, 65)), 32)\n }\n\n bi = sha256(msg0);\n\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n mstore(add(out, 96), bi)\n }\n\n return out;\n }\n}\n"
+ },
+ "contracts/samples/bls/lib/hubble-contracts/contracts/libs/BNPairingPrecompileCostEstimator.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.12;\n\ncontract BNPairingPrecompileCostEstimator {\n uint256 public baseCost;\n uint256 public perPairCost;\n\n // G1 Generator\n uint256 private constant G1_X = 1;\n uint256 private constant G1_Y = 2;\n\n // G2 genarator\n // prettier-ignore\n uint256 private constant G2_X0 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;\n // prettier-ignore\n uint256 private constant G2_X1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;\n // prettier-ignore\n uint256 private constant G2_Y0 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;\n // prettier-ignore\n uint256 private constant G2_Y1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;\n\n // G2 negated genarator y coordinates\n // prettier-ignore\n uint256 private constant N_G2_Y0 = 13392588948715843804641432497768002650278120570034223513918757245338268106653;\n // prettier-ignore\n uint256 private constant N_G2_Y1 = 17805874995975841540914202342111839520379459829704422454583296818431106115052;\n\n function run() external {\n _run();\n }\n\n function getGasCost(uint256 pairCount) external view returns (uint256) {\n return pairCount * perPairCost + baseCost;\n }\n\n function _run() internal {\n uint256 gasCost1Pair = _gasCost1Pair();\n uint256 gasCost2Pair = _gasCost2Pair();\n perPairCost = gasCost2Pair - gasCost1Pair;\n baseCost = gasCost1Pair - perPairCost;\n }\n\n function _gasCost1Pair() internal view returns (uint256) {\n uint256[6] memory input = [G1_X, G1_Y, G2_X1, G2_X0, G2_Y1, G2_Y0];\n uint256[1] memory out;\n bool callSuccess;\n uint256 suppliedGas = gasleft() - 2000;\n require(\n gasleft() > 2000,\n \"BNPairingPrecompileCostEstimator: not enough gas, single pair\"\n );\n uint256 gasT0 = gasleft();\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n callSuccess := staticcall(suppliedGas, 8, input, 192, out, 0x20)\n }\n uint256 gasCost = gasT0 - gasleft();\n require(\n callSuccess,\n \"BNPairingPrecompileCostEstimator: single pair call is failed\"\n );\n require(\n out[0] == 0,\n \"BNPairingPrecompileCostEstimator: single pair call result must be 0\"\n );\n return gasCost;\n }\n\n function _gasCost2Pair() internal view returns (uint256) {\n uint256[12] memory input =\n [\n G1_X,\n G1_Y,\n G2_X1,\n G2_X0,\n G2_Y1,\n G2_Y0,\n G1_X,\n G1_Y,\n G2_X1,\n G2_X0,\n N_G2_Y1,\n N_G2_Y0\n ];\n uint256[1] memory out;\n bool callSuccess;\n uint256 suppliedGas = gasleft() - 2000;\n require(\n gasleft() > 2000,\n \"BNPairingPrecompileCostEstimator: not enough gas, couple pair\"\n );\n uint256 gasT0 = gasleft();\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n callSuccess := staticcall(suppliedGas, 8, input, 384, out, 0x20)\n }\n uint256 gasCost = gasT0 - gasleft();\n require(\n callSuccess,\n \"BNPairingPrecompileCostEstimator: couple pair call is failed\"\n );\n require(\n out[0] == 1,\n \"BNPairingPrecompileCostEstimator: couple pair call result must be 1\"\n );\n return gasCost;\n }\n}\n"
+ },
+ "contracts/samples/bls/lib/hubble-contracts/contracts/libs/ModExp.sol": {
+ "content": "// SPDX-License-Identifier: MIT\npragma solidity >= 0.6.12;\n\n/**\n @title Compute Inverse by Modular Exponentiation\n @notice Compute $input^(N - 2) mod N$ using Addition Chain method.\n Where N = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47\n and N - 2 = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45\n @dev the function body is generated with the modified addchain script\n see https://github.com/kobigurk/addchain/commit/2c37a2ace567a9bdc680b4e929c94aaaa3ec700f\n */\nlibrary ModexpInverse {\n function run(uint256 t2) internal pure returns (uint256 t0) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let\n n\n := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47\n t0 := mulmod(t2, t2, n)\n let t5 := mulmod(t0, t2, n)\n let t1 := mulmod(t5, t0, n)\n let t3 := mulmod(t5, t5, n)\n let t8 := mulmod(t1, t0, n)\n let t4 := mulmod(t3, t5, n)\n let t6 := mulmod(t3, t1, n)\n t0 := mulmod(t3, t3, n)\n let t7 := mulmod(t8, t3, n)\n t3 := mulmod(t4, t3, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t7, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t7, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t4, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t7, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t3, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t3, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t4, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t3, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n }\n }\n}\n\n/**\n @title Compute Squre Root by Modular Exponentiation\n @notice Compute $input^{(N + 1) / 4} mod N$ using Addition Chain method.\n Where N = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47\n and (N + 1) / 4 = 0xc19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f52\n */\nlibrary ModexpSqrt {\n function run(uint256 t6) internal pure returns (uint256 t0) {\n // solium-disable-next-line security/no-inline-assembly\n assembly {\n let\n n\n := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47\n\n t0 := mulmod(t6, t6, n)\n let t4 := mulmod(t0, t6, n)\n let t2 := mulmod(t4, t0, n)\n let t3 := mulmod(t4, t4, n)\n let t8 := mulmod(t2, t0, n)\n let t1 := mulmod(t3, t4, n)\n let t5 := mulmod(t3, t2, n)\n t0 := mulmod(t3, t3, n)\n let t7 := mulmod(t8, t3, n)\n t3 := mulmod(t1, t3, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t4, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t4, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t7, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t4, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t7, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t4, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t4, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t8, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t7, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t3, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t6, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t4, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t5, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t4, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t4, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t3, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t3, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t2, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t0, n)\n t0 := mulmod(t0, t1, n)\n t0 := mulmod(t0, t0, n)\n }\n }\n}\n"
+ },
+ "contracts/samples/callback/TokenCallbackHandler.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-empty-blocks */\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport \"@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol\";\n\n/**\n * Token callback handler.\n * Handles supported tokens' callbacks, allowing account receiving these tokens.\n */\ncontract TokenCallbackHandler is IERC777Recipient, IERC721Receiver, IERC1155Receiver {\n function tokensReceived(\n address,\n address,\n address,\n uint256,\n bytes calldata,\n bytes calldata\n ) external pure override {\n }\n\n function onERC721Received(\n address,\n address,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC721Receiver.onERC721Received.selector;\n }\n\n function onERC1155Received(\n address,\n address,\n uint256,\n uint256,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155Received.selector;\n }\n\n function onERC1155BatchReceived(\n address,\n address,\n uint256[] calldata,\n uint256[] calldata,\n bytes calldata\n ) external pure override returns (bytes4) {\n return IERC1155Receiver.onERC1155BatchReceived.selector;\n }\n\n function supportsInterface(bytes4 interfaceId) external view virtual override returns (bool) {\n return\n interfaceId == type(IERC721Receiver).interfaceId ||\n interfaceId == type(IERC1155Receiver).interfaceId ||\n interfaceId == type(IERC165).interfaceId;\n }\n}\n"
+ },
+ "contracts/samples/DepositPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable reason-string */\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"../core/BasePaymaster.sol\";\nimport \"./IOracle.sol\";\n\n/**\n * A token-based paymaster that accepts token deposits\n * The deposit is only a safeguard: the user pays with his token balance.\n * only if the user didn't approve() the paymaster, or if the token balance is not enough, the deposit will be used.\n * thus the required deposit is to cover just one method call.\n * The deposit is locked for the current block: the user must issue unlockTokenDeposit() to be allowed to withdraw\n * (but can't use the deposit for this or further operations)\n *\n * paymasterAndData holds the paymaster address followed by the token address to use.\n * @notice This paymaster will be rejected by the standard rules of EIP4337, as it uses an external oracle.\n * (the standard rules ban accessing data of an external contract)\n * It can only be used if it is \"whitelisted\" by the bundler.\n * (technically, it can be used by an \"oracle\" which returns a static value, without accessing any storage)\n */\ncontract DepositPaymaster is BasePaymaster {\n\n using UserOperationLib for UserOperation;\n using SafeERC20 for IERC20;\n\n //calculated cost of the postOp\n uint256 constant public COST_OF_POST = 35000;\n\n IOracle private constant NULL_ORACLE = IOracle(address(0));\n mapping(IERC20 => IOracle) public oracles;\n mapping(IERC20 => mapping(address => uint256)) public balances;\n mapping(address => uint256) public unlockBlock;\n\n constructor(IEntryPoint _entryPoint) BasePaymaster(_entryPoint) {\n //owner account is unblocked, to allow withdraw of paid tokens;\n unlockTokenDeposit();\n }\n\n /**\n * owner of the paymaster should add supported tokens\n */\n function addToken(IERC20 token, IOracle tokenPriceOracle) external onlyOwner {\n require(oracles[token] == NULL_ORACLE, \"Token already set\");\n oracles[token] = tokenPriceOracle;\n }\n\n /**\n * deposit tokens that a specific account can use to pay for gas.\n * The sender must first approve this paymaster to withdraw these tokens (they are only withdrawn in this method).\n * Note depositing the tokens is equivalent to transferring them to the \"account\" - only the account can later\n * use them - either as gas, or using withdrawTo()\n *\n * @param token the token to deposit.\n * @param account the account to deposit for.\n * @param amount the amount of token to deposit.\n */\n function addDepositFor(IERC20 token, address account, uint256 amount) external {\n //(sender must have approval for the paymaster)\n token.safeTransferFrom(msg.sender, address(this), amount);\n require(oracles[token] != NULL_ORACLE, \"unsupported token\");\n balances[token][account] += amount;\n if (msg.sender == account) {\n lockTokenDeposit();\n }\n }\n\n /**\n * @return amount - the amount of given token deposited to the Paymaster.\n * @return _unlockBlock - the block height at which the deposit can be withdrawn.\n */\n function depositInfo(IERC20 token, address account) public view returns (uint256 amount, uint256 _unlockBlock) {\n amount = balances[token][account];\n _unlockBlock = unlockBlock[account];\n }\n\n /**\n * unlock deposit, so that it can be withdrawn.\n * can't be called in the same block as withdrawTo()\n */\n function unlockTokenDeposit() public {\n unlockBlock[msg.sender] = block.number;\n }\n\n /**\n * lock the tokens deposited for this account so they can be used to pay for gas.\n * after calling unlockTokenDeposit(), the account can't use this paymaster until the deposit is locked.\n */\n function lockTokenDeposit() public {\n unlockBlock[msg.sender] = 0;\n }\n\n /**\n * withdraw tokens.\n * can only be called after unlock() is called in a previous block.\n * @param token the token deposit to withdraw\n * @param target address to send to\n * @param amount amount to withdraw\n */\n function withdrawTokensTo(IERC20 token, address target, uint256 amount) public {\n require(unlockBlock[msg.sender] != 0 && block.number > unlockBlock[msg.sender], \"DepositPaymaster: must unlockTokenDeposit\");\n balances[token][msg.sender] -= amount;\n token.safeTransfer(target, amount);\n }\n\n /**\n * translate the given eth value to token amount\n * @param token the token to use\n * @param ethBought the required eth value we want to \"buy\"\n * @return requiredTokens the amount of tokens required to get this amount of eth\n */\n function getTokenValueOfEth(IERC20 token, uint256 ethBought) internal view virtual returns (uint256 requiredTokens) {\n IOracle oracle = oracles[token];\n require(oracle != NULL_ORACLE, \"DepositPaymaster: unsupported token\");\n return oracle.getTokenValueOfEth(ethBought);\n }\n\n /**\n * Validate the request:\n * The sender should have enough deposit to pay the max possible cost.\n * Note that the sender's balance is not checked. If it fails to pay from its balance,\n * this deposit will be used to compensate the paymaster for the transaction.\n */\n function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n internal view override returns (bytes memory context, uint256 validationData) {\n\n (userOpHash);\n // verificationGasLimit is dual-purposed, as gas limit for postOp. make sure it is high enough\n require(userOp.verificationGasLimit > COST_OF_POST, \"DepositPaymaster: gas too low for postOp\");\n\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n require(paymasterAndData.length == 20+20, \"DepositPaymaster: paymasterAndData must specify token\");\n IERC20 token = IERC20(address(bytes20(paymasterAndData[20:])));\n address account = userOp.getSender();\n uint256 maxTokenCost = getTokenValueOfEth(token, maxCost);\n uint256 gasPriceUserOp = userOp.gasPrice();\n require(unlockBlock[account] == 0, \"DepositPaymaster: deposit not locked\");\n require(balances[token][account] >= maxTokenCost, \"DepositPaymaster: deposit too low\");\n return (abi.encode(account, token, gasPriceUserOp, maxTokenCost, maxCost),0);\n }\n\n /**\n * perform the post-operation to charge the sender for the gas.\n * in normal mode, use transferFrom to withdraw enough tokens from the sender's balance.\n * in case the transferFrom fails, the _postOp reverts and the entryPoint will call it again,\n * this time in *postOpReverted* mode.\n * In this mode, we use the deposit to pay (which we validated to be large enough)\n */\n function _postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) internal override {\n\n (address account, IERC20 token, uint256 gasPricePostOp, uint256 maxTokenCost, uint256 maxCost) = abi.decode(context, (address, IERC20, uint256, uint256, uint256));\n //use same conversion rate as used for validation.\n uint256 actualTokenCost = (actualGasCost + COST_OF_POST * gasPricePostOp) * maxTokenCost / maxCost;\n if (mode != PostOpMode.postOpReverted) {\n // attempt to pay with tokens:\n token.safeTransferFrom(account, address(this), actualTokenCost);\n } else {\n //in case above transferFrom failed, pay with deposit:\n balances[token][account] -= actualTokenCost;\n }\n balances[token][owner()] += actualTokenCost;\n }\n}\n"
+ },
+ "contracts/samples/gnosis/EIP4337Fallback.sol": {
+ "content": "//SPDX-License-Identifier: GPL\npragma solidity ^0.8.7;\n\n/* solhint-disable no-inline-assembly */\n\nimport \"@gnosis.pm/safe-contracts/contracts/handler/DefaultCallbackHandler.sol\";\nimport \"@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol\";\nimport \"@openzeppelin/contracts/interfaces/IERC1271.sol\";\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"../../interfaces/IAccount.sol\";\nimport \"./EIP4337Manager.sol\";\n\nusing ECDSA for bytes32;\n\n/**\n * The GnosisSafe enables adding custom functions implementation to the Safe by setting a 'fallbackHandler'.\n * This 'fallbackHandler' adds an implementation of 'validateUserOp' to the GnosisSafe.\n * Note that the implementation of the 'validateUserOp' method is located in the EIP4337Manager.\n * Upon receiving the 'validateUserOp', a Safe with EIP4337Fallback enabled makes a 'delegatecall' to EIP4337Manager.\n */\ncontract EIP4337Fallback is DefaultCallbackHandler, IAccount, IERC1271 {\n bytes4 internal constant ERC1271_MAGIC_VALUE = 0x1626ba7e;\n\n address immutable public eip4337manager;\n constructor(address _eip4337manager) {\n eip4337manager = _eip4337manager;\n }\n\n /**\n * delegate the contract call to the EIP4337Manager\n */\n function delegateToManager() internal returns (bytes memory) {\n // delegate entire msg.data (including the appended \"msg.sender\") to the EIP4337Manager\n // will work only for GnosisSafe contracts\n GnosisSafe safe = GnosisSafe(payable(msg.sender));\n (bool success, bytes memory ret) = safe.execTransactionFromModuleReturnData(eip4337manager, 0, msg.data, Enum.Operation.DelegateCall);\n if (!success) {\n assembly {\n revert(add(ret, 32), mload(ret))\n }\n }\n return ret;\n }\n\n /**\n * called from the Safe. delegate actual work to EIP4337Manager\n */\n function validateUserOp(UserOperation calldata, bytes32, uint256) override external returns (uint256 deadline){\n bytes memory ret = delegateToManager();\n return abi.decode(ret, (uint256));\n }\n\n /**\n * Helper for wallet to get the next nonce.\n */\n function getNonce() public returns (uint256 nonce) {\n bytes memory ret = delegateToManager();\n (nonce) = abi.decode(ret, (uint256));\n }\n\n /**\n * called from the Safe. delegate actual work to EIP4337Manager\n */\n function executeAndRevert(\n address,\n uint256,\n bytes memory,\n Enum.Operation\n ) external {\n delegateToManager();\n }\n\n function isValidSignature(\n bytes32 _hash,\n bytes memory _signature\n ) external override view returns (bytes4) {\n bytes32 hash = _hash.toEthSignedMessageHash();\n address recovered = hash.recover(_signature);\n\n GnosisSafe safe = GnosisSafe(payable(address(msg.sender)));\n\n // Validate signatures\n if (safe.isOwner(recovered)) {\n return ERC1271_MAGIC_VALUE;\n } else {\n return 0xffffffff;\n }\n }\n}\n"
+ },
+ "contracts/samples/gnosis/EIP4337Manager.sol": {
+ "content": "//SPDX-License-Identifier: GPL\npragma solidity ^0.8.7;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"@gnosis.pm/safe-contracts/contracts/GnosisSafe.sol\";\nimport \"@gnosis.pm/safe-contracts/contracts/base/Executor.sol\";\nimport \"@gnosis.pm/safe-contracts/contracts/examples/libraries/GnosisSafeStorage.sol\";\nimport \"./EIP4337Fallback.sol\";\nimport \"../../interfaces/IAccount.sol\";\nimport \"../../interfaces/IEntryPoint.sol\";\nimport \"../../utils/Exec.sol\";\n\n using ECDSA for bytes32;\n\n/**\n * Main EIP4337 module.\n * Called (through the fallback module) using \"delegate\" from the GnosisSafe as an \"IAccount\",\n * so must implement validateUserOp\n * holds an immutable reference to the EntryPoint\n * Inherits GnosisSafe so that it can reference the memory storage\n */\ncontract EIP4337Manager is IAccount, GnosisSafeStorage, Executor {\n\n address public immutable eip4337Fallback;\n address public immutable entryPoint;\n\n // return value in case of signature failure, with no time-range.\n // equivalent to _packValidationData(true,0,0);\n uint256 constant internal SIG_VALIDATION_FAILED = 1;\n\n address internal constant SENTINEL_MODULES = address(0x1);\n\n constructor(address anEntryPoint) {\n entryPoint = anEntryPoint;\n eip4337Fallback = address(new EIP4337Fallback(address(this)));\n }\n\n /**\n * delegate-called (using execFromModule) through the fallback, so \"real\" msg.sender is attached as last 20 bytes\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external override returns (uint256 validationData) {\n address msgSender = address(bytes20(msg.data[msg.data.length - 20 :]));\n require(msgSender == entryPoint, \"account: not from entrypoint\");\n\n GnosisSafe pThis = GnosisSafe(payable(address(this)));\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n address recovered = hash.recover(userOp.signature);\n require(threshold == 1, \"account: only threshold 1\");\n if (!pThis.isOwner(recovered)) {\n validationData = SIG_VALIDATION_FAILED;\n }\n\n // mimic normal Safe nonce behaviour: prevent parallel nonces\n require(userOp.nonce < type(uint64).max, \"account: nonsequential nonce\");\n\n if (missingAccountFunds > 0) {\n //Note: MAY pay more than the minimum, to deposit for future transactions\n (bool success,) = payable(msgSender).call{value : missingAccountFunds}(\"\");\n (success);\n //ignore failure (its EntryPoint's job to verify, not account.)\n }\n }\n\n /**\n * Execute a call but also revert if the execution fails.\n * The default behavior of the Safe is to not revert if the call fails,\n * which is challenging for integrating with ERC4337 because then the\n * EntryPoint wouldn't know to emit the UserOperationRevertReason event,\n * which the frontend/client uses to capture the reason for the failure.\n */\n function executeAndRevert(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external {\n address msgSender = address(bytes20(msg.data[msg.data.length - 20 :]));\n require(msgSender == entryPoint, \"account: not from entrypoint\");\n require(msg.sender == eip4337Fallback, \"account: not from EIP4337Fallback\");\n\n bool success = execute(\n to,\n value,\n data,\n operation,\n type(uint256).max\n );\n\n bytes memory returnData = Exec.getReturnData(type(uint256).max);\n // Revert with the actual reason string\n // Adopted from: https://github.com/Uniswap/v3-periphery/blob/464a8a49611272f7349c970e0fadb7ec1d3c1086/contracts/base/Multicall.sol#L16-L23\n if (!success) {\n if (returnData.length < 68) revert();\n assembly {\n returnData := add(returnData, 0x04)\n }\n revert(abi.decode(returnData, (string)));\n }\n }\n\n /**\n * Helper for wallet to get the next nonce.\n */\n function getNonce() public view returns (uint256) {\n return IEntryPoint(entryPoint).getNonce(address(this), 0);\n }\n\n /**\n * set up a safe as EIP-4337 enabled.\n * called from the GnosisSafeAccountFactory during construction time\n * - enable 3 modules (this module, fallback and the entrypoint)\n * - this method is called with delegateCall, so the module (usually itself) is passed as parameter, and \"this\" is the safe itself\n */\n function setup4337Modules(\n EIP4337Manager manager //the manager (this contract)\n ) external {\n GnosisSafe safe = GnosisSafe(payable(address(this)));\n require(!safe.isModuleEnabled(manager.entryPoint()), \"setup4337Modules: entrypoint already enabled\");\n require(!safe.isModuleEnabled(manager.eip4337Fallback()), \"setup4337Modules: eip4337Fallback already enabled\");\n safe.enableModule(manager.entryPoint());\n safe.enableModule(manager.eip4337Fallback());\n }\n\n /**\n * replace EIP4337 module, to support a new EntryPoint.\n * must be called using execTransaction and Enum.Operation.DelegateCall\n * @param prevModule returned by getCurrentEIP4337Manager\n * @param oldManager the old EIP4337 manager to remove, returned by getCurrentEIP4337Manager\n * @param newManager the new EIP4337Manager, usually with a new EntryPoint\n */\n function replaceEIP4337Manager(address prevModule, EIP4337Manager oldManager, EIP4337Manager newManager) public {\n GnosisSafe pThis = GnosisSafe(payable(address(this)));\n address oldFallback = oldManager.eip4337Fallback();\n require(pThis.isModuleEnabled(oldFallback), \"replaceEIP4337Manager: oldManager is not active\");\n pThis.disableModule(oldFallback, oldManager.entryPoint());\n pThis.disableModule(prevModule, oldFallback);\n\n address eip4337fallback = newManager.eip4337Fallback();\n\n pThis.enableModule(newManager.entryPoint());\n pThis.enableModule(eip4337fallback);\n pThis.setFallbackHandler(eip4337fallback);\n\n validateEip4337(pThis, newManager);\n }\n\n /**\n * Validate this gnosisSafe is callable through the EntryPoint.\n * the test is might be incomplete: we check that we reach our validateUserOp and fail on signature.\n * we don't test full transaction\n */\n function validateEip4337(GnosisSafe safe, EIP4337Manager manager) public {\n\n // this prevents mistaken replaceEIP4337Manager to disable the module completely.\n // minimal signature that pass \"recover\"\n bytes memory sig = new bytes(65);\n sig[64] = bytes1(uint8(27));\n sig[2] = bytes1(uint8(1));\n sig[35] = bytes1(uint8(1));\n uint256 nonce = uint256(IEntryPoint(manager.entryPoint()).getNonce(address(safe), 0));\n UserOperation memory userOp = UserOperation(address(safe), nonce, \"\", \"\", 0, 1000000, 0, 0, 0, \"\", sig);\n UserOperation[] memory userOps = new UserOperation[](1);\n userOps[0] = userOp;\n IEntryPoint _entryPoint = IEntryPoint(payable(manager.entryPoint()));\n try _entryPoint.handleOps(userOps, payable(msg.sender)) {\n revert(\"validateEip4337: handleOps must fail\");\n } catch (bytes memory error) {\n if (keccak256(error) != keccak256(abi.encodeWithSignature(\"FailedOp(uint256,string)\", 0, \"AA24 signature error\"))) {\n revert(string(error));\n }\n }\n }\n /**\n * enumerate modules, and find the currently active EIP4337 manager (and previous module)\n * @return prev prev module, needed by replaceEIP4337Manager\n * @return manager the current active EIP4337Manager\n */\n function getCurrentEIP4337Manager(GnosisSafe safe) public view returns (address prev, address manager) {\n prev = address(SENTINEL_MODULES);\n (address[] memory modules,) = safe.getModulesPaginated(SENTINEL_MODULES, 100);\n for (uint i = 0; i < modules.length; i++) {\n address module = modules[i];\n try EIP4337Fallback(module).eip4337manager() returns (address _manager) {\n return (prev, _manager);\n }\n // solhint-disable-next-line no-empty-blocks\n catch {}\n prev = module;\n }\n return (address(0), address(0));\n }\n}\n"
+ },
+ "contracts/samples/gnosis/GnosisAccountFactory.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/utils/Create2.sol\";\nimport \"@gnosis.pm/safe-contracts/contracts/proxies/GnosisSafeProxyFactory.sol\";\nimport \"./EIP4337Manager.sol\";\n\n/**\n * A wrapper factory contract to deploy GnosisSafe as an ERC-4337 account contract.\n */\ncontract GnosisSafeAccountFactory {\n\n GnosisSafeProxyFactory public immutable proxyFactory;\n address public immutable safeSingleton;\n EIP4337Manager public immutable eip4337Manager;\n\n constructor(GnosisSafeProxyFactory _proxyFactory, address _safeSingleton, EIP4337Manager _eip4337Manager) {\n proxyFactory = _proxyFactory;\n safeSingleton = _safeSingleton;\n eip4337Manager = _eip4337Manager;\n }\n\n function createAccount(address owner,uint256 salt) public returns (address) {\n address addr = getAddress(owner, salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return addr;\n }\n return address(proxyFactory.createProxyWithNonce(\n safeSingleton, getInitializer(owner), salt));\n }\n\n function getInitializer(address owner) internal view returns (bytes memory) {\n address[] memory owners = new address[](1);\n owners[0] = owner;\n uint threshold = 1;\n address eip4337fallback = eip4337Manager.eip4337Fallback();\n\n bytes memory setup4337Modules = abi.encodeCall(\n EIP4337Manager.setup4337Modules, (eip4337Manager));\n\n return abi.encodeCall(GnosisSafe.setup, (\n owners, threshold,\n address (eip4337Manager), setup4337Modules,\n eip4337fallback,\n address(0), 0, payable(0) //no payment receiver\n ));\n }\n\n /**\n * calculate the counterfactual address of this account as it would be returned by createAccount()\n * (uses the same \"create2 signature\" used by GnosisSafeProxyFactory.createProxyWithNonce)\n */\n function getAddress(address owner,uint256 salt) public view returns (address) {\n bytes memory initializer = getInitializer(owner);\n //copied from deployProxyWithNonce\n bytes32 salt2 = keccak256(abi.encodePacked(keccak256(initializer), salt));\n bytes memory deploymentData = abi.encodePacked(proxyFactory.proxyCreationCode(), uint256(uint160(safeSingleton)));\n return Create2.computeAddress(bytes32(salt2), keccak256(deploymentData), address (proxyFactory));\n }\n}\n"
+ },
+ "contracts/samples/IOracle.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface IOracle {\n\n /**\n * return amount of tokens that are required to receive that much eth.\n */\n function getTokenValueOfEth(uint256 ethOutput) external view returns (uint256 tokenInput);\n}\n\n"
+ },
+ "contracts/samples/SimpleAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\nimport \"@openzeppelin/contracts/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol\";\n\nimport \"../core/BaseAccount.sol\";\nimport \"./callback/TokenCallbackHandler.sol\";\n\n/**\n * minimal account.\n * this is sample minimal account.\n * has execute, eth handling methods\n * has a single signer that can send requests through the entryPoint.\n */\ncontract SimpleAccount is BaseAccount, TokenCallbackHandler, UUPSUpgradeable, Initializable {\n using ECDSA for bytes32;\n\n address public owner;\n\n IEntryPoint private immutable _entryPoint;\n\n event SimpleAccountInitialized(IEntryPoint indexed entryPoint, address indexed owner);\n\n modifier onlyOwner() {\n _onlyOwner();\n _;\n }\n\n /// @inheritdoc BaseAccount\n function entryPoint() public view virtual override returns (IEntryPoint) {\n return _entryPoint;\n }\n\n\n // solhint-disable-next-line no-empty-blocks\n receive() external payable {}\n\n constructor(IEntryPoint anEntryPoint) {\n _entryPoint = anEntryPoint;\n _disableInitializers();\n }\n\n function _onlyOwner() internal view {\n //directly from EOA owner, or through the account itself (which gets redirected through execute())\n require(msg.sender == owner || msg.sender == address(this), \"only owner\");\n }\n\n /**\n * execute a transaction (called directly from owner, or by entryPoint)\n */\n function execute(address dest, uint256 value, bytes calldata func) external {\n _requireFromEntryPointOrOwner();\n _call(dest, value, func);\n }\n\n /**\n * execute a sequence of transactions\n */\n function executeBatch(address[] calldata dest, bytes[] calldata func) external {\n _requireFromEntryPointOrOwner();\n require(dest.length == func.length, \"wrong array lengths\");\n for (uint256 i = 0; i < dest.length; i++) {\n _call(dest[i], 0, func[i]);\n }\n }\n\n /**\n * @dev The _entryPoint member is immutable, to reduce gas consumption. To upgrade EntryPoint,\n * a new implementation of SimpleAccount must be deployed with the new EntryPoint address, then upgrading\n * the implementation by calling `upgradeTo()`\n */\n function initialize(address anOwner) public virtual initializer {\n _initialize(anOwner);\n }\n\n function _initialize(address anOwner) internal virtual {\n owner = anOwner;\n emit SimpleAccountInitialized(_entryPoint, owner);\n }\n\n // Require the function call went through EntryPoint or owner\n function _requireFromEntryPointOrOwner() internal view {\n require(msg.sender == address(entryPoint()) || msg.sender == owner, \"account: not Owner or EntryPoint\");\n }\n\n /// implement template method of BaseAccount\n function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)\n internal override virtual returns (uint256 validationData) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n if (owner != hash.recover(userOp.signature))\n return SIG_VALIDATION_FAILED;\n return 0;\n }\n\n function _call(address target, uint256 value, bytes memory data) internal {\n (bool success, bytes memory result) = target.call{value : value}(data);\n if (!success) {\n assembly {\n revert(add(result, 32), mload(result))\n }\n }\n }\n\n /**\n * check current account deposit in the entryPoint\n */\n function getDeposit() public view returns (uint256) {\n return entryPoint().balanceOf(address(this));\n }\n\n /**\n * deposit more funds for this account in the entryPoint\n */\n function addDeposit() public payable {\n entryPoint().depositTo{value : msg.value}(address(this));\n }\n\n /**\n * withdraw value from the account's deposit\n * @param withdrawAddress target to send to\n * @param amount to withdraw\n */\n function withdrawDepositTo(address payable withdrawAddress, uint256 amount) public onlyOwner {\n entryPoint().withdrawTo(withdrawAddress, amount);\n }\n\n function _authorizeUpgrade(address newImplementation) internal view override {\n (newImplementation);\n _onlyOwner();\n }\n}\n\n"
+ },
+ "contracts/samples/SimpleAccountFactory.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/utils/Create2.sol\";\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\nimport \"./SimpleAccount.sol\";\n\n/**\n * A sample factory contract for SimpleAccount\n * A UserOperations \"initCode\" holds the address of the factory, and a method call (to createAccount, in this sample factory).\n * The factory's createAccount returns the target account address even if it is already installed.\n * This way, the entryPoint.getSenderAddress() can be called either before or after the account is created.\n */\ncontract SimpleAccountFactory {\n SimpleAccount public immutable accountImplementation;\n\n constructor(IEntryPoint _entryPoint) {\n accountImplementation = new SimpleAccount(_entryPoint);\n }\n\n /**\n * create an account, and return its address.\n * returns the address even if the account is already deployed.\n * Note that during UserOperation execution, this method is called only if the account is not deployed.\n * This method returns an existing account address so that entryPoint.getSenderAddress() would work even after account creation\n */\n function createAccount(address owner,uint256 salt) public returns (SimpleAccount ret) {\n address addr = getAddress(owner, salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return SimpleAccount(payable(addr));\n }\n ret = SimpleAccount(payable(new ERC1967Proxy{salt : bytes32(salt)}(\n address(accountImplementation),\n abi.encodeCall(SimpleAccount.initialize, (owner))\n )));\n }\n\n /**\n * calculate the counterfactual address of this account as it would be returned by createAccount()\n */\n function getAddress(address owner,uint256 salt) public view returns (address) {\n return Create2.computeAddress(bytes32(salt), keccak256(abi.encodePacked(\n type(ERC1967Proxy).creationCode,\n abi.encode(\n address(accountImplementation),\n abi.encodeCall(SimpleAccount.initialize, (owner))\n )\n )));\n }\n}\n"
+ },
+ "contracts/samples/TokenPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable reason-string */\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport \"../core/BasePaymaster.sol\";\n\n/**\n * A sample paymaster that defines itself as a token to pay for gas.\n * The paymaster IS the token to use, since a paymaster cannot use an external contract.\n * Also, the exchange rate has to be fixed, since it can't reference an external Uniswap or other exchange contract.\n * subclass should override \"getTokenValueOfEth\" to provide actual token exchange rate, settable by the owner.\n * Known Limitation: this paymaster is exploitable when put into a batch with multiple ops (of different accounts):\n * - while a single op can't exploit the paymaster (if postOp fails to withdraw the tokens, the user's op is reverted,\n * and then we know we can withdraw the tokens), multiple ops with different senders (all using this paymaster)\n * in a batch can withdraw funds from 2nd and further ops, forcing the paymaster itself to pay (from its deposit)\n * - Possible workarounds are either use a more complex paymaster scheme (e.g. the DepositPaymaster) or\n * to whitelist the account and the called method ids.\n */\ncontract TokenPaymaster is BasePaymaster, ERC20 {\n\n //calculated cost of the postOp\n uint256 constant public COST_OF_POST = 15000;\n\n address public immutable theFactory;\n\n constructor(address accountFactory, string memory _symbol, IEntryPoint _entryPoint) ERC20(_symbol, _symbol) BasePaymaster(_entryPoint) {\n theFactory = accountFactory;\n //make it non-empty\n _mint(address(this), 1);\n\n //owner is allowed to withdraw tokens from the paymaster's balance\n _approve(address(this), msg.sender, type(uint).max);\n }\n\n\n /**\n * helpers for owner, to mint and withdraw tokens.\n * @param recipient - the address that will receive the minted tokens.\n * @param amount - the amount it will receive.\n */\n function mintTokens(address recipient, uint256 amount) external onlyOwner {\n _mint(recipient, amount);\n }\n\n /**\n * transfer paymaster ownership.\n * owner of this paymaster is allowed to withdraw funds (tokens transferred to this paymaster's balance)\n * when changing owner, the old owner's withdrawal rights are revoked.\n */\n function transferOwnership(address newOwner) public override virtual onlyOwner {\n // remove allowance of current owner\n _approve(address(this), owner(), 0);\n super.transferOwnership(newOwner);\n // new owner is allowed to withdraw tokens from the paymaster's balance\n _approve(address(this), newOwner, type(uint).max);\n }\n\n //Note: this method assumes a fixed ratio of token-to-eth. subclass should override to supply oracle\n // or a setter.\n function getTokenValueOfEth(uint256 valueEth) internal view virtual returns (uint256 valueToken) {\n return valueEth / 100;\n }\n\n /**\n * validate the request:\n * if this is a constructor call, make sure it is a known account.\n * verify the sender has enough tokens.\n * (since the paymaster is also the token, there is no notion of \"approval\")\n */\n function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 /*userOpHash*/, uint256 requiredPreFund)\n internal view override returns (bytes memory context, uint256 validationData) {\n uint256 tokenPrefund = getTokenValueOfEth(requiredPreFund);\n\n // verificationGasLimit is dual-purposed, as gas limit for postOp. make sure it is high enough\n // make sure that verificationGasLimit is high enough to handle postOp\n require(userOp.verificationGasLimit > COST_OF_POST, \"TokenPaymaster: gas too low for postOp\");\n\n if (userOp.initCode.length != 0) {\n _validateConstructor(userOp);\n require(balanceOf(userOp.sender) >= tokenPrefund, \"TokenPaymaster: no balance (pre-create)\");\n } else {\n\n require(balanceOf(userOp.sender) >= tokenPrefund, \"TokenPaymaster: no balance\");\n }\n\n return (abi.encode(userOp.sender), 0);\n }\n\n // when constructing an account, validate constructor code and parameters\n // we trust our factory (and that it doesn't have any other public methods)\n function _validateConstructor(UserOperation calldata userOp) internal virtual view {\n address factory = address(bytes20(userOp.initCode[0 : 20]));\n require(factory == theFactory, \"TokenPaymaster: wrong account factory\");\n }\n\n /**\n * actual charge of user.\n * this method will be called just after the user's TX with mode==OpSucceeded|OpReverted (account pays in both cases)\n * BUT: if the user changed its balance in a way that will cause postOp to revert, then it gets called again, after reverting\n * the user's TX , back to the state it was before the transaction started (before the validatePaymasterUserOp),\n * and the transaction should succeed there.\n */\n function _postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) internal override {\n //we don't really care about the mode, we just pay the gas with the user's tokens.\n (mode);\n address sender = abi.decode(context, (address));\n uint256 charge = getTokenValueOfEth(actualGasCost + COST_OF_POST);\n //actualGasCost is known to be no larger than the above requiredPreFund, so the transfer should succeed.\n _transfer(sender, address(this), charge);\n }\n}\n"
+ },
+ "contracts/samples/VerifyingPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable reason-string */\n/* solhint-disable no-inline-assembly */\n\nimport \"../core/BasePaymaster.sol\";\nimport \"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\";\n/**\n * A sample paymaster that uses external service to decide whether to pay for the UserOp.\n * The paymaster trusts an external signer to sign the transaction.\n * The calling user must pass the UserOp to that external signer first, which performs\n * whatever off-chain verification before signing the UserOp.\n * Note that this signature is NOT a replacement for the account-specific signature:\n * - the paymaster checks a signature to agree to PAY for GAS.\n * - the account checks a signature to prove identity and account ownership.\n */\ncontract VerifyingPaymaster is BasePaymaster {\n\n using ECDSA for bytes32;\n using UserOperationLib for UserOperation;\n\n address public immutable verifyingSigner;\n\n uint256 private constant VALID_TIMESTAMP_OFFSET = 20;\n\n uint256 private constant SIGNATURE_OFFSET = 84;\n\n constructor(IEntryPoint _entryPoint, address _verifyingSigner) BasePaymaster(_entryPoint) {\n verifyingSigner = _verifyingSigner;\n }\n\n mapping(address => uint256) public senderNonce;\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n // lighter signature scheme. must match UserOp.ts#packUserOp\n bytes calldata pnd = userOp.paymasterAndData;\n // copy directly the userOp from calldata up to (but not including) the paymasterAndData.\n // this encoding depends on the ABI encoding of calldata, but is much lighter to copy\n // than referencing each field separately.\n assembly {\n let ofs := userOp\n let len := sub(sub(pnd.offset, ofs), 32)\n ret := mload(0x40)\n mstore(0x40, add(ret, add(len, 32)))\n mstore(ret, len)\n calldatacopy(add(ret, 32), ofs, len)\n }\n }\n\n /**\n * return the hash we're going to sign off-chain (and validate on-chain)\n * this method is called by the off-chain service, to sign the request.\n * it is called on-chain from the validatePaymasterUserOp, to validate the signature.\n * note that this signature covers all fields of the UserOperation, except the \"paymasterAndData\",\n * which will carry the signature itself.\n */\n function getHash(UserOperation calldata userOp, uint48 validUntil, uint48 validAfter)\n public view returns (bytes32) {\n //can't use userOp.hash(), since it contains also the paymasterAndData itself.\n\n return keccak256(abi.encode(\n pack(userOp),\n block.chainid,\n address(this),\n senderNonce[userOp.getSender()],\n validUntil,\n validAfter\n ));\n }\n\n /**\n * verify our external signer signed this request.\n * the \"paymasterAndData\" is expected to be the paymaster and a signature over the entire request params\n * paymasterAndData[:20] : address(this)\n * paymasterAndData[20:84] : abi.encode(validUntil, validAfter)\n * paymasterAndData[84:] : signature\n */\n function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 /*userOpHash*/, uint256 requiredPreFund)\n internal override returns (bytes memory context, uint256 validationData) {\n (requiredPreFund);\n\n (uint48 validUntil, uint48 validAfter, bytes calldata signature) = parsePaymasterAndData(userOp.paymasterAndData);\n //ECDSA library supports both 64 and 65-byte long signatures.\n // we only \"require\" it here so that the revert reason on invalid signature will be of \"VerifyingPaymaster\", and not \"ECDSA\"\n require(signature.length == 64 || signature.length == 65, \"VerifyingPaymaster: invalid signature length in paymasterAndData\");\n bytes32 hash = ECDSA.toEthSignedMessageHash(getHash(userOp, validUntil, validAfter));\n senderNonce[userOp.getSender()]++;\n\n //don't revert on signature failure: return SIG_VALIDATION_FAILED\n if (verifyingSigner != ECDSA.recover(hash, signature)) {\n return (\"\",_packValidationData(true,validUntil,validAfter));\n }\n\n //no need for other on-chain validation: entire UserOp should have been checked\n // by the external service prior to signing it.\n return (\"\",_packValidationData(false,validUntil,validAfter));\n }\n\n function parsePaymasterAndData(bytes calldata paymasterAndData) public pure returns(uint48 validUntil, uint48 validAfter, bytes calldata signature) {\n (validUntil, validAfter) = abi.decode(paymasterAndData[VALID_TIMESTAMP_OFFSET:SIGNATURE_OFFSET],(uint48, uint48));\n signature = paymasterAndData[SIGNATURE_OFFSET:];\n }\n}\n"
+ },
+ "contracts/test/BrokenBlsAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/utils/Create2.sol\";\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\nimport \"../samples/SimpleAccount.sol\";\nimport \"../samples/bls/IBLSAccount.sol\";\n\n/**\n * for testing: a BLS account that fails to return its public-key (completely ignores its publickey)\n * this is a copy of the normal bls account, but it returns a public-key unrelated to the one it is constructed with.\n */\ncontract BrokenBLSAccount is SimpleAccount, IBLSAccount {\n address public immutable aggregator;\n\n // The constructor is used only for the \"implementation\" and only sets immutable values.\n // Mutable values slots for proxy accounts are set by the 'initialize' function.\n constructor(IEntryPoint anEntryPoint, address anAggregator) SimpleAccount(anEntryPoint) {\n aggregator = anAggregator;\n }\n\n function initialize(uint256[4] memory aPublicKey) public virtual initializer {\n (aPublicKey);\n super._initialize(address(0));\n }\n\n function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)\n internal override view returns (uint256 validationData) {\n\n (userOp, userOpHash);\n return _packValidationData(ValidationData(aggregator, 0,0));\n }\n\n function getBlsPublicKey() external override pure returns (uint256[4] memory) {\n uint256[4] memory pubkey;\n return pubkey;\n }\n}\n\n\n/**\n * Based n SimpleAccountFactory\n * can't be a subclass, since both constructor and createAccount depend on the\n * actual wallet contract constructor and initializer\n */\ncontract BrokenBLSAccountFactory {\n BrokenBLSAccount public immutable accountImplementation;\n\n constructor(IEntryPoint entryPoint, address aggregator){\n accountImplementation = new BrokenBLSAccount(entryPoint, aggregator);\n }\n\n /**\n * create an account, and return its address.\n * returns the address even if the account is already deployed.\n * Note that during UserOperation execution, this method is called only if the account is not deployed.\n * This method returns an existing account address so that entryPoint.getSenderAddress() would work even after account creation\n * Also note that out BLSSignatureAggregator requires that the public-key is the last parameter\n */\n function createAccount(uint salt, uint256[4] memory aPublicKey) public returns (BrokenBLSAccount) {\n\n address addr = getAddress(salt, aPublicKey);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return BrokenBLSAccount(payable(addr));\n }\n return BrokenBLSAccount(payable(new ERC1967Proxy{salt : bytes32(salt)}(\n address(accountImplementation),\n abi.encodeCall(BrokenBLSAccount.initialize, aPublicKey)\n )));\n }\n\n /**\n * calculate the counterfactual address of this account as it would be returned by createAccount()\n */\n function getAddress(uint salt, uint256[4] memory aPublicKey) public view returns (address) {\n return Create2.computeAddress(bytes32(salt), keccak256(abi.encodePacked(\n type(ERC1967Proxy).creationCode,\n abi.encode(\n address(accountImplementation),\n abi.encodeCall(BrokenBLSAccount.initialize, (aPublicKey))\n )\n )));\n }\n}\n"
+ },
+ "contracts/test/MaliciousAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"../core/EntryPoint.sol\";\n\ncontract MaliciousAccount is IAccount {\n IEntryPoint private ep;\n constructor(IEntryPoint _ep) payable {\n ep = _ep;\n }\n function validateUserOp(UserOperation calldata userOp, bytes32, uint256 missingAccountFunds)\n external returns (uint256 validationData) {\n ep.depositTo{value : missingAccountFunds}(address(this));\n // Now calculate basefee per EntryPoint.getUserOpGasPrice() and compare it to the basefe we pass off-chain in the signature\n uint256 externalBaseFee = abi.decode(userOp.signature, (uint256));\n uint256 requiredGas = userOp.callGasLimit + userOp.verificationGasLimit + userOp.preVerificationGas;\n uint256 gasPrice = missingAccountFunds / requiredGas;\n uint256 basefee = gasPrice - userOp.maxPriorityFeePerGas;\n require (basefee == externalBaseFee, \"Revert after first validation\");\n return 0;\n }\n}\n"
+ },
+ "contracts/test/TestAggregatedAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../samples/SimpleAccount.sol\";\n\n/**\n * test aggregated-signature account.\n * works only with TestAggregatedSignature, which doesn't really check signature, but nonce sum\n * a true aggregated account should expose data (e.g. its public key) to the aggregator.\n */\ncontract TestAggregatedAccount is SimpleAccount {\n address public immutable aggregator;\n\n // The constructor is used only for the \"implementation\" and only sets immutable values.\n // Mutable value slots for proxy accounts are set by the 'initialize' function.\n constructor(IEntryPoint anEntryPoint, address anAggregator) SimpleAccount(anEntryPoint) {\n aggregator = anAggregator;\n }\n\n /// @inheritdoc SimpleAccount\n function initialize(address) public virtual override initializer {\n super._initialize(address(0));\n }\n\n function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)\n internal override view returns (uint256 validationData) {\n (userOp, userOpHash);\n return _packValidationData(ValidationData(aggregator, 0, 0));\n }\n}\n"
+ },
+ "contracts/test/TestAggregatedAccountFactory.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/utils/Create2.sol\";\nimport \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol\";\n\nimport \"./TestAggregatedAccount.sol\";\n\n/**\n * Based on SimpleAccountFactory.\n * Cannot be a subclass since both constructor and createAccount depend on the\n * constructor and initializer of the actual account contract.\n */\ncontract TestAggregatedAccountFactory {\n TestAggregatedAccount public immutable accountImplementation;\n\n constructor(IEntryPoint anEntryPoint, address anAggregator){\n accountImplementation = new TestAggregatedAccount(anEntryPoint, anAggregator);\n }\n\n /**\n * create an account, and return its address.\n * returns the address even if the account is already deployed.\n * Note that during UserOperation execution, this method is called only if the account is not deployed.\n * This method returns an existing account address so that entryPoint.getSenderAddress() would work even after account creation\n */\n function createAccount(address owner,uint256 salt) public returns (TestAggregatedAccount ret) {\n address addr = getAddress(owner, salt);\n uint codeSize = addr.code.length;\n if (codeSize > 0) {\n return TestAggregatedAccount(payable(addr));\n }\n ret = TestAggregatedAccount(payable(new ERC1967Proxy{salt : bytes32(salt)}(\n address(accountImplementation),\n abi.encodeCall(TestAggregatedAccount.initialize, (owner))\n )));\n }\n\n /**\n * calculate the counterfactual address of this account as it would be returned by createAccount()\n */\n function getAddress(address owner,uint256 salt) public view returns (address) {\n return Create2.computeAddress(bytes32(salt), keccak256(abi.encodePacked(\n type(ERC1967Proxy).creationCode,\n abi.encode(\n address(accountImplementation),\n abi.encodeCall(TestAggregatedAccount.initialize, (owner))\n )\n )));\n }\n}\n"
+ },
+ "contracts/test/TestCounter.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n//sample \"receiver\" contract, for testing \"exec\" from account.\ncontract TestCounter {\n mapping(address => uint256) public counters;\n\n function count() public {\n counters[msg.sender] = counters[msg.sender] + 1;\n }\n\n function countFail() public pure {\n revert(\"count failed\");\n }\n\n function justemit() public {\n emit CalledFrom(msg.sender);\n }\n\n event CalledFrom(address sender);\n\n //helper method to waste gas\n // repeat - waste gas on writing storage in a loop\n // junk - dynamic buffer to stress the function size.\n mapping(uint256 => uint256) public xxx;\n uint256 public offset;\n\n function gasWaster(uint256 repeat, string calldata /*junk*/) external {\n for (uint256 i = 1; i <= repeat; i++) {\n offset++;\n xxx[offset] = i;\n }\n }\n}\n"
+ },
+ "contracts/test/TestExpirePaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../core/BasePaymaster.sol\";\n\n/**\n * test expiry mechanism: paymasterData encodes the \"validUntil\" and validAfter\" times\n */\ncontract TestExpirePaymaster is BasePaymaster {\n // solhint-disable no-empty-blocks\n constructor(IEntryPoint _entryPoint) BasePaymaster(_entryPoint)\n {}\n\n function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n internal virtual override view\n returns (bytes memory context, uint256 validationData) {\n (userOp, userOpHash, maxCost);\n (uint48 validAfter, uint48 validUntil) = abi.decode(userOp.paymasterAndData[20 :], (uint48, uint48));\n validationData = _packValidationData(false, validUntil, validAfter);\n context = \"\";\n }\n}\n"
+ },
+ "contracts/test/TestExpiryAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../samples/SimpleAccount.sol\";\n\n/**\n * A test account, for testing expiry.\n * add \"temporary\" owners, each with a time range (since..till) times for each.\n * NOTE: this is not a full \"session key\" implementation: a real session key should probably limit\n * other things, like target contracts and methods to be called.\n * also, the \"since\" value is not really useful, only for testing the entrypoint.\n */\ncontract TestExpiryAccount is SimpleAccount {\n using ECDSA for bytes32;\n\n mapping(address => uint48) public ownerAfter;\n mapping(address => uint48) public ownerUntil;\n\n // solhint-disable-next-line no-empty-blocks\n constructor(IEntryPoint anEntryPoint) SimpleAccount(anEntryPoint) {}\n\n function initialize(address anOwner) public virtual override initializer {\n super._initialize(anOwner);\n addTemporaryOwner(anOwner, 0, type(uint48).max);\n }\n\n // As this is a test contract, no need for proxy, so no need to disable init\n // solhint-disable-next-line no-empty-blocks\n function _disableInitializers() internal override {}\n\n function addTemporaryOwner(address owner, uint48 _after, uint48 _until) public onlyOwner {\n require(_until > _after, \"wrong until/after\");\n ownerAfter[owner] = _after;\n ownerUntil[owner] = _until;\n }\n\n /// implement template method of BaseAccount\n function _validateSignature(UserOperation calldata userOp, bytes32 userOpHash)\n internal override view returns (uint256 validationData) {\n bytes32 hash = userOpHash.toEthSignedMessageHash();\n address signer = hash.recover(userOp.signature);\n uint48 _until = ownerUntil[signer];\n uint48 _after = ownerAfter[signer];\n\n //we have \"until\" value for all valid owners. so zero means \"invalid signature\"\n bool sigFailed = _until == 0;\n return _packValidationData(sigFailed, _until, _after);\n }\n}\n"
+ },
+ "contracts/test/TestHelpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../core/Helpers.sol\";\n\ncontract TestHelpers {\n\n function parseValidationData(uint validationData) public pure returns (ValidationData memory) {\n return _parseValidationData(validationData);\n }\n\n function intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) public pure returns (ValidationData memory) {\n return _intersectTimeRange(validationData, paymasterValidationData);\n }\n\n function packValidationDataStruct(ValidationData memory data) public pure returns (uint256) {\n return _packValidationData(data);\n }\n\n function packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) public pure returns (uint256) {\n return _packValidationData(sigFailed, validUntil, validAfter);\n }\n}\n"
+ },
+ "contracts/test/TestOracle.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../samples/IOracle.sol\";\n\ncontract TestOracle is IOracle {\n function getTokenValueOfEth(uint256 ethOutput) external pure override returns (uint256 tokenInput) {\n return ethOutput * 2;\n }\n}\n"
+ },
+ "contracts/test/TestPaymasterAcceptAll.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../core/BasePaymaster.sol\";\n\n/**\n * test paymaster, that pays for everything, without any check.\n */\ncontract TestPaymasterAcceptAll is BasePaymaster {\n\n constructor(IEntryPoint _entryPoint) BasePaymaster(_entryPoint) {\n // to support \"deterministic address\" factory\n // solhint-disable avoid-tx-origin\n if (tx.origin != msg.sender) {\n _transferOwnership(tx.origin);\n }\n\n }\n\n function _validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n internal virtual override view\n returns (bytes memory context, uint256 validationData) {\n (userOp, userOpHash, maxCost);\n return (\"\", maxCost == 12345 ? 1 : 0);\n }\n}\n"
+ },
+ "contracts/test/TestRevertAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n/* solhint-disable no-inline-assembly */\n\nimport \"../samples/SimpleAccount.sol\";\ncontract TestRevertAccount is IAccount {\n IEntryPoint private ep;\n constructor(IEntryPoint _ep) payable {\n ep = _ep;\n }\n\n function validateUserOp(UserOperation calldata, bytes32, uint256 missingAccountFunds)\n external override returns (uint256 validationData) {\n ep.depositTo{value : missingAccountFunds}(address(this));\n return 0;\n }\n\n function revertLong(uint256 length) public pure{\n assembly {\n revert(0, length)\n }\n }\n}\n"
+ },
+ "contracts/test/TestSignatureAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable reason-string */\n\nimport \"../interfaces/IAggregator.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"../samples/SimpleAccount.sol\";\n\n/**\n * test signature aggregator.\n * the aggregated signature is the SUM of the nonce fields..\n */\ncontract TestSignatureAggregator is IAggregator {\n\n /// @inheritdoc IAggregator\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external pure override {\n uint sum = 0;\n for (uint i = 0; i < userOps.length; i++) {\n uint nonce = userOps[i].nonce;\n sum += nonce;\n }\n require(signature.length == 32, \"TestSignatureValidator: sig must be uint\");\n (uint sig) = abi.decode(signature, (uint));\n require(sig == sum, \"TestSignatureValidator: aggregated signature mismatch (nonce sum)\");\n }\n\n /// @inheritdoc IAggregator\n function validateUserOpSignature(UserOperation calldata)\n external pure returns (bytes memory) {\n return \"\";\n }\n\n /**\n * dummy test aggregator: sum all nonce values of UserOps.\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external pure returns (bytes memory aggregatedSignature) {\n uint sum = 0;\n for (uint i = 0; i < userOps.length; i++) {\n sum += userOps[i].nonce;\n }\n return abi.encode(sum);\n }\n\n /**\n * Calls the 'addStake' method of the EntryPoint. Forwards the entire msg.value to this call.\n * @param entryPoint - the EntryPoint to send the stake to.\n * @param delay - the new lock duration before the deposit can be withdrawn.\n */\n function addStake(IEntryPoint entryPoint, uint32 delay) external payable {\n entryPoint.addStake{value: msg.value}(delay);\n }\n}\n"
+ },
+ "contracts/test/TestToken.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract TestToken is ERC20 {\n constructor ()\n // solhint-disable-next-line no-empty-blocks\n ERC20(\"TST\", \"TestToken\") {\n }\n\n function mint(address sender, uint256 amount) external {\n _mint(sender, amount);\n }\n}\n"
+ },
+ "contracts/test/TestUtil.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../interfaces/UserOperation.sol\";\n\ncontract TestUtil {\n using UserOperationLib for UserOperation;\n\n function packUserOp(UserOperation calldata op) external pure returns (bytes memory){\n return op.pack();\n }\n\n}\n"
+ },
+ "contracts/test/TestWarmColdAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IEntryPoint.sol\";\nimport \"../interfaces/IAccount.sol\";\n\n// Using eip-2929 (https://eips.ethereum.org/EIPS/eip-2929) warm/cold storage access gas costs to detect simulation vs execution\n// COLD_ACCOUNT_ACCESS_COST == 2600, COLD_SLOAD_COST == 2100, WARM_STORAGE_READ_COST == 100\ncontract TestWarmColdAccount is IAccount {\n IEntryPoint private ep;\n uint public state = 1;\n constructor(IEntryPoint _ep) payable {\n ep = _ep;\n }\n\n function validateUserOp(UserOperation calldata userOp, bytes32, uint256 missingAccountFunds)\n external override returns (uint256 validationData) {\n ep.depositTo{value : missingAccountFunds}(address(this));\n if (userOp.nonce == 1) {\n // can only succeed if storage is already warm\n this.touchStorage{gas: 1000}();\n } else if (userOp.nonce == 2) {\n address paymaster = address(bytes20(userOp.paymasterAndData[: 20]));\n // can only succeed if storage is already warm\n this.touchPaymaster{gas: 1000}(paymaster);\n }\n return 0;\n }\n\n function touchStorage() public view returns (uint256) {\n return state;\n }\n\n function touchPaymaster(address paymaster) public view returns (uint256) {\n return paymaster.code.length;\n }\n}\n"
+ },
+ "contracts/utils/Exec.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {\n bool success = call(to,0,data,gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 1000000
+ },
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata",
+ "devdoc",
+ "userdoc",
+ "storageLayout",
+ "evm.gasEstimates"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ },
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/solcInputs/a4c52f0671aad8941c53d6ead2063803.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
new file mode 100644
index 00000000..dd58ba5a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
@@ -0,0 +1,68 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts/security/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n"
+ },
+ "contracts/core/EntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard {\n\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success,) = beneficiary.call{value : amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) public nonReentrant {\n\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(address(aggregator) != address(1), \"AA96 invalid aggregator\");\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {}\n catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {\n\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);\n }\n\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {\n return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(paymasterAndData.length >= 20, \"AA93 invalid paymasterAndData\");\n mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,\n sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));\n revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);\n }\n revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);\n\n }\n\n function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0) revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);\n if (sender1 == address(0)) revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender) revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0) revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0 : 20]));\n emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(UserOperation calldata userOp) internal view {\n // solhint-disable-next-line no-empty-blocks\n try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}\n catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0 : 20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)\n internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;\n }\n try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA23 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)\n internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(verificationGasLimit > gasUsedByValidateAccountPrepayment, \"AA41 too little verificationGas\");\n uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA33 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)\n private returns (uint256 validationData, uint256 paymasterValidationData) {\n\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |\n userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);\n (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}\n catch Error(string memory reason) {\n revert FailedOp(opIndex, string.concat(\"AA50 postOp reverted: \", reason));\n }\n catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {\n assembly {offset := data}\n }\n\n function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {\n assembly {data := offset}\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {mstore(0, number())}\n }\n}\n\n"
+ },
+ "contracts/core/Helpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\n struct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n }\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n// intersect account and paymaster ranges.\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(validationData);\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n }\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n }\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\n function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n }\n\n"
+ },
+ "contracts/core/NonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(address sender, uint192 key)\n public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(address sender, uint256 nonce) internal returns (bool) {\n\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n\n}\n"
+ },
+ "contracts/core/SenderCreator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(bytes calldata initCode) external returns (address sender) {\n address factory = address(bytes20(initCode[0 : 20]));\n bytes memory initCallData = initCode[20 :];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n"
+ },
+ "contracts/core/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(address account) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(unstakeDelaySec >= info.unstakeDelaySec, \"cannot decrease unstake time\");\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(info.withdrawTime <= block.timestamp, \"Stake withdrawal is not due\");\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success,) = withdrawAddress.call{value : stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success,) = withdrawAddress.call{value : withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n"
+ },
+ "contracts/interfaces/IAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external returns (uint256 validationData);\n}\n"
+ },
+ "contracts/interfaces/IAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\n}\n"
+ },
+ "contracts/interfaces/IEntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo);\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n\n"
+ },
+ "contracts/interfaces/INonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(address sender, uint192 key)\n external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n"
+ },
+ "contracts/interfaces/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;\n}\n"
+ },
+ "contracts/interfaces/IStakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n\n event Deposited(\n address indexed account,\n uint256 totalDeposit\n );\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(\n address indexed account,\n uint256 withdrawTime\n );\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
+ },
+ "contracts/interfaces/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n }\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {data := calldataload(userOp)}\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return abi.encode(\n sender, nonce,\n hashInitCode, hashCallData,\n callGasLimit, verificationGasLimit, preVerificationGas,\n maxFeePerGas, maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/utils/Exec.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {\n bool success = call(to,0,data,gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 1000000
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/solcInputs/cfbebdf1101dd2bc0f310cb0b7d62cb7.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/solcInputs/cfbebdf1101dd2bc0f310cb0b7d62cb7.json
new file mode 100644
index 00000000..dd27f82c
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/mainnet/solcInputs/cfbebdf1101dd2bc0f310cb0b7d62cb7.json
@@ -0,0 +1,59 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/core/EntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\n\ncontract EntryPoint is IEntryPoint, StakeManager {\n\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success,) = beneficiary.call{value : amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) public {\n\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));\n }\n\n uint256 collected = 0;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public {\n\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(address(aggregator) != address(1), \"AA96 invalid aggregator\");\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {}\n catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {\n\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);\n }\n\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {\n return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(paymasterAndData.length >= 20, \"AA93 invalid paymasterAndData\");\n mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,\n sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));\n revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);\n }\n revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);\n\n }\n\n function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0) revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);\n if (sender1 == address(0)) revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender) revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0) revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0 : 20]));\n emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n revert SenderAddressResult(senderCreator.createSender(initCode));\n }\n\n function _simulationOnlyValidations(UserOperation calldata userOp) internal view {\n // solhint-disable-next-line no-empty-blocks\n try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}\n catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0 : 20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)\n internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;\n }\n try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA23 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)\n internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(verificationGasLimit > gasUsedByValidateAccountPrepayment, \"AA41 too little verificationGas\");\n uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA33 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)\n private returns (uint256 validationData, uint256 paymasterValidationData) {\n\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |\n userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);\n (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}\n catch Error(string memory reason) {\n revert FailedOp(opIndex, string.concat(\"AA50 postOp reverted: \", reason));\n }\n catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {\n assembly {offset := data}\n }\n\n function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {\n assembly {data := offset}\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {mstore(0, number())}\n }\n}\n\n"
+ },
+ "contracts/core/Helpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\n struct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n }\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n// intersect account and paymaster ranges.\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(validationData);\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n }\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n }\n"
+ },
+ "contracts/core/SenderCreator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(bytes calldata initCode) external returns (address sender) {\n address factory = address(bytes20(initCode[0 : 20]));\n bytes memory initCallData = initCode[20 :];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n"
+ },
+ "contracts/core/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(address account) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(unstakeDelaySec >= info.unstakeDelaySec, \"cannot decrease unstake time\");\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(info.withdrawTime <= block.timestamp, \"Stake withdrawal is not due\");\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success,) = withdrawAddress.call{value : stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success,) = withdrawAddress.call{value : withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n"
+ },
+ "contracts/interfaces/IAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external returns (uint256 validationData);\n}\n"
+ },
+ "contracts/interfaces/IAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\n}\n"
+ },
+ "contracts/interfaces/IEntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\n\ninterface IEntryPoint is IStakeManager {\n\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo);\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n\n"
+ },
+ "contracts/interfaces/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;\n}\n"
+ },
+ "contracts/interfaces/IStakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n\n event Deposited(\n address indexed account,\n uint256 totalDeposit\n );\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(\n address indexed account,\n uint256 withdrawTime\n );\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
+ },
+ "contracts/interfaces/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\n /**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n }\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {data := calldataload(userOp)}\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n //lighter signature scheme. must match UserOp.ts#packUserOp\n bytes calldata sig = userOp.signature;\n // copy directly the userOp from calldata up to (but not including) the signature.\n // this encoding depends on the ABI encoding of calldata, but is much lighter to copy\n // than referencing each field separately.\n assembly {\n let ofs := userOp\n let len := sub(sub(sig.offset, ofs), 32)\n ret := mload(0x40)\n mstore(0x40, add(ret, add(len, 32)))\n mstore(ret, len)\n calldatacopy(add(ret, 32), ofs, len)\n }\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/utils/Exec.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {\n bool success = call(to,0,data,gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 1000000
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/.chainId b/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/.chainId
new file mode 100644
index 00000000..065fd3e7
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/.chainId
@@ -0,0 +1 @@
+137
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/EntryPoint.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/EntryPoint.json
new file mode 100644
index 00000000..037750fb
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/EntryPoint.json
@@ -0,0 +1,1318 @@
+{
+ "address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "paid",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bool",
+ "name": "targetSuccess",
+ "type": "bool"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetResult",
+ "type": "bytes"
+ }
+ ],
+ "name": "ExecutionResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "opIndex",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "reason",
+ "type": "string"
+ }
+ ],
+ "name": "FailedOp",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "SenderAddressResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureValidationFailed",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "stakeInfo",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IEntryPoint.AggregatorStakeInfo",
+ "name": "aggregatorInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResultWithAggregation",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "factory",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ }
+ ],
+ "name": "AccountDeployed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "BeforeExecution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalDeposit",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposited",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureAggregatorChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalStaked",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeLocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "withdrawTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeUnlocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeWithdrawn",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "success",
+ "type": "bool"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasUsed",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserOperationEvent",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "revertReason",
+ "type": "bytes"
+ }
+ ],
+ "name": "UserOperationRevertReason",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawn",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "SIG_VALIDATION_FAILED",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ }
+ ],
+ "name": "_validateSenderAndPaymaster",
+ "outputs": [],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ }
+ ],
+ "name": "addStake",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deposits",
+ "outputs": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "getDepositInfo",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "internalType": "struct IStakeManager.DepositInfo",
+ "name": "info",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "getNonce",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ }
+ ],
+ "name": "getSenderAddress",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "getUserOpHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "userOps",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "contract IAggregator",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.UserOpsPerAggregator[]",
+ "name": "opsPerAggregator",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleAggregatedOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "ops",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "incrementNonce",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.MemoryUserOp",
+ "name": "mUserOp",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "contextOffset",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.UserOpInfo",
+ "name": "opInfo",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes",
+ "name": "context",
+ "type": "bytes"
+ }
+ ],
+ "name": "innerHandleOp",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "",
+ "type": "uint192"
+ }
+ ],
+ "name": "nonceSequenceNumber",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "op",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetCallData",
+ "type": "bytes"
+ }
+ ],
+ "name": "simulateHandleOp",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "simulateValidation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unlockStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ }
+ ],
+ "name": "withdrawStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "withdrawAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdrawTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "args": [],
+ "numDeployments": 2,
+ "solcInputHash": "a4c52f0671aad8941c53d6ead2063803",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"targetSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"targetResult\",\"type\":\"bytes\"}],\"name\":\"ExecutionResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"opIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"FailedOp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderAddressResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureValidationFailed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResult\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"type\":\"tuple\"}],\"internalType\":\"struct IEntryPoint.AggregatorStakeInfo\",\"name\":\"aggregatorInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResultWithAggregation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"}],\"name\":\"AccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"BeforeExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalDeposit\",\"type\":\"uint256\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureAggregatorChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStaked\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"name\":\"StakeLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"StakeWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasUsed\",\"type\":\"uint256\"}],\"name\":\"UserOperationEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"revertReason\",\"type\":\"bytes\"}],\"name\":\"UserOperationRevertReason\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SIG_VALIDATION_FAILED\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"}],\"name\":\"_validateSenderAndPaymaster\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"}],\"name\":\"addStake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getDepositInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"internalType\":\"struct IStakeManager.DepositInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"getSenderAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"getUserOpHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"userOps\",\"type\":\"tuple[]\"},{\"internalType\":\"contract IAggregator\",\"name\":\"aggregator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.UserOpsPerAggregator[]\",\"name\":\"opsPerAggregator\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleAggregatedOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"incrementNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.MemoryUserOp\",\"name\":\"mUserOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contextOffset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.UserOpInfo\",\"name\":\"opInfo\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"name\":\"innerHandleOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"name\":\"nonceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCallData\",\"type\":\"bytes\"}],\"name\":\"simulateHandleOp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"simulateValidation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"}],\"name\":\"withdrawStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"withdrawAmount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"FailedOp(uint256,string)\":[{\"params\":{\"opIndex\":\"- index into the array of ops to the failed one (in simulateValidation, this is always zero)\",\"reason\":\"- revert reason The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues, so a failure can be attributed to the correct entity. Should be caught in off-chain handleOps simulation and not happen on-chain. Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\"}}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"params\":{\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"params\":{\"aggregatorInfo\":\"signature aggregation info (if the account requires signature aggregator) bundler MUST use it to verify the signature, or reject the UserOperation\",\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}]},\"kind\":\"dev\",\"methods\":{\"addStake(uint32)\":{\"params\":{\"unstakeDelaySec\":\"the new lock duration before the deposit can be withdrawn.\"}},\"getDepositInfo(address)\":{\"returns\":{\"info\":\"- full deposit information of given account\"}},\"getNonce(address,uint192)\":{\"params\":{\"key\":\"the high 192 bit of the nonce\",\"sender\":\"the account address\"},\"returns\":{\"nonce\":\"a full nonce to pass for next UserOp with this sender.\"}},\"getSenderAddress(bytes)\":{\"params\":{\"initCode\":\"the constructor code to be passed into the UserOperation.\"}},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"opsPerAggregator\":\"the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\"}},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"ops\":\"the operations to execute\"}},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"params\":{\"op\":\"the UserOperation to simulate\",\"target\":\"if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult are set to the return from that call.\",\"targetCallData\":\"callData to pass to target address\"}},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"details\":\"this method always revert. Successful result is ValidationResult error. other errors are failures.The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\",\"params\":{\"userOp\":\"the user operation to validate.\"}},\"withdrawStake(address)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\"}},\"withdrawTo(address,uint256)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\",\"withdrawAmount\":\"the amount to withdraw.\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"ExecutionResult(uint256,uint256,uint48,uint48,bool,bytes)\":[{\"notice\":\"return value of simulateHandleOp\"}],\"FailedOp(uint256,string)\":[{\"notice\":\"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.\"}],\"SenderAddressResult(address)\":[{\"notice\":\"return value of getSenderAddress\"}],\"SignatureValidationFailed(address)\":[{\"notice\":\"error case when a signature aggregator fails to verify the aggregated signature it had created.\"}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"notice\":\"Successful result from simulateValidation.\"}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"notice\":\"Successful result from simulateValidation, if the account returns a signature aggregator\"}]},\"events\":{\"AccountDeployed(bytes32,address,address,address)\":{\"notice\":\"account \\\"sender\\\" was deployed.\"},\"BeforeExecution()\":{\"notice\":\"an event emitted by handleOps(), before starting the execution loop. any event emitted before this event, is part of the validation.\"},\"SignatureAggregatorChanged(address)\":{\"notice\":\"signature aggregator used by the following UserOperationEvents within this bundle.\"},\"StakeLocked(address,uint256,uint256)\":{\"notice\":\"Emitted when stake or unstake delay are modified\"},\"StakeUnlocked(address,uint256)\":{\"notice\":\"Emitted once a stake is scheduled for withdrawal\"},\"UserOperationRevertReason(bytes32,address,uint256,bytes)\":{\"notice\":\"An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\"}},\"kind\":\"user\",\"methods\":{\"SIG_VALIDATION_FAILED()\":{\"notice\":\"for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value in case of signature failure, instead of revert.\"},\"_validateSenderAndPaymaster(bytes,address,bytes)\":{\"notice\":\"Called only during simulation. This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\"},\"addStake(uint32)\":{\"notice\":\"add to the account's stake - amount and delay any pending unstake is first cancelled.\"},\"balanceOf(address)\":{\"notice\":\"return the deposit (for gas payment) of the account\"},\"depositTo(address)\":{\"notice\":\"add to the deposit of the given account\"},\"deposits(address)\":{\"notice\":\"maps paymaster to their deposits and stakes\"},\"getNonce(address,uint192)\":{\"notice\":\"Return the next nonce for this sender. Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) But UserOp with different keys can come with arbitrary order.\"},\"getSenderAddress(bytes)\":{\"notice\":\"Get counterfactual sender address. Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. this method always revert, and returns the address in SenderAddressResult error\"},\"getUserOpHash((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"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.\"},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperation with Aggregators\"},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperations. no signature aggregator is used. if any account requires an aggregator (that is, it returned an aggregator when performing simulateValidation), then handleAggregatedOps() must be used instead.\"},\"incrementNonce(uint192)\":{\"notice\":\"Manually increment the nonce of the sender. This method is exposed just for completeness.. Account does NOT need to call it, neither during validation, nor elsewhere, as the EntryPoint will update the nonce regardless. Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future UserOperations will not pay extra for the first transaction with a given key.\"},\"innerHandleOp(bytes,((address,uint256,uint256,uint256,uint256,address,uint256,uint256),bytes32,uint256,uint256,uint256),bytes)\":{\"notice\":\"inner function to handle a UserOperation. Must be declared \\\"external\\\" to open a call context, but it can only be called by handleOps.\"},\"nonceSequenceNumber(address,uint192)\":{\"notice\":\"The next valid sequence number for a given nonce key.\"},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"notice\":\"simulate full execution of a UserOperation (including both validation and target execution) this method will always revert with \\\"ExecutionResult\\\". it performs full validation of the UserOperation, but ignores signature error. an optional target address is called after the userop succeeds, and its value is returned (before the entire call is reverted) Note that in order to collect the the success/failure of the target call, it must be executed with trace enabled to track the emitted events.\"},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\"},\"unlockStake()\":{\"notice\":\"attempt to unlock the stake. the value can be withdrawn (using withdrawStake) after the unstake delay.\"},\"withdrawStake(address)\":{\"notice\":\"withdraw from the (unlocked) stake. must first call unlockStake and wait for the unstakeDelay to pass\"},\"withdrawTo(address,uint256)\":{\"notice\":\"withdraw from the deposit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/core/EntryPoint.sol\":\"EntryPoint\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0x190dd6f8d592b7e4e930feb7f4313aeb8e1c4ad3154c27ce1cf6a512fc30d8cc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ce8dfb62d0c4fa260d6eec8f1cd47f5f2a044e11bde5b31d18072fa6e7d9010\",\"dweb:/ipfs/QmTyFztU3tLEcEDnqqiaW4UJetqsU77LXc6pjc9oTXCK5u\"]},\"contracts/core/EntryPoint.sol\":{\"keccak256\":\"0x04f86318b47f052d7308795ffae6ecec0d023d2458b4e17751b89a0e4acfcdc6\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://c9f6e359c8dbe875ad974d3a0fb7b3d62319a6b115c44bac1e4587ae2ad2edaf\",\"dweb:/ipfs/QmTSWTov2rUeYk8cwzrtsd3uVXokCYok4gMiZ1sPs9tycH\"]},\"contracts/core/Helpers.sol\":{\"keccak256\":\"0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746\",\"dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU\"]},\"contracts/core/NonceManager.sol\":{\"keccak256\":\"0xa17a4a6fde70088ab18ffe6df830f3efa31f1cd0e1a7160336c96e3c94984d25\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://b38615df9f80c56282b72888e9ba1eb1a9413fa67a0dbf094deda7af9feb38e7\",\"dweb:/ipfs/QmSzcXetEJRH4UHuUmZiSgX6bFgfqHWfmyuxVnh4NosMk1\"]},\"contracts/core/SenderCreator.sol\":{\"keccak256\":\"0x44b9449fec82d6cdfb01d52fdd5a72f90099c651316123810cf9633f00b018c2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a9c0487390e72638681d175c45bc92425c802fffdca4bd0ae8457782ee284612\",\"dweb:/ipfs/QmVbzuehCUWJWqEHyMWuc6cRVbxfcMdFsmGL9o4Wz7WY2x\"]},\"contracts/core/StakeManager.sol\":{\"keccak256\":\"0x21aa0956382bd000b1b8c3b1d19ca6ebcd6c9029eebb19c612fb38ee5dd2430a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0a625c8795354d9f429367f9c1d14eb8af7db9c7f2c2a2033e2066ced76a573a\",\"dweb:/ipfs/Qmd1j6UarUg54q1G2HCNCLQz8XGVZR1qxX7eQ6cytHpQPN\"]},\"contracts/interfaces/IAccount.sol\":{\"keccak256\":\"0x556a0e5980de18e90b115553ed502408155ba35f58642823010d9288047bc418\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a0f420134b79596db8737173c7b933ae0a33059e107b6327c43aa40d4744a9e4\",\"dweb:/ipfs/QmRo8s1AhXmEMV7uPYnbpYwU19e9Bk6jmYBJTiPx3Fo85W\"]},\"contracts/interfaces/IAggregator.sol\":{\"keccak256\":\"0x060e9ddb0152250c269ba0640dc5753834ac44cf182a2837d508c0c529cae26a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://20ed837bc5909c89ff1910246bf245a5dad6840aa939382e1694964eb7dbd37b\",\"dweb:/ipfs/QmTMybRq5yyghPDDs1ZCNAVB9sSJ4WHe6Q9mejuKPTAdNP\"]},\"contracts/interfaces/IEntryPoint.sol\":{\"keccak256\":\"0x3a90bf308819ed125fa4202f880999caff8a8686633b8ddb79a30ca240d5b8f8\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://d2d21cc92c2fdab2b58d21bc25d4cd0e8c284b922528a186b087b818d54bc6cf\",\"dweb:/ipfs/QmT1qrfuBjsv2rmRCDn8mgPXHp94hARJwzbcDuBLDTbFWd\"]},\"contracts/interfaces/INonceManager.sol\":{\"keccak256\":\"0x509871e6c63663cdcc3eba19920fe84e991f38b289b1377ac3c3a6d9f22d7e12\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://00fe21b4349b24c50df60e1a705179293982bd9e7a32b78d4bac9620f89e7fe2\",\"dweb:/ipfs/QmSFFYGfUwQbVa6hASjU7YxTvgi2HkfrPr4X5oPHscHg8b\"]},\"contracts/interfaces/IPaymaster.sol\":{\"keccak256\":\"0x36858ba8685024974f533530420688da3454d29996ebc42e410673a1ed2ec456\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://616cbcf51778b1961b7f20a547bec7efae6d1d565df0f651926241ed8bde9ad8\",\"dweb:/ipfs/QmaVsgffUUmeUJYgStvRr8cNZ1LBbrc3FYNLW4JT1dVLia\"]},\"contracts/interfaces/IStakeManager.sol\":{\"keccak256\":\"0xd227b02888cd4ac68daebcdfd992ec00f9fff66fa3b3bb16f656cd582fa3480f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://b389da4714a138be63704a576a482505eab2855e263b38a93706395d8d42e7c3\",\"dweb:/ipfs/QmeeAZpdHwUXxqP8pxA7GNtoCGBmmH4FaqLLwScVKGxtxZ\"]},\"contracts/interfaces/UserOperation.sol\":{\"keccak256\":\"0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c\",\"dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN\"]},\"contracts/utils/Exec.sol\":{\"keccak256\":\"0x5b232117afbc2939f3ffc92745614867e9e1d475a3e1e5443adae13c200174f1\",\"license\":\"LGPL-3.0-only\",\"urls\":[\"bzz-raw://62e7365379a06ead7b47637945bcaee095d51aab1d3ac00ddec69443e6cbe9fe\",\"dweb:/ipfs/QmctG3aw4U3KMSMeJKoLJ1NJewjMWfppnd1m3kxNTe39Uy\"]}},\"version\":1}",
+ "bytecode": "0x60a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033",
+ "deployedBytecode": "0x60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c63430008110033"
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/solcInputs/a4c52f0671aad8941c53d6ead2063803.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
new file mode 100644
index 00000000..dd58ba5a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
@@ -0,0 +1,68 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts/security/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n"
+ },
+ "contracts/core/EntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard {\n\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success,) = beneficiary.call{value : amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) public nonReentrant {\n\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(address(aggregator) != address(1), \"AA96 invalid aggregator\");\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {}\n catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {\n\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);\n }\n\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {\n return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(paymasterAndData.length >= 20, \"AA93 invalid paymasterAndData\");\n mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,\n sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));\n revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);\n }\n revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);\n\n }\n\n function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0) revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);\n if (sender1 == address(0)) revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender) revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0) revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0 : 20]));\n emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(UserOperation calldata userOp) internal view {\n // solhint-disable-next-line no-empty-blocks\n try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}\n catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0 : 20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)\n internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;\n }\n try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA23 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)\n internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(verificationGasLimit > gasUsedByValidateAccountPrepayment, \"AA41 too little verificationGas\");\n uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA33 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)\n private returns (uint256 validationData, uint256 paymasterValidationData) {\n\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |\n userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);\n (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}\n catch Error(string memory reason) {\n revert FailedOp(opIndex, string.concat(\"AA50 postOp reverted: \", reason));\n }\n catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {\n assembly {offset := data}\n }\n\n function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {\n assembly {data := offset}\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {mstore(0, number())}\n }\n}\n\n"
+ },
+ "contracts/core/Helpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\n struct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n }\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n// intersect account and paymaster ranges.\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(validationData);\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n }\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n }\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\n function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n }\n\n"
+ },
+ "contracts/core/NonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(address sender, uint192 key)\n public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(address sender, uint256 nonce) internal returns (bool) {\n\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n\n}\n"
+ },
+ "contracts/core/SenderCreator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(bytes calldata initCode) external returns (address sender) {\n address factory = address(bytes20(initCode[0 : 20]));\n bytes memory initCallData = initCode[20 :];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n"
+ },
+ "contracts/core/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(address account) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(unstakeDelaySec >= info.unstakeDelaySec, \"cannot decrease unstake time\");\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(info.withdrawTime <= block.timestamp, \"Stake withdrawal is not due\");\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success,) = withdrawAddress.call{value : stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success,) = withdrawAddress.call{value : withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n"
+ },
+ "contracts/interfaces/IAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external returns (uint256 validationData);\n}\n"
+ },
+ "contracts/interfaces/IAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\n}\n"
+ },
+ "contracts/interfaces/IEntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo);\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n\n"
+ },
+ "contracts/interfaces/INonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(address sender, uint192 key)\n external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n"
+ },
+ "contracts/interfaces/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;\n}\n"
+ },
+ "contracts/interfaces/IStakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n\n event Deposited(\n address indexed account,\n uint256 totalDeposit\n );\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(\n address indexed account,\n uint256 withdrawTime\n );\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
+ },
+ "contracts/interfaces/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n }\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {data := calldataload(userOp)}\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return abi.encode(\n sender, nonce,\n hashInitCode, hashCallData,\n callGasLimit, verificationGasLimit, preVerificationGas,\n maxFeePerGas, maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/utils/Exec.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {\n bool success = call(to,0,data,gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 1000000
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/solcInputs/cfbebdf1101dd2bc0f310cb0b7d62cb7.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/solcInputs/cfbebdf1101dd2bc0f310cb0b7d62cb7.json
new file mode 100644
index 00000000..dd27f82c
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/matic/solcInputs/cfbebdf1101dd2bc0f310cb0b7d62cb7.json
@@ -0,0 +1,59 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "contracts/core/EntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\n\ncontract EntryPoint is IEntryPoint, StakeManager {\n\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success,) = beneficiary.call{value : amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) public {\n\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));\n }\n\n uint256 collected = 0;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public {\n\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(address(aggregator) != address(1), \"AA96 invalid aggregator\");\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {}\n catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {\n\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);\n }\n\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {\n return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(paymasterAndData.length >= 20, \"AA93 invalid paymasterAndData\");\n mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,\n sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));\n revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);\n }\n revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);\n\n }\n\n function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0) revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);\n if (sender1 == address(0)) revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender) revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0) revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0 : 20]));\n emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n revert SenderAddressResult(senderCreator.createSender(initCode));\n }\n\n function _simulationOnlyValidations(UserOperation calldata userOp) internal view {\n // solhint-disable-next-line no-empty-blocks\n try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}\n catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0 : 20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)\n internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;\n }\n try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA23 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)\n internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(verificationGasLimit > gasUsedByValidateAccountPrepayment, \"AA41 too little verificationGas\");\n uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA33 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)\n private returns (uint256 validationData, uint256 paymasterValidationData) {\n\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |\n userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);\n (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}\n catch Error(string memory reason) {\n revert FailedOp(opIndex, string.concat(\"AA50 postOp reverted: \", reason));\n }\n catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {\n assembly {offset := data}\n }\n\n function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {\n assembly {data := offset}\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {mstore(0, number())}\n }\n}\n\n"
+ },
+ "contracts/core/Helpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\n struct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n }\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n// intersect account and paymaster ranges.\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(validationData);\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n }\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n }\n"
+ },
+ "contracts/core/SenderCreator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(bytes calldata initCode) external returns (address sender) {\n address factory = address(bytes20(initCode[0 : 20]));\n bytes memory initCallData = initCode[20 :];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n"
+ },
+ "contracts/core/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(address account) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(unstakeDelaySec >= info.unstakeDelaySec, \"cannot decrease unstake time\");\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(info.withdrawTime <= block.timestamp, \"Stake withdrawal is not due\");\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success,) = withdrawAddress.call{value : stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success,) = withdrawAddress.call{value : withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n"
+ },
+ "contracts/interfaces/IAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external returns (uint256 validationData);\n}\n"
+ },
+ "contracts/interfaces/IAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\n}\n"
+ },
+ "contracts/interfaces/IEntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\n\ninterface IEntryPoint is IStakeManager {\n\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo);\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n\n"
+ },
+ "contracts/interfaces/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;\n}\n"
+ },
+ "contracts/interfaces/IStakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n\n event Deposited(\n address indexed account,\n uint256 totalDeposit\n );\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(\n address indexed account,\n uint256 withdrawTime\n );\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
+ },
+ "contracts/interfaces/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\n /**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n }\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {data := calldataload(userOp)}\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n //lighter signature scheme. must match UserOp.ts#packUserOp\n bytes calldata sig = userOp.signature;\n // copy directly the userOp from calldata up to (but not including) the signature.\n // this encoding depends on the ABI encoding of calldata, but is much lighter to copy\n // than referencing each field separately.\n assembly {\n let ofs := userOp\n let len := sub(sub(sig.offset, ofs), 32)\n ret := mload(0x40)\n mstore(0x40, add(ret, add(len, 32)))\n mstore(ret, len)\n calldatacopy(add(ret, 32), ofs, len)\n }\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/utils/Exec.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {\n bool success = call(to,0,data,gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 1000000
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/mumbai/.chainId b/lib/SoulWalletCore/lib/account-abstraction/deployments/mumbai/.chainId
new file mode 100644
index 00000000..d7e2f72c
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/mumbai/.chainId
@@ -0,0 +1 @@
+80001
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/mumbai/EntryPoint.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/mumbai/EntryPoint.json
new file mode 100644
index 00000000..916c2390
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/mumbai/EntryPoint.json
@@ -0,0 +1,1318 @@
+{
+ "address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "paid",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bool",
+ "name": "targetSuccess",
+ "type": "bool"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetResult",
+ "type": "bytes"
+ }
+ ],
+ "name": "ExecutionResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "opIndex",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "reason",
+ "type": "string"
+ }
+ ],
+ "name": "FailedOp",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "SenderAddressResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureValidationFailed",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "stakeInfo",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IEntryPoint.AggregatorStakeInfo",
+ "name": "aggregatorInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResultWithAggregation",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "factory",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ }
+ ],
+ "name": "AccountDeployed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "BeforeExecution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalDeposit",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposited",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureAggregatorChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalStaked",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeLocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "withdrawTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeUnlocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeWithdrawn",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "success",
+ "type": "bool"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasUsed",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserOperationEvent",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "revertReason",
+ "type": "bytes"
+ }
+ ],
+ "name": "UserOperationRevertReason",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawn",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "SIG_VALIDATION_FAILED",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ }
+ ],
+ "name": "_validateSenderAndPaymaster",
+ "outputs": [],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ }
+ ],
+ "name": "addStake",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deposits",
+ "outputs": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "getDepositInfo",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "internalType": "struct IStakeManager.DepositInfo",
+ "name": "info",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "getNonce",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ }
+ ],
+ "name": "getSenderAddress",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "getUserOpHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "userOps",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "contract IAggregator",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.UserOpsPerAggregator[]",
+ "name": "opsPerAggregator",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleAggregatedOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "ops",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "incrementNonce",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.MemoryUserOp",
+ "name": "mUserOp",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "contextOffset",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.UserOpInfo",
+ "name": "opInfo",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes",
+ "name": "context",
+ "type": "bytes"
+ }
+ ],
+ "name": "innerHandleOp",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "",
+ "type": "uint192"
+ }
+ ],
+ "name": "nonceSequenceNumber",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "op",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetCallData",
+ "type": "bytes"
+ }
+ ],
+ "name": "simulateHandleOp",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "simulateValidation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unlockStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ }
+ ],
+ "name": "withdrawStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "withdrawAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdrawTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "args": [],
+ "numDeployments": 1,
+ "solcInputHash": "a4c52f0671aad8941c53d6ead2063803",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"targetSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"targetResult\",\"type\":\"bytes\"}],\"name\":\"ExecutionResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"opIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"FailedOp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderAddressResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureValidationFailed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResult\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"type\":\"tuple\"}],\"internalType\":\"struct IEntryPoint.AggregatorStakeInfo\",\"name\":\"aggregatorInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResultWithAggregation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"}],\"name\":\"AccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"BeforeExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalDeposit\",\"type\":\"uint256\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureAggregatorChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStaked\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"name\":\"StakeLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"StakeWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasUsed\",\"type\":\"uint256\"}],\"name\":\"UserOperationEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"revertReason\",\"type\":\"bytes\"}],\"name\":\"UserOperationRevertReason\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SIG_VALIDATION_FAILED\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"}],\"name\":\"_validateSenderAndPaymaster\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"}],\"name\":\"addStake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getDepositInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"internalType\":\"struct IStakeManager.DepositInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"getSenderAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"getUserOpHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"userOps\",\"type\":\"tuple[]\"},{\"internalType\":\"contract IAggregator\",\"name\":\"aggregator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.UserOpsPerAggregator[]\",\"name\":\"opsPerAggregator\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleAggregatedOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"incrementNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.MemoryUserOp\",\"name\":\"mUserOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contextOffset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.UserOpInfo\",\"name\":\"opInfo\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"name\":\"innerHandleOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"name\":\"nonceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCallData\",\"type\":\"bytes\"}],\"name\":\"simulateHandleOp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"simulateValidation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"}],\"name\":\"withdrawStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"withdrawAmount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"FailedOp(uint256,string)\":[{\"params\":{\"opIndex\":\"- index into the array of ops to the failed one (in simulateValidation, this is always zero)\",\"reason\":\"- revert reason The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues, so a failure can be attributed to the correct entity. Should be caught in off-chain handleOps simulation and not happen on-chain. Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\"}}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"params\":{\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"params\":{\"aggregatorInfo\":\"signature aggregation info (if the account requires signature aggregator) bundler MUST use it to verify the signature, or reject the UserOperation\",\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}]},\"kind\":\"dev\",\"methods\":{\"addStake(uint32)\":{\"params\":{\"unstakeDelaySec\":\"the new lock duration before the deposit can be withdrawn.\"}},\"getDepositInfo(address)\":{\"returns\":{\"info\":\"- full deposit information of given account\"}},\"getNonce(address,uint192)\":{\"params\":{\"key\":\"the high 192 bit of the nonce\",\"sender\":\"the account address\"},\"returns\":{\"nonce\":\"a full nonce to pass for next UserOp with this sender.\"}},\"getSenderAddress(bytes)\":{\"params\":{\"initCode\":\"the constructor code to be passed into the UserOperation.\"}},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"opsPerAggregator\":\"the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\"}},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"ops\":\"the operations to execute\"}},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"params\":{\"op\":\"the UserOperation to simulate\",\"target\":\"if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult are set to the return from that call.\",\"targetCallData\":\"callData to pass to target address\"}},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"details\":\"this method always revert. Successful result is ValidationResult error. other errors are failures.The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\",\"params\":{\"userOp\":\"the user operation to validate.\"}},\"withdrawStake(address)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\"}},\"withdrawTo(address,uint256)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\",\"withdrawAmount\":\"the amount to withdraw.\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"ExecutionResult(uint256,uint256,uint48,uint48,bool,bytes)\":[{\"notice\":\"return value of simulateHandleOp\"}],\"FailedOp(uint256,string)\":[{\"notice\":\"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.\"}],\"SenderAddressResult(address)\":[{\"notice\":\"return value of getSenderAddress\"}],\"SignatureValidationFailed(address)\":[{\"notice\":\"error case when a signature aggregator fails to verify the aggregated signature it had created.\"}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"notice\":\"Successful result from simulateValidation.\"}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"notice\":\"Successful result from simulateValidation, if the account returns a signature aggregator\"}]},\"events\":{\"AccountDeployed(bytes32,address,address,address)\":{\"notice\":\"account \\\"sender\\\" was deployed.\"},\"BeforeExecution()\":{\"notice\":\"an event emitted by handleOps(), before starting the execution loop. any event emitted before this event, is part of the validation.\"},\"SignatureAggregatorChanged(address)\":{\"notice\":\"signature aggregator used by the following UserOperationEvents within this bundle.\"},\"StakeLocked(address,uint256,uint256)\":{\"notice\":\"Emitted when stake or unstake delay are modified\"},\"StakeUnlocked(address,uint256)\":{\"notice\":\"Emitted once a stake is scheduled for withdrawal\"},\"UserOperationRevertReason(bytes32,address,uint256,bytes)\":{\"notice\":\"An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\"}},\"kind\":\"user\",\"methods\":{\"SIG_VALIDATION_FAILED()\":{\"notice\":\"for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value in case of signature failure, instead of revert.\"},\"_validateSenderAndPaymaster(bytes,address,bytes)\":{\"notice\":\"Called only during simulation. This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\"},\"addStake(uint32)\":{\"notice\":\"add to the account's stake - amount and delay any pending unstake is first cancelled.\"},\"balanceOf(address)\":{\"notice\":\"return the deposit (for gas payment) of the account\"},\"depositTo(address)\":{\"notice\":\"add to the deposit of the given account\"},\"deposits(address)\":{\"notice\":\"maps paymaster to their deposits and stakes\"},\"getNonce(address,uint192)\":{\"notice\":\"Return the next nonce for this sender. Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) But UserOp with different keys can come with arbitrary order.\"},\"getSenderAddress(bytes)\":{\"notice\":\"Get counterfactual sender address. Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. this method always revert, and returns the address in SenderAddressResult error\"},\"getUserOpHash((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"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.\"},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperation with Aggregators\"},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperations. no signature aggregator is used. if any account requires an aggregator (that is, it returned an aggregator when performing simulateValidation), then handleAggregatedOps() must be used instead.\"},\"incrementNonce(uint192)\":{\"notice\":\"Manually increment the nonce of the sender. This method is exposed just for completeness.. Account does NOT need to call it, neither during validation, nor elsewhere, as the EntryPoint will update the nonce regardless. Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future UserOperations will not pay extra for the first transaction with a given key.\"},\"innerHandleOp(bytes,((address,uint256,uint256,uint256,uint256,address,uint256,uint256),bytes32,uint256,uint256,uint256),bytes)\":{\"notice\":\"inner function to handle a UserOperation. Must be declared \\\"external\\\" to open a call context, but it can only be called by handleOps.\"},\"nonceSequenceNumber(address,uint192)\":{\"notice\":\"The next valid sequence number for a given nonce key.\"},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"notice\":\"simulate full execution of a UserOperation (including both validation and target execution) this method will always revert with \\\"ExecutionResult\\\". it performs full validation of the UserOperation, but ignores signature error. an optional target address is called after the userop succeeds, and its value is returned (before the entire call is reverted) Note that in order to collect the the success/failure of the target call, it must be executed with trace enabled to track the emitted events.\"},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\"},\"unlockStake()\":{\"notice\":\"attempt to unlock the stake. the value can be withdrawn (using withdrawStake) after the unstake delay.\"},\"withdrawStake(address)\":{\"notice\":\"withdraw from the (unlocked) stake. must first call unlockStake and wait for the unstakeDelay to pass\"},\"withdrawTo(address,uint256)\":{\"notice\":\"withdraw from the deposit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/core/EntryPoint.sol\":\"EntryPoint\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0x190dd6f8d592b7e4e930feb7f4313aeb8e1c4ad3154c27ce1cf6a512fc30d8cc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ce8dfb62d0c4fa260d6eec8f1cd47f5f2a044e11bde5b31d18072fa6e7d9010\",\"dweb:/ipfs/QmTyFztU3tLEcEDnqqiaW4UJetqsU77LXc6pjc9oTXCK5u\"]},\"contracts/core/EntryPoint.sol\":{\"keccak256\":\"0x04f86318b47f052d7308795ffae6ecec0d023d2458b4e17751b89a0e4acfcdc6\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://c9f6e359c8dbe875ad974d3a0fb7b3d62319a6b115c44bac1e4587ae2ad2edaf\",\"dweb:/ipfs/QmTSWTov2rUeYk8cwzrtsd3uVXokCYok4gMiZ1sPs9tycH\"]},\"contracts/core/Helpers.sol\":{\"keccak256\":\"0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746\",\"dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU\"]},\"contracts/core/NonceManager.sol\":{\"keccak256\":\"0xa17a4a6fde70088ab18ffe6df830f3efa31f1cd0e1a7160336c96e3c94984d25\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://b38615df9f80c56282b72888e9ba1eb1a9413fa67a0dbf094deda7af9feb38e7\",\"dweb:/ipfs/QmSzcXetEJRH4UHuUmZiSgX6bFgfqHWfmyuxVnh4NosMk1\"]},\"contracts/core/SenderCreator.sol\":{\"keccak256\":\"0x44b9449fec82d6cdfb01d52fdd5a72f90099c651316123810cf9633f00b018c2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a9c0487390e72638681d175c45bc92425c802fffdca4bd0ae8457782ee284612\",\"dweb:/ipfs/QmVbzuehCUWJWqEHyMWuc6cRVbxfcMdFsmGL9o4Wz7WY2x\"]},\"contracts/core/StakeManager.sol\":{\"keccak256\":\"0x21aa0956382bd000b1b8c3b1d19ca6ebcd6c9029eebb19c612fb38ee5dd2430a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0a625c8795354d9f429367f9c1d14eb8af7db9c7f2c2a2033e2066ced76a573a\",\"dweb:/ipfs/Qmd1j6UarUg54q1G2HCNCLQz8XGVZR1qxX7eQ6cytHpQPN\"]},\"contracts/interfaces/IAccount.sol\":{\"keccak256\":\"0x556a0e5980de18e90b115553ed502408155ba35f58642823010d9288047bc418\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a0f420134b79596db8737173c7b933ae0a33059e107b6327c43aa40d4744a9e4\",\"dweb:/ipfs/QmRo8s1AhXmEMV7uPYnbpYwU19e9Bk6jmYBJTiPx3Fo85W\"]},\"contracts/interfaces/IAggregator.sol\":{\"keccak256\":\"0x060e9ddb0152250c269ba0640dc5753834ac44cf182a2837d508c0c529cae26a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://20ed837bc5909c89ff1910246bf245a5dad6840aa939382e1694964eb7dbd37b\",\"dweb:/ipfs/QmTMybRq5yyghPDDs1ZCNAVB9sSJ4WHe6Q9mejuKPTAdNP\"]},\"contracts/interfaces/IEntryPoint.sol\":{\"keccak256\":\"0x3a90bf308819ed125fa4202f880999caff8a8686633b8ddb79a30ca240d5b8f8\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://d2d21cc92c2fdab2b58d21bc25d4cd0e8c284b922528a186b087b818d54bc6cf\",\"dweb:/ipfs/QmT1qrfuBjsv2rmRCDn8mgPXHp94hARJwzbcDuBLDTbFWd\"]},\"contracts/interfaces/INonceManager.sol\":{\"keccak256\":\"0x509871e6c63663cdcc3eba19920fe84e991f38b289b1377ac3c3a6d9f22d7e12\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://00fe21b4349b24c50df60e1a705179293982bd9e7a32b78d4bac9620f89e7fe2\",\"dweb:/ipfs/QmSFFYGfUwQbVa6hASjU7YxTvgi2HkfrPr4X5oPHscHg8b\"]},\"contracts/interfaces/IPaymaster.sol\":{\"keccak256\":\"0x36858ba8685024974f533530420688da3454d29996ebc42e410673a1ed2ec456\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://616cbcf51778b1961b7f20a547bec7efae6d1d565df0f651926241ed8bde9ad8\",\"dweb:/ipfs/QmaVsgffUUmeUJYgStvRr8cNZ1LBbrc3FYNLW4JT1dVLia\"]},\"contracts/interfaces/IStakeManager.sol\":{\"keccak256\":\"0xd227b02888cd4ac68daebcdfd992ec00f9fff66fa3b3bb16f656cd582fa3480f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://b389da4714a138be63704a576a482505eab2855e263b38a93706395d8d42e7c3\",\"dweb:/ipfs/QmeeAZpdHwUXxqP8pxA7GNtoCGBmmH4FaqLLwScVKGxtxZ\"]},\"contracts/interfaces/UserOperation.sol\":{\"keccak256\":\"0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c\",\"dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN\"]},\"contracts/utils/Exec.sol\":{\"keccak256\":\"0x5b232117afbc2939f3ffc92745614867e9e1d475a3e1e5443adae13c200174f1\",\"license\":\"LGPL-3.0-only\",\"urls\":[\"bzz-raw://62e7365379a06ead7b47637945bcaee095d51aab1d3ac00ddec69443e6cbe9fe\",\"dweb:/ipfs/QmctG3aw4U3KMSMeJKoLJ1NJewjMWfppnd1m3kxNTe39Uy\"]}},\"version\":1}",
+ "bytecode": "0x60a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033",
+ "deployedBytecode": "0x60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c63430008110033"
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/mumbai/solcInputs/a4c52f0671aad8941c53d6ead2063803.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/mumbai/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
new file mode 100644
index 00000000..dd58ba5a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/mumbai/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
@@ -0,0 +1,68 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts/security/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n"
+ },
+ "contracts/core/EntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard {\n\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success,) = beneficiary.call{value : amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) public nonReentrant {\n\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(address(aggregator) != address(1), \"AA96 invalid aggregator\");\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {}\n catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {\n\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);\n }\n\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {\n return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(paymasterAndData.length >= 20, \"AA93 invalid paymasterAndData\");\n mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,\n sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));\n revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);\n }\n revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);\n\n }\n\n function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0) revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);\n if (sender1 == address(0)) revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender) revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0) revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0 : 20]));\n emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(UserOperation calldata userOp) internal view {\n // solhint-disable-next-line no-empty-blocks\n try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}\n catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0 : 20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)\n internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;\n }\n try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA23 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)\n internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(verificationGasLimit > gasUsedByValidateAccountPrepayment, \"AA41 too little verificationGas\");\n uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA33 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)\n private returns (uint256 validationData, uint256 paymasterValidationData) {\n\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |\n userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);\n (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}\n catch Error(string memory reason) {\n revert FailedOp(opIndex, string.concat(\"AA50 postOp reverted: \", reason));\n }\n catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {\n assembly {offset := data}\n }\n\n function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {\n assembly {data := offset}\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {mstore(0, number())}\n }\n}\n\n"
+ },
+ "contracts/core/Helpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\n struct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n }\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n// intersect account and paymaster ranges.\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(validationData);\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n }\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n }\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\n function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n }\n\n"
+ },
+ "contracts/core/NonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(address sender, uint192 key)\n public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(address sender, uint256 nonce) internal returns (bool) {\n\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n\n}\n"
+ },
+ "contracts/core/SenderCreator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(bytes calldata initCode) external returns (address sender) {\n address factory = address(bytes20(initCode[0 : 20]));\n bytes memory initCallData = initCode[20 :];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n"
+ },
+ "contracts/core/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(address account) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(unstakeDelaySec >= info.unstakeDelaySec, \"cannot decrease unstake time\");\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(info.withdrawTime <= block.timestamp, \"Stake withdrawal is not due\");\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success,) = withdrawAddress.call{value : stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success,) = withdrawAddress.call{value : withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n"
+ },
+ "contracts/interfaces/IAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external returns (uint256 validationData);\n}\n"
+ },
+ "contracts/interfaces/IAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\n}\n"
+ },
+ "contracts/interfaces/IEntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo);\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n\n"
+ },
+ "contracts/interfaces/INonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(address sender, uint192 key)\n external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n"
+ },
+ "contracts/interfaces/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;\n}\n"
+ },
+ "contracts/interfaces/IStakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n\n event Deposited(\n address indexed account,\n uint256 totalDeposit\n );\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(\n address indexed account,\n uint256 withdrawTime\n );\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
+ },
+ "contracts/interfaces/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n }\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {data := calldataload(userOp)}\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return abi.encode(\n sender, nonce,\n hashInitCode, hashCallData,\n callGasLimit, verificationGasLimit, preVerificationGas,\n maxFeePerGas, maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/utils/Exec.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {\n bool success = call(to,0,data,gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 1000000
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/optimism/.chainId b/lib/SoulWalletCore/lib/account-abstraction/deployments/optimism/.chainId
new file mode 100644
index 00000000..9a037142
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/optimism/.chainId
@@ -0,0 +1 @@
+10
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/optimism/EntryPoint.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/optimism/EntryPoint.json
new file mode 100644
index 00000000..916c2390
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/optimism/EntryPoint.json
@@ -0,0 +1,1318 @@
+{
+ "address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "paid",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bool",
+ "name": "targetSuccess",
+ "type": "bool"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetResult",
+ "type": "bytes"
+ }
+ ],
+ "name": "ExecutionResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "opIndex",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "reason",
+ "type": "string"
+ }
+ ],
+ "name": "FailedOp",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "SenderAddressResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureValidationFailed",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "stakeInfo",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IEntryPoint.AggregatorStakeInfo",
+ "name": "aggregatorInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResultWithAggregation",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "factory",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ }
+ ],
+ "name": "AccountDeployed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "BeforeExecution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalDeposit",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposited",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureAggregatorChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalStaked",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeLocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "withdrawTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeUnlocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeWithdrawn",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "success",
+ "type": "bool"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasUsed",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserOperationEvent",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "revertReason",
+ "type": "bytes"
+ }
+ ],
+ "name": "UserOperationRevertReason",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawn",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "SIG_VALIDATION_FAILED",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ }
+ ],
+ "name": "_validateSenderAndPaymaster",
+ "outputs": [],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ }
+ ],
+ "name": "addStake",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deposits",
+ "outputs": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "getDepositInfo",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "internalType": "struct IStakeManager.DepositInfo",
+ "name": "info",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "getNonce",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ }
+ ],
+ "name": "getSenderAddress",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "getUserOpHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "userOps",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "contract IAggregator",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.UserOpsPerAggregator[]",
+ "name": "opsPerAggregator",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleAggregatedOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "ops",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "incrementNonce",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.MemoryUserOp",
+ "name": "mUserOp",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "contextOffset",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.UserOpInfo",
+ "name": "opInfo",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes",
+ "name": "context",
+ "type": "bytes"
+ }
+ ],
+ "name": "innerHandleOp",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "",
+ "type": "uint192"
+ }
+ ],
+ "name": "nonceSequenceNumber",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "op",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetCallData",
+ "type": "bytes"
+ }
+ ],
+ "name": "simulateHandleOp",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "simulateValidation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unlockStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ }
+ ],
+ "name": "withdrawStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "withdrawAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdrawTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "args": [],
+ "numDeployments": 1,
+ "solcInputHash": "a4c52f0671aad8941c53d6ead2063803",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"targetSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"targetResult\",\"type\":\"bytes\"}],\"name\":\"ExecutionResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"opIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"FailedOp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderAddressResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureValidationFailed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResult\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"type\":\"tuple\"}],\"internalType\":\"struct IEntryPoint.AggregatorStakeInfo\",\"name\":\"aggregatorInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResultWithAggregation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"}],\"name\":\"AccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"BeforeExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalDeposit\",\"type\":\"uint256\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureAggregatorChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStaked\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"name\":\"StakeLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"StakeWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasUsed\",\"type\":\"uint256\"}],\"name\":\"UserOperationEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"revertReason\",\"type\":\"bytes\"}],\"name\":\"UserOperationRevertReason\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SIG_VALIDATION_FAILED\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"}],\"name\":\"_validateSenderAndPaymaster\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"}],\"name\":\"addStake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getDepositInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"internalType\":\"struct IStakeManager.DepositInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"getSenderAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"getUserOpHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"userOps\",\"type\":\"tuple[]\"},{\"internalType\":\"contract IAggregator\",\"name\":\"aggregator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.UserOpsPerAggregator[]\",\"name\":\"opsPerAggregator\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleAggregatedOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"incrementNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.MemoryUserOp\",\"name\":\"mUserOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contextOffset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.UserOpInfo\",\"name\":\"opInfo\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"name\":\"innerHandleOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"name\":\"nonceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCallData\",\"type\":\"bytes\"}],\"name\":\"simulateHandleOp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"simulateValidation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"}],\"name\":\"withdrawStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"withdrawAmount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"FailedOp(uint256,string)\":[{\"params\":{\"opIndex\":\"- index into the array of ops to the failed one (in simulateValidation, this is always zero)\",\"reason\":\"- revert reason The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues, so a failure can be attributed to the correct entity. Should be caught in off-chain handleOps simulation and not happen on-chain. Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\"}}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"params\":{\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"params\":{\"aggregatorInfo\":\"signature aggregation info (if the account requires signature aggregator) bundler MUST use it to verify the signature, or reject the UserOperation\",\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}]},\"kind\":\"dev\",\"methods\":{\"addStake(uint32)\":{\"params\":{\"unstakeDelaySec\":\"the new lock duration before the deposit can be withdrawn.\"}},\"getDepositInfo(address)\":{\"returns\":{\"info\":\"- full deposit information of given account\"}},\"getNonce(address,uint192)\":{\"params\":{\"key\":\"the high 192 bit of the nonce\",\"sender\":\"the account address\"},\"returns\":{\"nonce\":\"a full nonce to pass for next UserOp with this sender.\"}},\"getSenderAddress(bytes)\":{\"params\":{\"initCode\":\"the constructor code to be passed into the UserOperation.\"}},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"opsPerAggregator\":\"the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\"}},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"ops\":\"the operations to execute\"}},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"params\":{\"op\":\"the UserOperation to simulate\",\"target\":\"if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult are set to the return from that call.\",\"targetCallData\":\"callData to pass to target address\"}},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"details\":\"this method always revert. Successful result is ValidationResult error. other errors are failures.The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\",\"params\":{\"userOp\":\"the user operation to validate.\"}},\"withdrawStake(address)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\"}},\"withdrawTo(address,uint256)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\",\"withdrawAmount\":\"the amount to withdraw.\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"ExecutionResult(uint256,uint256,uint48,uint48,bool,bytes)\":[{\"notice\":\"return value of simulateHandleOp\"}],\"FailedOp(uint256,string)\":[{\"notice\":\"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.\"}],\"SenderAddressResult(address)\":[{\"notice\":\"return value of getSenderAddress\"}],\"SignatureValidationFailed(address)\":[{\"notice\":\"error case when a signature aggregator fails to verify the aggregated signature it had created.\"}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"notice\":\"Successful result from simulateValidation.\"}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"notice\":\"Successful result from simulateValidation, if the account returns a signature aggregator\"}]},\"events\":{\"AccountDeployed(bytes32,address,address,address)\":{\"notice\":\"account \\\"sender\\\" was deployed.\"},\"BeforeExecution()\":{\"notice\":\"an event emitted by handleOps(), before starting the execution loop. any event emitted before this event, is part of the validation.\"},\"SignatureAggregatorChanged(address)\":{\"notice\":\"signature aggregator used by the following UserOperationEvents within this bundle.\"},\"StakeLocked(address,uint256,uint256)\":{\"notice\":\"Emitted when stake or unstake delay are modified\"},\"StakeUnlocked(address,uint256)\":{\"notice\":\"Emitted once a stake is scheduled for withdrawal\"},\"UserOperationRevertReason(bytes32,address,uint256,bytes)\":{\"notice\":\"An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\"}},\"kind\":\"user\",\"methods\":{\"SIG_VALIDATION_FAILED()\":{\"notice\":\"for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value in case of signature failure, instead of revert.\"},\"_validateSenderAndPaymaster(bytes,address,bytes)\":{\"notice\":\"Called only during simulation. This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\"},\"addStake(uint32)\":{\"notice\":\"add to the account's stake - amount and delay any pending unstake is first cancelled.\"},\"balanceOf(address)\":{\"notice\":\"return the deposit (for gas payment) of the account\"},\"depositTo(address)\":{\"notice\":\"add to the deposit of the given account\"},\"deposits(address)\":{\"notice\":\"maps paymaster to their deposits and stakes\"},\"getNonce(address,uint192)\":{\"notice\":\"Return the next nonce for this sender. Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) But UserOp with different keys can come with arbitrary order.\"},\"getSenderAddress(bytes)\":{\"notice\":\"Get counterfactual sender address. Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. this method always revert, and returns the address in SenderAddressResult error\"},\"getUserOpHash((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"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.\"},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperation with Aggregators\"},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperations. no signature aggregator is used. if any account requires an aggregator (that is, it returned an aggregator when performing simulateValidation), then handleAggregatedOps() must be used instead.\"},\"incrementNonce(uint192)\":{\"notice\":\"Manually increment the nonce of the sender. This method is exposed just for completeness.. Account does NOT need to call it, neither during validation, nor elsewhere, as the EntryPoint will update the nonce regardless. Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future UserOperations will not pay extra for the first transaction with a given key.\"},\"innerHandleOp(bytes,((address,uint256,uint256,uint256,uint256,address,uint256,uint256),bytes32,uint256,uint256,uint256),bytes)\":{\"notice\":\"inner function to handle a UserOperation. Must be declared \\\"external\\\" to open a call context, but it can only be called by handleOps.\"},\"nonceSequenceNumber(address,uint192)\":{\"notice\":\"The next valid sequence number for a given nonce key.\"},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"notice\":\"simulate full execution of a UserOperation (including both validation and target execution) this method will always revert with \\\"ExecutionResult\\\". it performs full validation of the UserOperation, but ignores signature error. an optional target address is called after the userop succeeds, and its value is returned (before the entire call is reverted) Note that in order to collect the the success/failure of the target call, it must be executed with trace enabled to track the emitted events.\"},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\"},\"unlockStake()\":{\"notice\":\"attempt to unlock the stake. the value can be withdrawn (using withdrawStake) after the unstake delay.\"},\"withdrawStake(address)\":{\"notice\":\"withdraw from the (unlocked) stake. must first call unlockStake and wait for the unstakeDelay to pass\"},\"withdrawTo(address,uint256)\":{\"notice\":\"withdraw from the deposit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/core/EntryPoint.sol\":\"EntryPoint\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0x190dd6f8d592b7e4e930feb7f4313aeb8e1c4ad3154c27ce1cf6a512fc30d8cc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ce8dfb62d0c4fa260d6eec8f1cd47f5f2a044e11bde5b31d18072fa6e7d9010\",\"dweb:/ipfs/QmTyFztU3tLEcEDnqqiaW4UJetqsU77LXc6pjc9oTXCK5u\"]},\"contracts/core/EntryPoint.sol\":{\"keccak256\":\"0x04f86318b47f052d7308795ffae6ecec0d023d2458b4e17751b89a0e4acfcdc6\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://c9f6e359c8dbe875ad974d3a0fb7b3d62319a6b115c44bac1e4587ae2ad2edaf\",\"dweb:/ipfs/QmTSWTov2rUeYk8cwzrtsd3uVXokCYok4gMiZ1sPs9tycH\"]},\"contracts/core/Helpers.sol\":{\"keccak256\":\"0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746\",\"dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU\"]},\"contracts/core/NonceManager.sol\":{\"keccak256\":\"0xa17a4a6fde70088ab18ffe6df830f3efa31f1cd0e1a7160336c96e3c94984d25\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://b38615df9f80c56282b72888e9ba1eb1a9413fa67a0dbf094deda7af9feb38e7\",\"dweb:/ipfs/QmSzcXetEJRH4UHuUmZiSgX6bFgfqHWfmyuxVnh4NosMk1\"]},\"contracts/core/SenderCreator.sol\":{\"keccak256\":\"0x44b9449fec82d6cdfb01d52fdd5a72f90099c651316123810cf9633f00b018c2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a9c0487390e72638681d175c45bc92425c802fffdca4bd0ae8457782ee284612\",\"dweb:/ipfs/QmVbzuehCUWJWqEHyMWuc6cRVbxfcMdFsmGL9o4Wz7WY2x\"]},\"contracts/core/StakeManager.sol\":{\"keccak256\":\"0x21aa0956382bd000b1b8c3b1d19ca6ebcd6c9029eebb19c612fb38ee5dd2430a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0a625c8795354d9f429367f9c1d14eb8af7db9c7f2c2a2033e2066ced76a573a\",\"dweb:/ipfs/Qmd1j6UarUg54q1G2HCNCLQz8XGVZR1qxX7eQ6cytHpQPN\"]},\"contracts/interfaces/IAccount.sol\":{\"keccak256\":\"0x556a0e5980de18e90b115553ed502408155ba35f58642823010d9288047bc418\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a0f420134b79596db8737173c7b933ae0a33059e107b6327c43aa40d4744a9e4\",\"dweb:/ipfs/QmRo8s1AhXmEMV7uPYnbpYwU19e9Bk6jmYBJTiPx3Fo85W\"]},\"contracts/interfaces/IAggregator.sol\":{\"keccak256\":\"0x060e9ddb0152250c269ba0640dc5753834ac44cf182a2837d508c0c529cae26a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://20ed837bc5909c89ff1910246bf245a5dad6840aa939382e1694964eb7dbd37b\",\"dweb:/ipfs/QmTMybRq5yyghPDDs1ZCNAVB9sSJ4WHe6Q9mejuKPTAdNP\"]},\"contracts/interfaces/IEntryPoint.sol\":{\"keccak256\":\"0x3a90bf308819ed125fa4202f880999caff8a8686633b8ddb79a30ca240d5b8f8\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://d2d21cc92c2fdab2b58d21bc25d4cd0e8c284b922528a186b087b818d54bc6cf\",\"dweb:/ipfs/QmT1qrfuBjsv2rmRCDn8mgPXHp94hARJwzbcDuBLDTbFWd\"]},\"contracts/interfaces/INonceManager.sol\":{\"keccak256\":\"0x509871e6c63663cdcc3eba19920fe84e991f38b289b1377ac3c3a6d9f22d7e12\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://00fe21b4349b24c50df60e1a705179293982bd9e7a32b78d4bac9620f89e7fe2\",\"dweb:/ipfs/QmSFFYGfUwQbVa6hASjU7YxTvgi2HkfrPr4X5oPHscHg8b\"]},\"contracts/interfaces/IPaymaster.sol\":{\"keccak256\":\"0x36858ba8685024974f533530420688da3454d29996ebc42e410673a1ed2ec456\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://616cbcf51778b1961b7f20a547bec7efae6d1d565df0f651926241ed8bde9ad8\",\"dweb:/ipfs/QmaVsgffUUmeUJYgStvRr8cNZ1LBbrc3FYNLW4JT1dVLia\"]},\"contracts/interfaces/IStakeManager.sol\":{\"keccak256\":\"0xd227b02888cd4ac68daebcdfd992ec00f9fff66fa3b3bb16f656cd582fa3480f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://b389da4714a138be63704a576a482505eab2855e263b38a93706395d8d42e7c3\",\"dweb:/ipfs/QmeeAZpdHwUXxqP8pxA7GNtoCGBmmH4FaqLLwScVKGxtxZ\"]},\"contracts/interfaces/UserOperation.sol\":{\"keccak256\":\"0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c\",\"dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN\"]},\"contracts/utils/Exec.sol\":{\"keccak256\":\"0x5b232117afbc2939f3ffc92745614867e9e1d475a3e1e5443adae13c200174f1\",\"license\":\"LGPL-3.0-only\",\"urls\":[\"bzz-raw://62e7365379a06ead7b47637945bcaee095d51aab1d3ac00ddec69443e6cbe9fe\",\"dweb:/ipfs/QmctG3aw4U3KMSMeJKoLJ1NJewjMWfppnd1m3kxNTe39Uy\"]}},\"version\":1}",
+ "bytecode": "0x60a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033",
+ "deployedBytecode": "0x60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c63430008110033"
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/optimism/solcInputs/a4c52f0671aad8941c53d6ead2063803.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/optimism/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
new file mode 100644
index 00000000..dd58ba5a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/optimism/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
@@ -0,0 +1,68 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts/security/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n"
+ },
+ "contracts/core/EntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard {\n\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success,) = beneficiary.call{value : amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) public nonReentrant {\n\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(address(aggregator) != address(1), \"AA96 invalid aggregator\");\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {}\n catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {\n\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);\n }\n\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {\n return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(paymasterAndData.length >= 20, \"AA93 invalid paymasterAndData\");\n mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,\n sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));\n revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);\n }\n revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);\n\n }\n\n function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0) revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);\n if (sender1 == address(0)) revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender) revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0) revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0 : 20]));\n emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(UserOperation calldata userOp) internal view {\n // solhint-disable-next-line no-empty-blocks\n try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}\n catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0 : 20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)\n internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;\n }\n try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA23 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)\n internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(verificationGasLimit > gasUsedByValidateAccountPrepayment, \"AA41 too little verificationGas\");\n uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA33 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)\n private returns (uint256 validationData, uint256 paymasterValidationData) {\n\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |\n userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);\n (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}\n catch Error(string memory reason) {\n revert FailedOp(opIndex, string.concat(\"AA50 postOp reverted: \", reason));\n }\n catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {\n assembly {offset := data}\n }\n\n function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {\n assembly {data := offset}\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {mstore(0, number())}\n }\n}\n\n"
+ },
+ "contracts/core/Helpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\n struct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n }\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n// intersect account and paymaster ranges.\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(validationData);\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n }\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n }\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\n function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n }\n\n"
+ },
+ "contracts/core/NonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(address sender, uint192 key)\n public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(address sender, uint256 nonce) internal returns (bool) {\n\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n\n}\n"
+ },
+ "contracts/core/SenderCreator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(bytes calldata initCode) external returns (address sender) {\n address factory = address(bytes20(initCode[0 : 20]));\n bytes memory initCallData = initCode[20 :];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n"
+ },
+ "contracts/core/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(address account) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(unstakeDelaySec >= info.unstakeDelaySec, \"cannot decrease unstake time\");\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(info.withdrawTime <= block.timestamp, \"Stake withdrawal is not due\");\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success,) = withdrawAddress.call{value : stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success,) = withdrawAddress.call{value : withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n"
+ },
+ "contracts/interfaces/IAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external returns (uint256 validationData);\n}\n"
+ },
+ "contracts/interfaces/IAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\n}\n"
+ },
+ "contracts/interfaces/IEntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo);\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n\n"
+ },
+ "contracts/interfaces/INonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(address sender, uint192 key)\n external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n"
+ },
+ "contracts/interfaces/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;\n}\n"
+ },
+ "contracts/interfaces/IStakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n\n event Deposited(\n address indexed account,\n uint256 totalDeposit\n );\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(\n address indexed account,\n uint256 withdrawTime\n );\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
+ },
+ "contracts/interfaces/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n }\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {data := calldataload(userOp)}\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return abi.encode(\n sender, nonce,\n hashInitCode, hashCallData,\n callGasLimit, verificationGasLimit, preVerificationGas,\n maxFeePerGas, maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/utils/Exec.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {\n bool success = call(to,0,data,gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 1000000
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/sepolia/.chainId b/lib/SoulWalletCore/lib/account-abstraction/deployments/sepolia/.chainId
new file mode 100644
index 00000000..bd8d1cd4
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/sepolia/.chainId
@@ -0,0 +1 @@
+11155111
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/sepolia/EntryPoint.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/sepolia/EntryPoint.json
new file mode 100644
index 00000000..916c2390
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/sepolia/EntryPoint.json
@@ -0,0 +1,1318 @@
+{
+ "address": "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
+ "abi": [
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "paid",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bool",
+ "name": "targetSuccess",
+ "type": "bool"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetResult",
+ "type": "bytes"
+ }
+ ],
+ "name": "ExecutionResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "opIndex",
+ "type": "uint256"
+ },
+ {
+ "internalType": "string",
+ "name": "reason",
+ "type": "string"
+ }
+ ],
+ "name": "FailedOp",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "SenderAddressResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureValidationFailed",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResult",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "sigFailed",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validAfter",
+ "type": "uint48"
+ },
+ {
+ "internalType": "uint48",
+ "name": "validUntil",
+ "type": "uint48"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterContext",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.ReturnInfo",
+ "name": "returnInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "senderInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "factoryInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "paymasterInfo",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "stake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct IStakeManager.StakeInfo",
+ "name": "stakeInfo",
+ "type": "tuple"
+ }
+ ],
+ "internalType": "struct IEntryPoint.AggregatorStakeInfo",
+ "name": "aggregatorInfo",
+ "type": "tuple"
+ }
+ ],
+ "name": "ValidationResultWithAggregation",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "factory",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ }
+ ],
+ "name": "AccountDeployed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [],
+ "name": "BeforeExecution",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalDeposit",
+ "type": "uint256"
+ }
+ ],
+ "name": "Deposited",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "aggregator",
+ "type": "address"
+ }
+ ],
+ "name": "SignatureAggregatorChanged",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "totalStaked",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "unstakeDelaySec",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeLocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "withdrawTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeUnlocked",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "StakeWithdrawn",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "success",
+ "type": "bool"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "actualGasUsed",
+ "type": "uint256"
+ }
+ ],
+ "name": "UserOperationEvent",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "bytes",
+ "name": "revertReason",
+ "type": "bytes"
+ }
+ ],
+ "name": "UserOperationRevertReason",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Withdrawn",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "SIG_VALIDATION_FAILED",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ }
+ ],
+ "name": "_validateSenderAndPaymaster",
+ "outputs": [],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ }
+ ],
+ "name": "addStake",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "depositTo",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "deposits",
+ "outputs": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "getDepositInfo",
+ "outputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint112",
+ "name": "deposit",
+ "type": "uint112"
+ },
+ {
+ "internalType": "bool",
+ "name": "staked",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint112",
+ "name": "stake",
+ "type": "uint112"
+ },
+ {
+ "internalType": "uint32",
+ "name": "unstakeDelaySec",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint48",
+ "name": "withdrawTime",
+ "type": "uint48"
+ }
+ ],
+ "internalType": "struct IStakeManager.DepositInfo",
+ "name": "info",
+ "type": "tuple"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "getNonce",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ }
+ ],
+ "name": "getSenderAddress",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "getUserOpHash",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "userOps",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "contract IAggregator",
+ "name": "aggregator",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IEntryPoint.UserOpsPerAggregator[]",
+ "name": "opsPerAggregator",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleAggregatedOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation[]",
+ "name": "ops",
+ "type": "tuple[]"
+ },
+ {
+ "internalType": "address payable",
+ "name": "beneficiary",
+ "type": "address"
+ }
+ ],
+ "name": "handleOps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint192",
+ "name": "key",
+ "type": "uint192"
+ }
+ ],
+ "name": "incrementNonce",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "components": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "paymaster",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.MemoryUserOp",
+ "name": "mUserOp",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "userOpHash",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "uint256",
+ "name": "prefund",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "contextOffset",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preOpGas",
+ "type": "uint256"
+ }
+ ],
+ "internalType": "struct EntryPoint.UserOpInfo",
+ "name": "opInfo",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes",
+ "name": "context",
+ "type": "bytes"
+ }
+ ],
+ "name": "innerHandleOp",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "actualGasCost",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ },
+ {
+ "internalType": "uint192",
+ "name": "",
+ "type": "uint192"
+ }
+ ],
+ "name": "nonceSequenceNumber",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "op",
+ "type": "tuple"
+ },
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "targetCallData",
+ "type": "bytes"
+ }
+ ],
+ "name": "simulateHandleOp",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "initCode",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "callData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint256",
+ "name": "callGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "verificationGasLimit",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "preVerificationGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPriorityFeePerGas",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "paymasterAndData",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct UserOperation",
+ "name": "userOp",
+ "type": "tuple"
+ }
+ ],
+ "name": "simulateValidation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "unlockStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ }
+ ],
+ "name": "withdrawStake",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address payable",
+ "name": "withdrawAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "withdrawAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdrawTo",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "stateMutability": "payable",
+ "type": "receive"
+ }
+ ],
+ "args": [],
+ "numDeployments": 1,
+ "solcInputHash": "a4c52f0671aad8941c53d6ead2063803",
+ "metadata": "{\"compiler\":{\"version\":\"0.8.17+commit.8df45f5f\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bool\",\"name\":\"targetSuccess\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"targetResult\",\"type\":\"bytes\"}],\"name\":\"ExecutionResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"opIndex\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"reason\",\"type\":\"string\"}],\"name\":\"FailedOp\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderAddressResult\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureValidationFailed\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResult\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"sigFailed\",\"type\":\"bool\"},{\"internalType\":\"uint48\",\"name\":\"validAfter\",\"type\":\"uint48\"},{\"internalType\":\"uint48\",\"name\":\"validUntil\",\"type\":\"uint48\"},{\"internalType\":\"bytes\",\"name\":\"paymasterContext\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.ReturnInfo\",\"name\":\"returnInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"senderInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"factoryInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"paymasterInfo\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"stake\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"internalType\":\"struct IStakeManager.StakeInfo\",\"name\":\"stakeInfo\",\"type\":\"tuple\"}],\"internalType\":\"struct IEntryPoint.AggregatorStakeInfo\",\"name\":\"aggregatorInfo\",\"type\":\"tuple\"}],\"name\":\"ValidationResultWithAggregation\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"factory\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"}],\"name\":\"AccountDeployed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"BeforeExecution\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalDeposit\",\"type\":\"uint256\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"SignatureAggregatorChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"totalStaked\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"unstakeDelaySec\",\"type\":\"uint256\"}],\"name\":\"StakeLocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"withdrawTime\",\"type\":\"uint256\"}],\"name\":\"StakeUnlocked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"StakeWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"actualGasUsed\",\"type\":\"uint256\"}],\"name\":\"UserOperationEvent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"revertReason\",\"type\":\"bytes\"}],\"name\":\"UserOperationRevertReason\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SIG_VALIDATION_FAILED\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"}],\"name\":\"_validateSenderAndPaymaster\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"}],\"name\":\"addStake\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"depositTo\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"deposits\",\"outputs\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getDepositInfo\",\"outputs\":[{\"components\":[{\"internalType\":\"uint112\",\"name\":\"deposit\",\"type\":\"uint112\"},{\"internalType\":\"bool\",\"name\":\"staked\",\"type\":\"bool\"},{\"internalType\":\"uint112\",\"name\":\"stake\",\"type\":\"uint112\"},{\"internalType\":\"uint32\",\"name\":\"unstakeDelaySec\",\"type\":\"uint32\"},{\"internalType\":\"uint48\",\"name\":\"withdrawTime\",\"type\":\"uint48\"}],\"internalType\":\"struct IStakeManager.DepositInfo\",\"name\":\"info\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"getNonce\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"}],\"name\":\"getSenderAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"getUserOpHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"userOps\",\"type\":\"tuple[]\"},{\"internalType\":\"contract IAggregator\",\"name\":\"aggregator\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct IEntryPoint.UserOpsPerAggregator[]\",\"name\":\"opsPerAggregator\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleAggregatedOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation[]\",\"name\":\"ops\",\"type\":\"tuple[]\"},{\"internalType\":\"address payable\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"handleOps\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint192\",\"name\":\"key\",\"type\":\"uint192\"}],\"name\":\"incrementNonce\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"paymaster\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.MemoryUserOp\",\"name\":\"mUserOp\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"userOpHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"prefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"contextOffset\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preOpGas\",\"type\":\"uint256\"}],\"internalType\":\"struct EntryPoint.UserOpInfo\",\"name\":\"opInfo\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"name\":\"innerHandleOp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"actualGasCost\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"\",\"type\":\"uint192\"}],\"name\":\"nonceSequenceNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"op\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"targetCallData\",\"type\":\"bytes\"}],\"name\":\"simulateHandleOp\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"initCode\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"callGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"verificationGasLimit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"preVerificationGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxPriorityFeePerGas\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"paymasterAndData\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"struct UserOperation\",\"name\":\"userOp\",\"type\":\"tuple\"}],\"name\":\"simulateValidation\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlockStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"}],\"name\":\"withdrawStake\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address payable\",\"name\":\"withdrawAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"withdrawAmount\",\"type\":\"uint256\"}],\"name\":\"withdrawTo\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"errors\":{\"FailedOp(uint256,string)\":[{\"params\":{\"opIndex\":\"- index into the array of ops to the failed one (in simulateValidation, this is always zero)\",\"reason\":\"- revert reason The string starts with a unique code \\\"AAmn\\\", where \\\"m\\\" is \\\"1\\\" for factory, \\\"2\\\" for account and \\\"3\\\" for paymaster issues, so a failure can be attributed to the correct entity. Should be caught in off-chain handleOps simulation and not happen on-chain. Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\"}}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"params\":{\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"params\":{\"aggregatorInfo\":\"signature aggregation info (if the account requires signature aggregator) bundler MUST use it to verify the signature, or reject the UserOperation\",\"factoryInfo\":\"stake information about the factory (if any)\",\"paymasterInfo\":\"stake information about the paymaster (if any)\",\"returnInfo\":\"gas and time-range returned values\",\"senderInfo\":\"stake information about the sender\"}}]},\"kind\":\"dev\",\"methods\":{\"addStake(uint32)\":{\"params\":{\"unstakeDelaySec\":\"the new lock duration before the deposit can be withdrawn.\"}},\"getDepositInfo(address)\":{\"returns\":{\"info\":\"- full deposit information of given account\"}},\"getNonce(address,uint192)\":{\"params\":{\"key\":\"the high 192 bit of the nonce\",\"sender\":\"the account address\"},\"returns\":{\"nonce\":\"a full nonce to pass for next UserOp with this sender.\"}},\"getSenderAddress(bytes)\":{\"params\":{\"initCode\":\"the constructor code to be passed into the UserOperation.\"}},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"opsPerAggregator\":\"the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\"}},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"params\":{\"beneficiary\":\"the address to receive the fees\",\"ops\":\"the operations to execute\"}},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"params\":{\"op\":\"the UserOperation to simulate\",\"target\":\"if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult are set to the return from that call.\",\"targetCallData\":\"callData to pass to target address\"}},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"details\":\"this method always revert. Successful result is ValidationResult error. other errors are failures.The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\",\"params\":{\"userOp\":\"the user operation to validate.\"}},\"withdrawStake(address)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\"}},\"withdrawTo(address,uint256)\":{\"params\":{\"withdrawAddress\":\"the address to send withdrawn value.\",\"withdrawAmount\":\"the amount to withdraw.\"}}},\"version\":1},\"userdoc\":{\"errors\":{\"ExecutionResult(uint256,uint256,uint48,uint48,bool,bytes)\":[{\"notice\":\"return value of simulateHandleOp\"}],\"FailedOp(uint256,string)\":[{\"notice\":\"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.\"}],\"SenderAddressResult(address)\":[{\"notice\":\"return value of getSenderAddress\"}],\"SignatureValidationFailed(address)\":[{\"notice\":\"error case when a signature aggregator fails to verify the aggregated signature it had created.\"}],\"ValidationResult((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256))\":[{\"notice\":\"Successful result from simulateValidation.\"}],\"ValidationResultWithAggregation((uint256,uint256,bool,uint48,uint48,bytes),(uint256,uint256),(uint256,uint256),(uint256,uint256),(address,(uint256,uint256)))\":[{\"notice\":\"Successful result from simulateValidation, if the account returns a signature aggregator\"}]},\"events\":{\"AccountDeployed(bytes32,address,address,address)\":{\"notice\":\"account \\\"sender\\\" was deployed.\"},\"BeforeExecution()\":{\"notice\":\"an event emitted by handleOps(), before starting the execution loop. any event emitted before this event, is part of the validation.\"},\"SignatureAggregatorChanged(address)\":{\"notice\":\"signature aggregator used by the following UserOperationEvents within this bundle.\"},\"StakeLocked(address,uint256,uint256)\":{\"notice\":\"Emitted when stake or unstake delay are modified\"},\"StakeUnlocked(address,uint256)\":{\"notice\":\"Emitted once a stake is scheduled for withdrawal\"},\"UserOperationRevertReason(bytes32,address,uint256,bytes)\":{\"notice\":\"An event emitted if the UserOperation \\\"callData\\\" reverted with non-zero length\"}},\"kind\":\"user\",\"methods\":{\"SIG_VALIDATION_FAILED()\":{\"notice\":\"for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value in case of signature failure, instead of revert.\"},\"_validateSenderAndPaymaster(bytes,address,bytes)\":{\"notice\":\"Called only during simulation. This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\"},\"addStake(uint32)\":{\"notice\":\"add to the account's stake - amount and delay any pending unstake is first cancelled.\"},\"balanceOf(address)\":{\"notice\":\"return the deposit (for gas payment) of the account\"},\"depositTo(address)\":{\"notice\":\"add to the deposit of the given account\"},\"deposits(address)\":{\"notice\":\"maps paymaster to their deposits and stakes\"},\"getNonce(address,uint192)\":{\"notice\":\"Return the next nonce for this sender. Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop) But UserOp with different keys can come with arbitrary order.\"},\"getSenderAddress(bytes)\":{\"notice\":\"Get counterfactual sender address. Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation. this method always revert, and returns the address in SenderAddressResult error\"},\"getUserOpHash((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"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.\"},\"handleAggregatedOps(((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperation with Aggregators\"},\"handleOps((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes)[],address)\":{\"notice\":\"Execute a batch of UserOperations. no signature aggregator is used. if any account requires an aggregator (that is, it returned an aggregator when performing simulateValidation), then handleAggregatedOps() must be used instead.\"},\"incrementNonce(uint192)\":{\"notice\":\"Manually increment the nonce of the sender. This method is exposed just for completeness.. Account does NOT need to call it, neither during validation, nor elsewhere, as the EntryPoint will update the nonce regardless. Possible use-case is call it with various keys to \\\"initialize\\\" their nonces to one, so that future UserOperations will not pay extra for the first transaction with a given key.\"},\"innerHandleOp(bytes,((address,uint256,uint256,uint256,uint256,address,uint256,uint256),bytes32,uint256,uint256,uint256),bytes)\":{\"notice\":\"inner function to handle a UserOperation. Must be declared \\\"external\\\" to open a call context, but it can only be called by handleOps.\"},\"nonceSequenceNumber(address,uint192)\":{\"notice\":\"The next valid sequence number for a given nonce key.\"},\"simulateHandleOp((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes),address,bytes)\":{\"notice\":\"simulate full execution of a UserOperation (including both validation and target execution) this method will always revert with \\\"ExecutionResult\\\". it performs full validation of the UserOperation, but ignores signature error. an optional target address is called after the userop succeeds, and its value is returned (before the entire call is reverted) Note that in order to collect the the success/failure of the target call, it must be executed with trace enabled to track the emitted events.\"},\"simulateValidation((address,uint256,bytes,bytes,uint256,uint256,uint256,uint256,uint256,bytes,bytes))\":{\"notice\":\"Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\"},\"unlockStake()\":{\"notice\":\"attempt to unlock the stake. the value can be withdrawn (using withdrawStake) after the unstake delay.\"},\"withdrawStake(address)\":{\"notice\":\"withdraw from the (unlocked) stake. must first call unlockStake and wait for the unstakeDelay to pass\"},\"withdrawTo(address,uint256)\":{\"notice\":\"withdraw from the deposit.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/core/EntryPoint.sol\":\"EntryPoint\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[],\"viaIR\":true},\"sources\":{\"@openzeppelin/contracts/security/ReentrancyGuard.sol\":{\"keccak256\":\"0x190dd6f8d592b7e4e930feb7f4313aeb8e1c4ad3154c27ce1cf6a512fc30d8cc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://4ce8dfb62d0c4fa260d6eec8f1cd47f5f2a044e11bde5b31d18072fa6e7d9010\",\"dweb:/ipfs/QmTyFztU3tLEcEDnqqiaW4UJetqsU77LXc6pjc9oTXCK5u\"]},\"contracts/core/EntryPoint.sol\":{\"keccak256\":\"0x04f86318b47f052d7308795ffae6ecec0d023d2458b4e17751b89a0e4acfcdc6\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://c9f6e359c8dbe875ad974d3a0fb7b3d62319a6b115c44bac1e4587ae2ad2edaf\",\"dweb:/ipfs/QmTSWTov2rUeYk8cwzrtsd3uVXokCYok4gMiZ1sPs9tycH\"]},\"contracts/core/Helpers.sol\":{\"keccak256\":\"0x591c87519f7155d1909210276b77925ab2722a99b7b5d5649aecc36ebbdb045a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://69643e83f68e6a13d5075c7565bfce326673b0bd98c432033c4603ea84835746\",\"dweb:/ipfs/QmSwSzjYyV7qudi5vvsmzHMG2Z4YJZxX51RRXXVCLaNcEU\"]},\"contracts/core/NonceManager.sol\":{\"keccak256\":\"0xa17a4a6fde70088ab18ffe6df830f3efa31f1cd0e1a7160336c96e3c94984d25\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://b38615df9f80c56282b72888e9ba1eb1a9413fa67a0dbf094deda7af9feb38e7\",\"dweb:/ipfs/QmSzcXetEJRH4UHuUmZiSgX6bFgfqHWfmyuxVnh4NosMk1\"]},\"contracts/core/SenderCreator.sol\":{\"keccak256\":\"0x44b9449fec82d6cdfb01d52fdd5a72f90099c651316123810cf9633f00b018c2\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a9c0487390e72638681d175c45bc92425c802fffdca4bd0ae8457782ee284612\",\"dweb:/ipfs/QmVbzuehCUWJWqEHyMWuc6cRVbxfcMdFsmGL9o4Wz7WY2x\"]},\"contracts/core/StakeManager.sol\":{\"keccak256\":\"0x21aa0956382bd000b1b8c3b1d19ca6ebcd6c9029eebb19c612fb38ee5dd2430a\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://0a625c8795354d9f429367f9c1d14eb8af7db9c7f2c2a2033e2066ced76a573a\",\"dweb:/ipfs/Qmd1j6UarUg54q1G2HCNCLQz8XGVZR1qxX7eQ6cytHpQPN\"]},\"contracts/interfaces/IAccount.sol\":{\"keccak256\":\"0x556a0e5980de18e90b115553ed502408155ba35f58642823010d9288047bc418\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://a0f420134b79596db8737173c7b933ae0a33059e107b6327c43aa40d4744a9e4\",\"dweb:/ipfs/QmRo8s1AhXmEMV7uPYnbpYwU19e9Bk6jmYBJTiPx3Fo85W\"]},\"contracts/interfaces/IAggregator.sol\":{\"keccak256\":\"0x060e9ddb0152250c269ba0640dc5753834ac44cf182a2837d508c0c529cae26a\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://20ed837bc5909c89ff1910246bf245a5dad6840aa939382e1694964eb7dbd37b\",\"dweb:/ipfs/QmTMybRq5yyghPDDs1ZCNAVB9sSJ4WHe6Q9mejuKPTAdNP\"]},\"contracts/interfaces/IEntryPoint.sol\":{\"keccak256\":\"0x3a90bf308819ed125fa4202f880999caff8a8686633b8ddb79a30ca240d5b8f8\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://d2d21cc92c2fdab2b58d21bc25d4cd0e8c284b922528a186b087b818d54bc6cf\",\"dweb:/ipfs/QmT1qrfuBjsv2rmRCDn8mgPXHp94hARJwzbcDuBLDTbFWd\"]},\"contracts/interfaces/INonceManager.sol\":{\"keccak256\":\"0x509871e6c63663cdcc3eba19920fe84e991f38b289b1377ac3c3a6d9f22d7e12\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://00fe21b4349b24c50df60e1a705179293982bd9e7a32b78d4bac9620f89e7fe2\",\"dweb:/ipfs/QmSFFYGfUwQbVa6hASjU7YxTvgi2HkfrPr4X5oPHscHg8b\"]},\"contracts/interfaces/IPaymaster.sol\":{\"keccak256\":\"0x36858ba8685024974f533530420688da3454d29996ebc42e410673a1ed2ec456\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://616cbcf51778b1961b7f20a547bec7efae6d1d565df0f651926241ed8bde9ad8\",\"dweb:/ipfs/QmaVsgffUUmeUJYgStvRr8cNZ1LBbrc3FYNLW4JT1dVLia\"]},\"contracts/interfaces/IStakeManager.sol\":{\"keccak256\":\"0xd227b02888cd4ac68daebcdfd992ec00f9fff66fa3b3bb16f656cd582fa3480f\",\"license\":\"GPL-3.0-only\",\"urls\":[\"bzz-raw://b389da4714a138be63704a576a482505eab2855e263b38a93706395d8d42e7c3\",\"dweb:/ipfs/QmeeAZpdHwUXxqP8pxA7GNtoCGBmmH4FaqLLwScVKGxtxZ\"]},\"contracts/interfaces/UserOperation.sol\":{\"keccak256\":\"0x61374003361059087fdcf17967a7bba052badeaf5c7f0ae689166f8aafd3a45c\",\"license\":\"GPL-3.0\",\"urls\":[\"bzz-raw://6ff83c59432e733bf6304dda27cd4b0f34401917dd535e2669cc842d2d26568c\",\"dweb:/ipfs/QmPJbHU5TAjHqUTZzAcicEeG2nknmwCN43L4EW9LHbknTN\"]},\"contracts/utils/Exec.sol\":{\"keccak256\":\"0x5b232117afbc2939f3ffc92745614867e9e1d475a3e1e5443adae13c200174f1\",\"license\":\"LGPL-3.0-only\",\"urls\":[\"bzz-raw://62e7365379a06ead7b47637945bcaee095d51aab1d3ac00ddec69443e6cbe9fe\",\"dweb:/ipfs/QmctG3aw4U3KMSMeJKoLJ1NJewjMWfppnd1m3kxNTe39Uy\"]}},\"version\":1}",
+ "bytecode": "0x60a080604052346200008957600160025561022c8181016001600160401b038111838210176200007357829162005d18833903906000f080156200006757608052604051615c8990816200008f82396080518181816113df01528181613e9501526141b60152f35b6040513d6000823e3d90fd5b634e487b7160e01b600052604160045260246000fd5b600080fdfe60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c634300081100336080806040523461001657610210908161001c8239f35b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c63570e1a361461002857600080fd5b346100c95760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100c95760043567ffffffffffffffff918282116100c957366023830112156100c95781600401359283116100c95736602484840101116100c9576100c561009e84602485016100fc565b60405173ffffffffffffffffffffffffffffffffffffffff90911681529081906020820190565b0390f35b80fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90806014116101bb5767ffffffffffffffff917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec82018381116101cd575b604051937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f81600b8701160116850190858210908211176101c0575b604052808452602084019036848401116101bb576020946000600c819682946014880187378301015251923560601c5af19060005191156101b557565b60009150565b600080fd5b6101c86100cc565b610178565b6101d56100cc565b61013a56fea26469706673582212201927e80b76ab9b71c952137dd676621a9fdf520c25928815636594036eb1c40364736f6c63430008110033",
+ "deployedBytecode": "0x60806040526004361015610023575b361561001957600080fd5b610021615531565b005b60003560e01c80630396cb60146101b35780630bd28e3b146101aa5780631b2e01b8146101a15780631d732756146101985780631fad948c1461018f578063205c28781461018657806335567e1a1461017d5780634b1d7cf5146101745780635287ce121461016b57806370a08231146101625780638f41ec5a14610159578063957122ab146101505780639b249f6914610147578063a61935311461013e578063b760faf914610135578063bb9fe6bf1461012c578063c23a5cea14610123578063d6383f941461011a578063ee219423146101115763fc7e286d0361000e5761010c611bcd565b61000e565b5061010c6119b5565b5061010c61184d565b5061010c6116b4565b5061010c611536565b5061010c6114f7565b5061010c6114d6565b5061010c611337565b5061010c611164565b5061010c611129565b5061010c6110a4565b5061010c610f54565b5061010c610bf8565b5061010c610b33565b5061010c610994565b5061010c6108ba565b5061010c6106e7565b5061010c610467565b5061010c610385565b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043563ffffffff8116808203610359576103547fa5ae833d0bb1dcd632d98a8b70973e8516812898e19bf27b70071ebc8dc52c01916102716102413373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b9161024d811515615697565b61026a610261600185015463ffffffff1690565b63ffffffff1690565b11156156fc565b54926103366dffffffffffffffffffffffffffff946102f461029834888460781c166121d5565b966102a4881515615761565b6102b0818911156157c6565b6102d4816102bc6105ec565b941684906dffffffffffffffffffffffffffff169052565b6001602084015287166dffffffffffffffffffffffffffff166040830152565b63ffffffff83166060820152600060808201526103313373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61582b565b6040805194855263ffffffff90911660208501523393918291820190565b0390a2005b600080fd5b6024359077ffffffffffffffffffffffffffffffffffffffffffffffff8216820361035957565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043577ffffffffffffffffffffffffffffffffffffffffffffffff81168103610359576104149033600052600160205260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b61041e8154612491565b9055005b73ffffffffffffffffffffffffffffffffffffffff81160361035957565b6024359061044d82610422565b565b60c4359061044d82610422565b359061044d82610422565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760206104fc6004356104a881610422565b73ffffffffffffffffffffffffffffffffffffffff6104c561035e565b91166000526001835260406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b54604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60a0810190811067ffffffffffffffff82111761055157604052565b610559610505565b604052565b610100810190811067ffffffffffffffff82111761055157604052565b67ffffffffffffffff811161055157604052565b6060810190811067ffffffffffffffff82111761055157604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761055157604052565b6040519061044d82610535565b6040519060c0820182811067ffffffffffffffff82111761055157604052565b604051906040820182811067ffffffffffffffff82111761055157604052565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60209267ffffffffffffffff8111610675575b01160190565b61067d610505565b61066f565b92919261068e82610639565b9161069c60405193846105ab565b829481845281830111610359578281602093846000960137010152565b9181601f840112156103595782359167ffffffffffffffff8311610359576020838186019501011161035957565b5034610359576101c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff60043581811161035957366023820112156103595761074a903690602481600401359101610682565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc36016101808112610359576101006040519161078783610535565b12610359576040516107988161055e565b6107a0610440565b815260443560208201526064356040820152608435606082015260a43560808201526107ca61044f565b60a082015260e43560c08201526101043560e082015281526101243560208201526101443560408201526101643560608201526101843560808201526101a4359182116103595761083e9261082661082e9336906004016106b9565b9290916128b1565b6040519081529081906020820190565b0390f35b9060407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126103595760043567ffffffffffffffff9283821161035957806023830112156103595781600401359384116103595760248460051b830101116103595760240191906024356108b781610422565b90565b5034610359576108c936610842565b6108d4929192611e3a565b6108dd83611d2d565b60005b84811061095d57506000927fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f9728480a183915b85831061092d576109238585611ed7565b6100216001600255565b909193600190610953610941878987611dec565b61094b8886611dca565b51908861233f565b0194019190610912565b8061098b610984610972600194869896611dca565b5161097e848a88611dec565b84613448565b9083612f30565b019290926108e0565b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356109d081610422565b6024359060009133835282602052604083206dffffffffffffffffffffffffffff81541692838311610ad557848373ffffffffffffffffffffffffffffffffffffffff829593610a788496610a3f610a2c8798610ad29c6121c0565b6dffffffffffffffffffffffffffff1690565b6dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810185905233917fd1c19fbcd4551a5edfb66d43d2e337c04837afda3482b42bdf569a8fccdae5fb91a2165af1610acc611ea7565b50615ba2565b80f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f576974686472617720616d6f756e7420746f6f206c61726765000000000000006044820152fd5b50346103595760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576020600435610b7181610422565b73ffffffffffffffffffffffffffffffffffffffff610b8e61035e565b911660005260018252610bc98160406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000006040519260401b16178152f35b503461035957610c0736610842565b610c0f611e3a565b6000805b838210610df657610c249150611d2d565b7fbb47ee3e183a558b1a2ff0874b079f3fc5478b7454eacf2bfc5af2ff5878f972600080a16000805b848110610d5c57505060008093815b818110610c9357610923868660007f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d8180a2611ed7565b610cf7610ca182848a6124cb565b610ccc610cb3610cb36020840161256d565b73ffffffffffffffffffffffffffffffffffffffff1690565b7f575ff3acadd5ab348fe1855e217e0f3678f8d767d7494c9f9fefbee2e17cca4d600080a280612519565b906000915b808310610d1457505050610d0f90612491565b610c5c565b90919497610d4f610d49610d5592610d438c8b610d3c82610d368e8b8d611dec565b92611dca565b519161233f565b906121d5565b99612491565b95612491565b9190610cfc565b610d678186886124cb565b6020610d7f610d768380612519565b9290930161256d565b9173ffffffffffffffffffffffffffffffffffffffff60009316905b828410610db45750505050610daf90612491565b610c4d565b90919294610d4f81610de985610de2610dd0610dee968d611dca565b51610ddc8c8b8a611dec565b85613448565b908b613148565b612491565b929190610d9b565b610e018285876124cb565b90610e0c8280612519565b92610e1c610cb36020830161256d565b9173ffffffffffffffffffffffffffffffffffffffff8316610e416001821415612577565b610e62575b505050610e5c91610e56916121d5565b91612491565b90610c13565b909592610e7b6040999693999895989788810190611fc8565b92908a3b156103595789938b918a5193849283927fe3563a4f00000000000000000000000000000000000000000000000000000000845260049e8f850193610ec294612711565b03815a93600094fa9081610f3b575b50610f255786517f86a9f75000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8a16818a0190815281906020010390fd5b0390fd5b9497509295509093509181610e56610e5c610e46565b80610f48610f4e9261057b565b8061111e565b38610ed1565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761083e73ffffffffffffffffffffffffffffffffffffffff600435610fa881610422565b608060409283928351610fba81610535565b60009381858093528260208201528287820152826060820152015216815280602052209061104965ffffffffffff6001835194610ff686610535565b80546dffffffffffffffffffffffffffff8082168852607082901c60ff161515602089015260789190911c1685870152015463ffffffff8116606086015260201c16608084019065ffffffffffff169052565b5191829182919091608065ffffffffffff8160a08401956dffffffffffffffffffffffffffff808251168652602082015115156020870152604082015116604086015263ffffffff6060820151166060860152015116910152565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff6004356110f581610422565b16600052600060205260206dffffffffffffffffffffffffffff60406000205416604051908152f35b600091031261035957565b50346103595760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957602060405160018152f35b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261035957600467ffffffffffffffff8135818111610359576111b590369084016106b9565b9050602435916111c483610422565b604435908111610359576111db90369085016106b9565b92909115908161132d575b506112c6576014821015611236575b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160409060208152600060208201520190565b6112466112529261124c92612b88565b90612b96565b60601c90565b3b1561125f5738806111f5565b610f21906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601b60208201527f41413330207061796d6173746572206e6f74206465706c6f796564000000000060408201520190565b610f21836040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352820160609060208152601960208201527f41413230206163636f756e74206e6f74206465706c6f7965640000000000000060408201520190565b90503b15386111e6565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595760043567ffffffffffffffff81116103595761138960249136906004016106b9565b906113bf6040519283927f570e1a3600000000000000000000000000000000000000000000000000000000845260048401612d2c565b0360208273ffffffffffffffffffffffffffffffffffffffff92816000857f0000000000000000000000000000000000000000000000000000000000000000165af1918215611471575b600092611441575b50604051917f6ca7b806000000000000000000000000000000000000000000000000000000008352166004820152fd5b61146391925060203d811161146a575b61145b81836105ab565b810190612d17565b9038611411565b503d611451565b611479612183565b611409565b90816101609103126103595790565b60207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc820112610359576004359067ffffffffffffffff8211610359576108b79160040161147e565b50346103595760206114ef6114ea3661148d565b612a0c565b604051908152f35b5060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595761002160043561153181610422565b61562b565b5034610359576000807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126116b1573381528060205260408120600181019063ffffffff825416908115611653576115f06115b5611618936115a76115a2855460ff9060701c1690565b61598f565b65ffffffffffff42166159f4565b84547fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff16602082901b69ffffffffffff000000001617909455565b7fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff8154169055565b60405165ffffffffffff91909116815233907ffa9b3c14cc825c412c9ed81b3ba365a5b459439403f18829e572ed53a4180f0a90602090a280f35b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74207374616b6564000000000000000000000000000000000000000000006044820152fd5b80fd5b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610359576004356116f081610422565b610ad273ffffffffffffffffffffffffffffffffffffffff6117323373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b926117ea611755610a2c86546dffffffffffffffffffffffffffff9060781c1690565b94611761861515615a0e565b6117c26001820161179a65ffffffffffff611786835465ffffffffffff9060201c1690565b16611792811515615a73565b421015615ad8565b80547fffffffffffffffffffffffffffffffffffffffffffff00000000000000000000169055565b7fffffff0000000000000000000000000000ffffffffffffffffffffffffffffff8154169055565b6040805173ffffffffffffffffffffffffffffffffffffffff831681526020810186905233917fb7c918e0e249f999e965cafeb6c664271b3f4317d296461500e71da39f0cbda391a2600080809581948294165af1611847611ea7565b50615b3d565b50346103595760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595767ffffffffffffffff6004358181116103595761189e90369060040161147e565b602435916118ab83610422565b604435908111610359576118c6610f219136906004016106b9565b6118ce611caa565b6118d785612e2b565b6118ea6118e48287613240565b906153ba565b946118fa826000924384526121e2565b96438252819360609573ffffffffffffffffffffffffffffffffffffffff8316611981575b50505050608001519361194e6040611940602084015165ffffffffffff1690565b92015165ffffffffffff1690565b906040519687967f8b7ac980000000000000000000000000000000000000000000000000000000008852600488016127e1565b8395508394965061199b60409492939451809481936127d3565b03925af19060806119aa611ea7565b92919038808061191f565b5034610359576119c43661148d565b6119cc611caa565b6119d582612e2b565b6119df8183613240565b825160a00151919391611a0c9073ffffffffffffffffffffffffffffffffffffffff166154dc565b6154dc565b90611a30611a07855173ffffffffffffffffffffffffffffffffffffffff90511690565b94611a39612b50565b50611a68611a4c60409586810190611fc8565b90600060148310611bc55750611246611a079261124c92612b88565b91611a72916153ba565b805173ffffffffffffffffffffffffffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff821660018114916080880151978781015191886020820151611ac79065ffffffffffff1690565b91015165ffffffffffff16916060015192611ae06105f9565b9a8b5260208b0152841515898b015265ffffffffffff1660608a015265ffffffffffff16608089015260a088015215159081611bbc575b50611b515750610f2192519485947fe0cff05f00000000000000000000000000000000000000000000000000000000865260048601612cbd565b9190610f2193611b60846154dc565b611b87611b6b610619565b73ffffffffffffffffffffffffffffffffffffffff9096168652565b6020850152519586957ffaecb4e400000000000000000000000000000000000000000000000000000000875260048701612c2b565b90501538611b17565b9150506154dc565b50346103595760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126103595773ffffffffffffffffffffffffffffffffffffffff600435611c1e81610422565b16600052600060205260a0604060002065ffffffffffff60018254920154604051926dffffffffffffffffffffffffffff90818116855260ff8160701c161515602086015260781c16604084015263ffffffff8116606084015260201c166080820152f35b60209067ffffffffffffffff8111611c9d575b60051b0190565b611ca5610505565b611c96565b60405190611cb782610535565b604051608083610100830167ffffffffffffffff811184821017611d20575b60405260009283815283602082015283604082015283606082015283838201528360a08201528360c08201528360e082015281528260208201528260408201528260608201520152565b611d28610505565b611cd6565b90611d3782611c83565b611d4460405191826105ab565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0611d728294611c83565b019060005b828110611d8357505050565b602090611d8e611caa565b82828501015201611d77565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020918151811015611ddf575b60051b010190565b611de7611d9a565b611dd7565b9190811015611e2d575b60051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea181360301821215610359570190565b611e35611d9a565b611df6565b6002805414611e495760028055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152fd5b3d15611ed2573d90611eb882610639565b91611ec660405193846105ab565b82523d6000602084013e565b606090565b73ffffffffffffffffffffffffffffffffffffffff168015611f6a57600080809381935af1611f04611ea7565b5015611f0c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f41413931206661696c65642073656e6420746f2062656e6566696369617279006044820152fd5b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4141393020696e76616c69642062656e656669636961727900000000000000006044820152fd5b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff82116103595760200191813603831361035957565b90816020910312610359575190565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b60005b83811061207a5750506000910152565b818101518382015260200161206a565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f6020936120c681518092818752878088019101612067565b0116010190565b906120e76080916108b796946101c0808652850191612028565b9360e0815173ffffffffffffffffffffffffffffffffffffffff80825116602087015260208201516040870152604082015160608701526060820151858701528482015160a087015260a08201511660c086015260c081015182860152015161010084015260208101516101208401526040810151610140840152606081015161016084015201516101808201526101a081840391015261208a565b506040513d6000823e3d90fd5b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b919082039182116121cd57565b61044d612190565b919082018092116121cd57565b905a918160206121fb6060830151936060810190611fc8565b906122348560405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af16000918161230f575b50612308575060206000803e7fdeaddead000000000000000000000000000000000000000000000000000000006000511461229b5761229561228a6108b7945a906121c0565b6080840151906121d5565b91614afc565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9250505090565b61233191925060203d8111612338575b61232981836105ab565b810190612019565b9038612244565b503d61231f565b909291925a9380602061235b6060830151946060810190611fc8565b906123948660405195869485947f1d732756000000000000000000000000000000000000000000000000000000008652600486016120cd565b03816000305af160009181612471575b5061246a575060206000803e7fdeaddead00000000000000000000000000000000000000000000000000000000600051146123fc576123f66123eb6108b795965a906121c0565b6080830151906121d5565b92614ddf565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152600f60408201527f41413935206f7574206f6620676173000000000000000000000000000000000060608201520190565b9450505050565b61248a91925060203d81116123385761232981836105ab565b90386123a4565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146124bf570190565b6124c7612190565b0190565b919081101561250c575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa181360301821215610359570190565b612514611d9a565b6124d5565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe181360301821215610359570180359067ffffffffffffffff821161035957602001918160051b3603831361035957565b356108b781610422565b1561257e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393620696e76616c69642061676772656761746f720000000000000000006044820152fd5b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18236030181121561035957016020813591019167ffffffffffffffff821161035957813603831361035957565b6108b7916126578161263d8461045c565b73ffffffffffffffffffffffffffffffffffffffff169052565b602082013560208201526126f26126a361268861267760408601866125dc565b610160806040880152860191612028565b61269560608601866125dc565b908583036060870152612028565b6080840135608084015260a084013560a084015260c084013560c084015260e084013560e084015261010080850135908401526101206126e5818601866125dc565b9185840390860152612028565b9161270361014091828101906125dc565b929091818503910152612028565b949391929083604087016040885252606086019360608160051b8801019482600090815b848310612754575050505050508460206108b795968503910152612028565b9091929394977fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa08b820301855288357ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea1843603018112156127cf57600191846127bd920161262c565b98602090810196950193019190612735565b8280fd5b908092918237016000815290565b9290936108b796959260c0958552602085015265ffffffffffff8092166040850152166060830152151560808201528160a0820152019061208a565b1561282457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4141393220696e7465726e616c2063616c6c206f6e6c790000000000000000006044820152fd5b9060406108b79260008152816020820152019061208a565b6040906108b793928152816020820152019061208a565b909291925a936128c230331461281d565b8151946040860151955a6113886060830151890101116129e2576108b7966000958051612909575b50505090612903915a9003608084015101943691610682565b91615047565b612938916129349161292f855173ffffffffffffffffffffffffffffffffffffffff1690565b615c12565b1590565b612944575b80806128ea565b61290392919450612953615c24565b908151612967575b5050600193909161293d565b7f1c4fada7374c0a9ee8841fc38afe82932dc0f8e69012e927f061a8bae611a20173ffffffffffffffffffffffffffffffffffffffff6020870151926129d860206129c6835173ffffffffffffffffffffffffffffffffffffffff1690565b9201519560405193849316968361289a565b0390a3388061295b565b7fdeaddead0000000000000000000000000000000000000000000000000000000060005260206000fd5b612a22612a1c6040830183611fc8565b90615c07565b90612a33612a1c6060830183611fc8565b90612ae9612a48612a1c610120840184611fc8565b60405194859360208501956101008201359260e08301359260c08101359260a08201359260808301359273ffffffffffffffffffffffffffffffffffffffff60208201359135168c9693909a9998959261012098959273ffffffffffffffffffffffffffffffffffffffff6101408a019d168952602089015260408801526060870152608086015260a085015260c084015260e08301526101008201520152565b0391612b1b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938481018352826105ab565b51902060408051602081019283523091810191909152466060820152608092830181529091612b4a90826105ab565b51902090565b604051906040820182811067ffffffffffffffff821117612b7b575b60405260006020838281520152565b612b83610505565b612b6c565b906014116103595790601490565b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009035818116939260148110612bcb57505050565b60140360031b82901b16169150565b9060c060a06108b793805184526020810151602085015260408101511515604085015265ffffffffffff80606083015116606086015260808201511660808501520151918160a0820152019061208a565b9294612c8c61044d95612c7a610100959998612c68612c54602097610140808c528b0190612bda565b9b878a019060208091805184520151910152565b80516060890152602001516080880152565b805160a08701526020015160c0860152565b73ffffffffffffffffffffffffffffffffffffffff81511660e0850152015191019060208091805184520151910152565b612d0661044d94612cf4612cdf60a0959998969960e0865260e0860190612bda565b98602085019060208091805184520151910152565b80516060840152602001516080830152565b019060208091805184520151910152565b9081602091031261035957516108b781610422565b9160206108b7938181520191612028565b90612d6c73ffffffffffffffffffffffffffffffffffffffff916108b797959694606085526060850191612028565b941660208201526040818503910152612028565b60009060033d11612d8d57565b905060046000803e60005160e01c90565b600060443d106108b7576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d602484011117612e1a57818401948551938411612e22573d85010160208487010111612e1a57506108b7929101602001906105ab565b949350505050565b50949350505050565b612e386040820182611fc8565b612e50612e448461256d565b93610120810190611fc8565b9290303b1561035957600093612e949160405196879586957f957122ab00000000000000000000000000000000000000000000000000000000875260048701612d3d565b0381305afa9081612f1d575b5061044d576001612eaf612d80565b6308c379a014612ec8575b612ec057565b61044d612183565b612ed0612d9e565b80612edc575b50612eba565b80516000925015612ed657610f21906040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b80610f48612f2a9261057b565b38612ea0565b9190612f3b9061317f565b73ffffffffffffffffffffffffffffffffffffffff929183166130da5761306c57612f659061317f565b9116612ffe57612f725750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602160448201527f41413332207061796d61737465722065787069726564206f72206e6f7420647560648201527f6500000000000000000000000000000000000000000000000000000000000000608482015260a490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413334207369676e6174757265206572726f7200000000000000000000000060608201520190565b610f21836040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601760408201527f414132322065787069726564206f72206e6f742064756500000000000000000060608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601460408201527f41413234207369676e6174757265206572726f7200000000000000000000000060608201520190565b9291906131549061317f565b909273ffffffffffffffffffffffffffffffffffffffff808095169116036130da5761306c57612f65905b80156131d25761318e9061535f565b73ffffffffffffffffffffffffffffffffffffffff65ffffffffffff8060408401511642119081156131c2575b5091511691565b90506020830151164210386131bb565b50600090600090565b156131e257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f41413934206761732076616c756573206f766572666c6f7700000000000000006044820152fd5b916000915a9381519061325382826136b3565b61325c81612a0c565b602084015261329a6effffffffffffffffffffffffffffff60808401516060850151176040850151176101008401359060e0850135171711156131db565b6132a382613775565b6132ae818584613836565b97906132df6129346132d4875173ffffffffffffffffffffffffffffffffffffffff1690565b60208801519061546c565b6133db576132ec43600052565b73ffffffffffffffffffffffffffffffffffffffff61332460a0606097015173ffffffffffffffffffffffffffffffffffffffff1690565b166133c1575b505a810360a0840135106133545760809360c092604087015260608601525a900391013501910152565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413430206f76657220766572696669636174696f6e4761734c696d6974000060608201520190565b909350816133d2929750858461455c565b9590923861332a565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b9290916000925a825161345b81846136b3565b61346483612a0c565b60208501526134a26effffffffffffffffffffffffffffff60808301516060840151176040840151176101008601359060e0870135171711156131db565b6134ab81613775565b6134b78186868b613ba2565b98906134e86129346134dd865173ffffffffffffffffffffffffffffffffffffffff1690565b60208701519061546c565b6135e0576134f543600052565b73ffffffffffffffffffffffffffffffffffffffff61352d60a0606096015173ffffffffffffffffffffffffffffffffffffffff1690565b166135c5575b505a840360a08601351061355f5750604085015260608401526080919060c0905a900391013501910152565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601e60448201527f41413430206f76657220766572696669636174696f6e4761734c696d697400006064820152608490fd5b909250816135d79298508686856147ef565b96909138613533565b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601a60408201527f4141323520696e76616c6964206163636f756e74206e6f6e636500000000000060608201520190565b1561365557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4141393320696e76616c6964207061796d6173746572416e64446174610000006044820152fd5b613725906136dd6136c38261256d565b73ffffffffffffffffffffffffffffffffffffffff168452565b602081013560208401526080810135604084015260a0810135606084015260c0810135608084015260e081013560c084015261010081013560e0840152610120810190611fc8565b90811561376a5761374f61124c6112468460a09461374a601461044d9998101561364e565b612b88565b73ffffffffffffffffffffffffffffffffffffffff16910152565b505060a06000910152565b60a081015173ffffffffffffffffffffffffffffffffffffffff16156137b75760c060035b60ff60408401519116606084015102016080830151019101510290565b60c0600161379a565b6137d86040929594939560608352606083019061262c565b9460208201520152565b9061044d602f60405180947f414132332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b810103600f8101855201836105ab565b916000926000925a936139046020835193613865855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d6138766040830183611fc8565b9084613e0d565b60a086015173ffffffffffffffffffffffffffffffffffffffff16906138a243600052565b85809373ffffffffffffffffffffffffffffffffffffffff809416159889613b3a575b60600151908601516040517f3a871cdd0000000000000000000000000000000000000000000000000000000081529788968795869390600485016137c0565b03938a1690f1829181613b1a575b50613b115750600190613923612d80565b6308c379a014613abd575b50613a50575b613941575b50505a900391565b61396b9073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b613986610a2c82546dffffffffffffffffffffffffffff1690565b8083116139e3576139dc926dffffffffffffffffffffffffffff9103166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b3880613939565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601760408201527f41413231206469646e2774207061792070726566756e6400000000000000000060608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613ac5612d9e565b9081613ad1575061392e565b610f2191613adf91506137e2565b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301612882565b95506139349050565b613b3391925060203d81116123385761232981836105ab565b9038613912565b9450613b80610a2c613b6c8c73ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b546dffffffffffffffffffffffffffff1690565b8b811115613b975750856060835b969150506138c5565b606087918d03613b8e565b90926000936000935a94613beb6020835193613bd2855173ffffffffffffffffffffffffffffffffffffffff1690565b9561387d613be36040830183611fc8565b90848c61412b565b03938a1690f1829181613ded575b50613de45750600190613c0a612d80565b6308c379a014613d8e575b50613d20575b613c29575b5050505a900391565b613c539073ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b91613c6f610a2c84546dffffffffffffffffffffffffffff1690565b90818311613cba575082547fffffffffffffffffffffffffffffffffffff0000000000000000000000000000169190036dffffffffffffffffffffffffffff16179055388080613c20565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601760448201527f41413231206469646e2774207061792070726566756e640000000000000000006064820152608490fd5b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601660408201527f4141323320726576657274656420286f72204f4f47290000000000000000000060608201520190565b613d96612d9e565b9081613da25750613c15565b8691613dae91506137e2565b90610f216040519283927f220266b60000000000000000000000000000000000000000000000000000000084526004840161289a565b9650613c1b9050565b613e0691925060203d81116123385761232981836105ab565b9038613bf9565b909180613e1957505050565b81515173ffffffffffffffffffffffffffffffffffffffff1692833b6140be57606083510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280613e78878760048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156140b1575b600092614091575b508082169586156140245716809503613fb7573b15613f4a5761124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d93613f1193612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a3565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313520696e6974436f6465206d757374206372656174652073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6140aa91925060203d811161146a5761145b81836105ab565b9038613ec7565b6140b9612183565b613ebf565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601f60408201527f414131302073656e64657220616c726561647920636f6e73747275637465640060608201520190565b9290918161413a575b50505050565b82515173ffffffffffffffffffffffffffffffffffffffff1693843b6143e257606084510151604051907f570e1a3600000000000000000000000000000000000000000000000000000000825260208280614199888860048401612d2c565b0381600073ffffffffffffffffffffffffffffffffffffffff95867f00000000000000000000000000000000000000000000000000000000000000001690f19182156143d5575b6000926143b5575b5080821696871561434757168096036142d9573b15614273575061124c6112467fd51a9c61267aa6196961883ecf5ff2da6619c37dac0fa92122513fb32c032d2d9361423393612b88565b602083810151935160a001516040805173ffffffffffffffffffffffffffffffffffffffff9485168152939091169183019190915290a338808080614134565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f4141313520696e6974436f6465206d757374206372656174652073656e6465726064820152608490fd5b610f21826040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152602060408201527f4141313420696e6974436f6465206d7573742072657475726e2073656e64657260608201520190565b610f21846040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601b60408201527f4141313320696e6974436f6465206661696c6564206f72204f4f47000000000060608201520190565b6143ce91925060203d811161146a5761145b81836105ab565b90386141e8565b6143dd612183565b6141e0565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601f60448201527f414131302073656e64657220616c726561647920636f6e7374727563746564006064820152608490fd5b1561444f57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4141343120746f6f206c6974746c6520766572696669636174696f6e476173006044820152fd5b919060408382031261035957825167ffffffffffffffff81116103595783019080601f83011215610359578151916144e483610639565b916144f260405193846105ab565b838352602084830101116103595760209261451291848085019101612067565b92015190565b9061044d602f60405180947f414133332072657665727465643a20000000000000000000000000000000000060208301526138268151809260208686019101612067565b93919260609460009460009380519261459b60a08a86015195614580888811614448565b015173ffffffffffffffffffffffffffffffffffffffff1690565b916145c68373ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b946145e2610a2c87546dffffffffffffffffffffffffffff1690565b968588106147825773ffffffffffffffffffffffffffffffffffffffff60208a98946146588a966dffffffffffffffffffffffffffff8b6146919e03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b015194604051998a98899788937ff465c77e000000000000000000000000000000000000000000000000000000008552600485016137c0565b0395169103f190818391849361475c575b506147555750506001906146b4612d80565b6308c379a014614733575b506146c657565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601660408201527f4141333320726576657274656420286f72204f4f47290000000000000000000060608201520190565b61473b612d9e565b908161474757506146bf565b610f2191613adf9150614518565b9450925050565b90925061477b91503d8085833e61477381836105ab565b8101906144ad565b91386146a2565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b91949293909360609560009560009382519061481660a08b84015193614580848611614448565b936148418573ffffffffffffffffffffffffffffffffffffffff166000526000602052604060002090565b61485c610a2c82546dffffffffffffffffffffffffffff1690565b8781106149b7579273ffffffffffffffffffffffffffffffffffffffff60208a989693946146588a966dffffffffffffffffffffffffffff8d6148d69e9c9a03166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b0395169103f1908183918493614999575b506149915750506001906148f9612d80565b6308c379a014614972575b5061490c5750565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152601660448201527f4141333320726576657274656420286f72204f4f4729000000000000000000006064820152608490fd5b61497a612d9e565b90816149865750614904565b613dae925050614518565b955093505050565b9092506149b091503d8085833e61477381836105ab565b91386148e7565b610f218a6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601e60408201527f41413331207061796d6173746572206465706f73697420746f6f206c6f77000060608201520190565b60031115614a2f57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b929190614a7c6040916002865260606020870152606086019061208a565b930152565b939291906003811015614a2f57604091614a7c91865260606020870152606086019061208a565b9061044d603660405180947f4141353020706f73744f702072657665727465643a20000000000000000000006020830152614aec8151809260208686019101612067565b81010360168101855201836105ab565b929190925a93600091805191614b1183615318565b9260a0810195614b35875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff93908481169081614ca457505050614b76825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f94614bc26020928c614c329551039061553a565b015194896020614c04614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b9a5173ffffffffffffffffffffffffffffffffffffffff1690565b9401519785604051968796169a16988590949392606092608083019683521515602083015260408201520152565b0390a4565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152602060408201527f414135312070726566756e642062656c6f772061637475616c476173436f737460608201520190565b9a918051614cb4575b5050614b78565b6060850151600099509091803b15614ddb579189918983614d07956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081614dc8575b50614dc3576001614d20612d80565b6308c379a014614da4575b614d37575b3880614cad565b6040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b614dac612d9e565b80614db75750614d2b565b613adf610f2191614aa8565b614d30565b80610f48614dd59261057b565b38614d11565b8980fd5b9392915a90600092805190614df382615318565b9360a0830196614e17885173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff95908681169081614f0d57505050614e58845173ffffffffffffffffffffffffffffffffffffffff1690565b915b5a9003019485029860408301908a825110614ea757507f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f949392614bc2614c32938c60209451039061553a565b604080517f220266b600000000000000000000000000000000000000000000000000000000815260048101929092526024820152602060448201527f414135312070726566756e642062656c6f772061637475616c476173436f73746064820152608490fd5b93918051614f1d575b5050614e5a565b606087015160009a509091803b1561504357918a918a83614f70956040518097819682957fa9a234090000000000000000000000000000000000000000000000000000000084528c029060048401614a5e565b0393f19081615030575b5061502b576001614f89612d80565b6308c379a01461500e575b614fa0575b3880614f16565b610f218b6040519182917f220266b600000000000000000000000000000000000000000000000000000000835260048301608091815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b615016612d9e565b806150215750614f94565b613dae8d91614aa8565b614f99565b80610f4861503d9261057b565b38614f7a565b8a80fd5b909392915a9480519161505983615318565b9260a081019561507d875173ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff938185169182615165575050506150bd825173ffffffffffffffffffffffffffffffffffffffff1690565b985b5a90030193840297604084019089825110614c37577f49628fd1471006c1482da88028e9ce4dbb080b815c9b0344d39e5a8e6ec1419f946151096020928c614c329551039061553a565b61511288614a25565b015194896020615139614be9865173ffffffffffffffffffffffffffffffffffffffff1690565b940151604080519182529815602082015297880152606087015290821695909116939081906080820190565b9a918151615175575b50506150bf565b8784026151818a614a25565b60028a1461520c576060860151823b15610359576151d493600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f180156151ff575b6151ec575b505b388061516e565b80610f486151f99261057b565b386151e3565b615207612183565b6151de565b6060860151823b156103595761525793600080948d604051978896879586937fa9a2340900000000000000000000000000000000000000000000000000000000855260048501614a81565b0393f19081615305575b50615300576001615270612d80565b6308c379a0146152ed575b156151e5576040517f220266b600000000000000000000000000000000000000000000000000000000815280610f21600482016080906000815260406020820152601260408201527f4141353020706f73744f7020726576657274000000000000000000000000000060608201520190565b6152f5612d9e565b80614db7575061527b565b6151e5565b80610f486153129261057b565b38615261565b60e060c082015191015180821461533c57480180821015615337575090565b905090565b5090565b6040519061534d8261058f565b60006040838281528260208201520152565b615367615340565b5065ffffffffffff808260a01c1680156153b3575b604051926153898461058f565b73ffffffffffffffffffffffffffffffffffffffff8116845260d01c602084015216604082015290565b508061537c565b6153cf6153d5916153c9615340565b5061535f565b9161535f565b9073ffffffffffffffffffffffffffffffffffffffff9182825116928315615461575b65ffffffffffff928391826040816020850151169301511693836040816020840151169201511690808410615459575b50808511615451575b506040519561543f8761058f565b16855216602084015216604082015290565b935038615431565b925038615428565b8151811693506153f8565b73ffffffffffffffffffffffffffffffffffffffff16600052600160205267ffffffffffffffff6154c88260401c60406000209077ffffffffffffffffffffffffffffffffffffffffffffffff16600052602052604060002090565b918254926154d584612491565b9055161490565b9073ffffffffffffffffffffffffffffffffffffffff6154fa612b50565b9216600052600060205263ffffffff600160406000206dffffffffffffffffffffffffffff815460781c1685520154166020830152565b61044d3361562b565b73ffffffffffffffffffffffffffffffffffffffff16600052600060205260406000206dffffffffffffffffffffffffffff8082541692830180931161561e575b8083116155c05761044d92166dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f6465706f736974206f766572666c6f77000000000000000000000000000000006044820152fd5b615626612190565b61557b565b73ffffffffffffffffffffffffffffffffffffffff9061564b348261553a565b168060005260006020527f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c460206dffffffffffffffffffffffffffff60406000205416604051908152a2565b1561569e57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f6d757374207370656369667920756e7374616b652064656c61790000000000006044820152fd5b1561570357565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f63616e6e6f7420646563726561736520756e7374616b652074696d65000000006044820152fd5b1561576857565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6e6f207374616b652073706563696669656400000000000000000000000000006044820152fd5b156157cd57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b65206f766572666c6f770000000000000000000000000000000000006044820152fd5b9065ffffffffffff6080600161044d9461588b6dffffffffffffffffffffffffffff86511682906dffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffff0000000000000000000000000000825416179055565b602085015115156eff000000000000000000000000000082549160701b16807fffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffff83161783557fffffff000000000000000000000000000000ffffffffffffffffffffffffffff7cffffffffffffffffffffffffffff000000000000000000000000000000604089015160781b16921617178155019263ffffffff6060820151167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000008554161784550151167fffffffffffffffffffffffffffffffffffffffffffff000000000000ffffffff69ffffffffffff0000000083549260201b169116179055565b1561599657565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f616c726561647920756e7374616b696e670000000000000000000000000000006044820152fd5b91909165ffffffffffff808094169116019182116121cd57565b15615a1557565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f4e6f207374616b6520746f2077697468647261770000000000000000000000006044820152fd5b15615a7a57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f6d7573742063616c6c20756e6c6f636b5374616b6528292066697273740000006044820152fd5b15615adf57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5374616b65207769746864726177616c206973206e6f742064756500000000006044820152fd5b15615b4457565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661696c656420746f207769746864726177207374616b6500000000000000006044820152fd5b15615ba957565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6661696c656420746f20776974686472617700000000000000000000000000006044820152fd5b816040519182372090565b9060009283809360208451940192f190565b3d610800808211615c4b575b50604051906020818301016040528082526000602083013e90565b905038615c3056fea2646970667358221220a706d8b02d7086d80e9330811f5af84b2614abdc5e9a1f2260126070a31d7cee64736f6c63430008110033"
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/deployments/sepolia/solcInputs/a4c52f0671aad8941c53d6ead2063803.json b/lib/SoulWalletCore/lib/account-abstraction/deployments/sepolia/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
new file mode 100644
index 00000000..dd58ba5a
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/deployments/sepolia/solcInputs/a4c52f0671aad8941c53d6ead2063803.json
@@ -0,0 +1,68 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "@openzeppelin/contracts/security/ReentrancyGuard.sol": {
+ "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor() {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and making it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n _nonReentrantBefore();\n _;\n _nonReentrantAfter();\n }\n\n function _nonReentrantBefore() private {\n // On the first call to nonReentrant, _status will be _NOT_ENTERED\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n }\n\n function _nonReentrantAfter() private {\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n"
+ },
+ "contracts/core/EntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n\nimport \"../interfaces/IAccount.sol\";\nimport \"../interfaces/IPaymaster.sol\";\nimport \"../interfaces/IEntryPoint.sol\";\n\nimport \"../utils/Exec.sol\";\nimport \"./StakeManager.sol\";\nimport \"./SenderCreator.sol\";\nimport \"./Helpers.sol\";\nimport \"./NonceManager.sol\";\nimport \"@openzeppelin/contracts/security/ReentrancyGuard.sol\";\n\ncontract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard {\n\n using UserOperationLib for UserOperation;\n\n SenderCreator private immutable senderCreator = new SenderCreator();\n\n // internal value used during simulation: need to query aggregator.\n address private constant SIMULATE_FIND_AGGREGATOR = address(1);\n\n // marker for inner call revert on out of gas\n bytes32 private constant INNER_OUT_OF_GAS = hex'deaddead';\n\n uint256 private constant REVERT_REASON_MAX_LEN = 2048;\n\n /**\n * for simulation purposes, validateUserOp (and validatePaymasterUserOp) must return this value\n * in case of signature failure, instead of revert.\n */\n uint256 public constant SIG_VALIDATION_FAILED = 1;\n\n /**\n * compensate the caller's beneficiary address with the collected fees of all UserOperations.\n * @param beneficiary the address to receive the fees\n * @param amount amount to transfer.\n */\n function _compensate(address payable beneficiary, uint256 amount) internal {\n require(beneficiary != address(0), \"AA90 invalid beneficiary\");\n (bool success,) = beneficiary.call{value : amount}(\"\");\n require(success, \"AA91 failed send to beneficiary\");\n }\n\n /**\n * execute a user op\n * @param opIndex index into the opInfo array\n * @param userOp the userOp to execute\n * @param opInfo the opInfo filled by validatePrepayment for this userOp.\n * @return collected the total amount this userOp paid.\n */\n function _executeUserOp(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory opInfo) private returns (uint256 collected) {\n uint256 preGas = gasleft();\n bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);\n\n try this.innerHandleOp(userOp.callData, opInfo, context) returns (uint256 _actualGasCost) {\n collected = _actualGasCost;\n } catch {\n bytes32 innerRevertCode;\n assembly {\n returndatacopy(0, 0, 32)\n innerRevertCode := mload(0)\n }\n // handleOps was called with gas limit too low. abort entire bundle.\n if (innerRevertCode == INNER_OUT_OF_GAS) {\n //report paymaster, since if it is not deliberately caused by the bundler,\n // it must be a revert caused by paymaster.\n revert FailedOp(opIndex, \"AA95 out of gas\");\n }\n\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n collected = _handlePostOp(opIndex, IPaymaster.PostOpMode.postOpReverted, opInfo, context, actualGas);\n }\n }\n\n /**\n * Execute a batch of UserOperations.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) public nonReentrant {\n\n uint256 opslen = ops.length;\n UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);\n\n unchecked {\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[i];\n (uint256 validationData, uint256 pmValidationData) = _validatePrepayment(i, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, pmValidationData, address(0));\n }\n\n uint256 collected = 0;\n emit BeforeExecution();\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(i, ops[i], opInfos[i]);\n }\n\n _compensate(beneficiary, collected);\n } //unchecked\n }\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) public nonReentrant {\n\n uint256 opasLen = opsPerAggregator.length;\n uint256 totalOps = 0;\n for (uint256 i = 0; i < opasLen; i++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[i];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n //address(1) is special marker of \"signature error\"\n require(address(aggregator) != address(1), \"AA96 invalid aggregator\");\n\n if (address(aggregator) != address(0)) {\n // solhint-disable-next-line no-empty-blocks\n try aggregator.validateSignatures(ops, opa.signature) {}\n catch {\n revert SignatureValidationFailed(address(aggregator));\n }\n }\n\n totalOps += ops.length;\n }\n\n UserOpInfo[] memory opInfos = new UserOpInfo[](totalOps);\n\n emit BeforeExecution();\n\n uint256 opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n UserOperation[] calldata ops = opa.userOps;\n IAggregator aggregator = opa.aggregator;\n\n uint256 opslen = ops.length;\n for (uint256 i = 0; i < opslen; i++) {\n UserOpInfo memory opInfo = opInfos[opIndex];\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(opIndex, ops[i], opInfo);\n _validateAccountAndPaymasterValidationData(i, validationData, paymasterValidationData, address(aggregator));\n opIndex++;\n }\n }\n\n uint256 collected = 0;\n opIndex = 0;\n for (uint256 a = 0; a < opasLen; a++) {\n UserOpsPerAggregator calldata opa = opsPerAggregator[a];\n emit SignatureAggregatorChanged(address(opa.aggregator));\n UserOperation[] calldata ops = opa.userOps;\n uint256 opslen = ops.length;\n\n for (uint256 i = 0; i < opslen; i++) {\n collected += _executeUserOp(opIndex, ops[i], opInfos[opIndex]);\n opIndex++;\n }\n }\n emit SignatureAggregatorChanged(address(0));\n\n _compensate(beneficiary, collected);\n }\n\n /// @inheritdoc IEntryPoint\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external override {\n\n UserOpInfo memory opInfo;\n _simulationOnlyValidations(op);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, op, opInfo);\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n\n numberMarker();\n uint256 paid = _executeUserOp(0, op, opInfo);\n numberMarker();\n bool targetSuccess;\n bytes memory targetResult;\n if (target != address(0)) {\n (targetSuccess, targetResult) = target.call(targetCallData);\n }\n revert ExecutionResult(opInfo.preOpGas, paid, data.validAfter, data.validUntil, targetSuccess, targetResult);\n }\n\n\n // A memory copy of UserOp static fields only.\n // Excluding: callData, initCode and signature. Replacing paymasterAndData with paymaster.\n struct MemoryUserOp {\n address sender;\n uint256 nonce;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n address paymaster;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n }\n\n struct UserOpInfo {\n MemoryUserOp mUserOp;\n bytes32 userOpHash;\n uint256 prefund;\n uint256 contextOffset;\n uint256 preOpGas;\n }\n\n /**\n * inner function to handle a UserOperation.\n * Must be declared \"external\" to open a call context, but it can only be called by handleOps.\n */\n function innerHandleOp(bytes memory callData, UserOpInfo memory opInfo, bytes calldata context) external returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n require(msg.sender == address(this), \"AA92 internal call only\");\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n\n uint callGasLimit = mUserOp.callGasLimit;\n unchecked {\n // handleOps was called with gas limit too low. abort entire bundle.\n if (gasleft() < callGasLimit + mUserOp.verificationGasLimit + 5000) {\n assembly {\n mstore(0, INNER_OUT_OF_GAS)\n revert(0, 32)\n }\n }\n }\n\n IPaymaster.PostOpMode mode = IPaymaster.PostOpMode.opSucceeded;\n if (callData.length > 0) {\n bool success = Exec.call(mUserOp.sender, 0, callData, callGasLimit);\n if (!success) {\n bytes memory result = Exec.getReturnData(REVERT_REASON_MAX_LEN);\n if (result.length > 0) {\n emit UserOperationRevertReason(opInfo.userOpHash, mUserOp.sender, mUserOp.nonce, result);\n }\n mode = IPaymaster.PostOpMode.opReverted;\n }\n }\n\n unchecked {\n uint256 actualGas = preGas - gasleft() + opInfo.preOpGas;\n //note: opIndex is ignored (relevant only if mode==postOpReverted, which is only possible outside of innerHandleOp)\n return _handlePostOp(0, mode, opInfo, context, actualGas);\n }\n }\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) public view returns (bytes32) {\n return keccak256(abi.encode(userOp.hash(), address(this), block.chainid));\n }\n\n /**\n * copy general fields from userOp into the memory opInfo structure.\n */\n function _copyUserOpToMemory(UserOperation calldata userOp, MemoryUserOp memory mUserOp) internal pure {\n mUserOp.sender = userOp.sender;\n mUserOp.nonce = userOp.nonce;\n mUserOp.callGasLimit = userOp.callGasLimit;\n mUserOp.verificationGasLimit = userOp.verificationGasLimit;\n mUserOp.preVerificationGas = userOp.preVerificationGas;\n mUserOp.maxFeePerGas = userOp.maxFeePerGas;\n mUserOp.maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes calldata paymasterAndData = userOp.paymasterAndData;\n if (paymasterAndData.length > 0) {\n require(paymasterAndData.length >= 20, \"AA93 invalid paymasterAndData\");\n mUserOp.paymaster = address(bytes20(paymasterAndData[: 20]));\n } else {\n mUserOp.paymaster = address(0);\n }\n }\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external {\n UserOpInfo memory outOpInfo;\n\n _simulationOnlyValidations(userOp);\n (uint256 validationData, uint256 paymasterValidationData) = _validatePrepayment(0, userOp, outOpInfo);\n StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);\n StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);\n StakeInfo memory factoryInfo;\n {\n bytes calldata initCode = userOp.initCode;\n address factory = initCode.length >= 20 ? address(bytes20(initCode[0 : 20])) : address(0);\n factoryInfo = _getStakeInfo(factory);\n }\n\n ValidationData memory data = _intersectTimeRange(validationData, paymasterValidationData);\n address aggregator = data.aggregator;\n bool sigFailed = aggregator == address(1);\n ReturnInfo memory returnInfo = ReturnInfo(outOpInfo.preOpGas, outOpInfo.prefund,\n sigFailed, data.validAfter, data.validUntil, getMemoryBytesFromOffset(outOpInfo.contextOffset));\n\n if (aggregator != address(0) && aggregator != address(1)) {\n AggregatorStakeInfo memory aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));\n revert ValidationResultWithAggregation(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);\n }\n revert ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo);\n\n }\n\n function _getRequiredPrefund(MemoryUserOp memory mUserOp) internal pure returns (uint256 requiredPrefund) {\n unchecked {\n //when using a Paymaster, the verificationGasLimit is used also to as a limit for the postOp call.\n // our security model might call postOp eventually twice\n uint256 mul = mUserOp.paymaster != address(0) ? 3 : 1;\n uint256 requiredGas = mUserOp.callGasLimit + mUserOp.verificationGasLimit * mul + mUserOp.preVerificationGas;\n\n requiredPrefund = requiredGas * mUserOp.maxFeePerGas;\n }\n }\n\n // create the sender's contract if needed.\n function _createSenderIfNeeded(uint256 opIndex, UserOpInfo memory opInfo, bytes calldata initCode) internal {\n if (initCode.length != 0) {\n address sender = opInfo.mUserOp.sender;\n if (sender.code.length != 0) revert FailedOp(opIndex, \"AA10 sender already constructed\");\n address sender1 = senderCreator.createSender{gas : opInfo.mUserOp.verificationGasLimit}(initCode);\n if (sender1 == address(0)) revert FailedOp(opIndex, \"AA13 initCode failed or OOG\");\n if (sender1 != sender) revert FailedOp(opIndex, \"AA14 initCode must return sender\");\n if (sender1.code.length == 0) revert FailedOp(opIndex, \"AA15 initCode must create sender\");\n address factory = address(bytes20(initCode[0 : 20]));\n emit AccountDeployed(opInfo.userOpHash, sender, factory, opInfo.mUserOp.paymaster);\n }\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes calldata initCode) public {\n address sender = senderCreator.createSender(initCode);\n revert SenderAddressResult(sender);\n }\n\n function _simulationOnlyValidations(UserOperation calldata userOp) internal view {\n // solhint-disable-next-line no-empty-blocks\n try this._validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData) {}\n catch Error(string memory revertReason) {\n if (bytes(revertReason).length != 0) {\n revert FailedOp(0, revertReason);\n }\n }\n }\n\n /**\n * Called only during simulation.\n * This function always reverts to prevent warm/cold storage differentiation in simulation vs execution.\n */\n function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData) external view {\n if (initCode.length == 0 && sender.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA20 account not deployed\");\n }\n if (paymasterAndData.length >= 20) {\n address paymaster = address(bytes20(paymasterAndData[0 : 20]));\n if (paymaster.code.length == 0) {\n // it would revert anyway. but give a meaningful message\n revert(\"AA30 paymaster not deployed\");\n }\n }\n // always revert\n revert(\"\");\n }\n\n /**\n * call account.validateUserOp.\n * revert (with FailedOp) in case validateUserOp reverts, or account didn't send required prefund.\n * decrement account's deposit if needed\n */\n function _validateAccountPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPrefund)\n internal returns (uint256 gasUsedByValidateAccountPrepayment, uint256 validationData) {\n unchecked {\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n address sender = mUserOp.sender;\n _createSenderIfNeeded(opIndex, opInfo, op.initCode);\n address paymaster = mUserOp.paymaster;\n numberMarker();\n uint256 missingAccountFunds = 0;\n if (paymaster == address(0)) {\n uint256 bal = balanceOf(sender);\n missingAccountFunds = bal > requiredPrefund ? 0 : requiredPrefund - bal;\n }\n try IAccount(sender).validateUserOp{gas : mUserOp.verificationGasLimit}(op, opInfo.userOpHash, missingAccountFunds)\n returns (uint256 _validationData) {\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA23 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA23 reverted (or OOG)\");\n }\n if (paymaster == address(0)) {\n DepositInfo storage senderInfo = deposits[sender];\n uint256 deposit = senderInfo.deposit;\n if (requiredPrefund > deposit) {\n revert FailedOp(opIndex, \"AA21 didn't pay prefund\");\n }\n senderInfo.deposit = uint112(deposit - requiredPrefund);\n }\n gasUsedByValidateAccountPrepayment = preGas - gasleft();\n }\n }\n\n /**\n * In case the request has a paymaster:\n * Validate paymaster has enough deposit.\n * Call paymaster.validatePaymasterUserOp.\n * Revert with proper FailedOp in case paymaster reverts.\n * Decrement paymaster's deposit\n */\n function _validatePaymasterPrepayment(uint256 opIndex, UserOperation calldata op, UserOpInfo memory opInfo, uint256 requiredPreFund, uint256 gasUsedByValidateAccountPrepayment)\n internal returns (bytes memory context, uint256 validationData) {\n unchecked {\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 verificationGasLimit = mUserOp.verificationGasLimit;\n require(verificationGasLimit > gasUsedByValidateAccountPrepayment, \"AA41 too little verificationGas\");\n uint256 gas = verificationGasLimit - gasUsedByValidateAccountPrepayment;\n\n address paymaster = mUserOp.paymaster;\n DepositInfo storage paymasterInfo = deposits[paymaster];\n uint256 deposit = paymasterInfo.deposit;\n if (deposit < requiredPreFund) {\n revert FailedOp(opIndex, \"AA31 paymaster deposit too low\");\n }\n paymasterInfo.deposit = uint112(deposit - requiredPreFund);\n try IPaymaster(paymaster).validatePaymasterUserOp{gas : gas}(op, opInfo.userOpHash, requiredPreFund) returns (bytes memory _context, uint256 _validationData){\n context = _context;\n validationData = _validationData;\n } catch Error(string memory revertReason) {\n revert FailedOp(opIndex, string.concat(\"AA33 reverted: \", revertReason));\n } catch {\n revert FailedOp(opIndex, \"AA33 reverted (or OOG)\");\n }\n }\n }\n\n /**\n * revert if either account validationData or paymaster validationData is expired\n */\n function _validateAccountAndPaymasterValidationData(uint256 opIndex, uint256 validationData, uint256 paymasterValidationData, address expectedAggregator) internal view {\n (address aggregator, bool outOfTimeRange) = _getValidationData(validationData);\n if (expectedAggregator != aggregator) {\n revert FailedOp(opIndex, \"AA24 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA22 expired or not due\");\n }\n //pmAggregator is not a real signature aggregator: we don't have logic to handle it as address.\n // non-zero address means that the paymaster fails due to some signature check (which is ok only during estimation)\n address pmAggregator;\n (pmAggregator, outOfTimeRange) = _getValidationData(paymasterValidationData);\n if (pmAggregator != address(0)) {\n revert FailedOp(opIndex, \"AA34 signature error\");\n }\n if (outOfTimeRange) {\n revert FailedOp(opIndex, \"AA32 paymaster expired or not due\");\n }\n }\n\n function _getValidationData(uint256 validationData) internal view returns (address aggregator, bool outOfTimeRange) {\n if (validationData == 0) {\n return (address(0), false);\n }\n ValidationData memory data = _parseValidationData(validationData);\n // solhint-disable-next-line not-rely-on-time\n outOfTimeRange = block.timestamp > data.validUntil || block.timestamp < data.validAfter;\n aggregator = data.aggregator;\n }\n\n /**\n * validate account and paymaster (if defined).\n * also make sure total validation doesn't exceed verificationGasLimit\n * this method is called off-chain (simulateValidation()) and on-chain (from handleOps)\n * @param opIndex the index of this userOp into the \"opInfos\" array\n * @param userOp the userOp to validate\n */\n function _validatePrepayment(uint256 opIndex, UserOperation calldata userOp, UserOpInfo memory outOpInfo)\n private returns (uint256 validationData, uint256 paymasterValidationData) {\n\n uint256 preGas = gasleft();\n MemoryUserOp memory mUserOp = outOpInfo.mUserOp;\n _copyUserOpToMemory(userOp, mUserOp);\n outOpInfo.userOpHash = getUserOpHash(userOp);\n\n // validate all numeric values in userOp are well below 128 bit, so they can safely be added\n // and multiplied without causing overflow\n uint256 maxGasValues = mUserOp.preVerificationGas | mUserOp.verificationGasLimit | mUserOp.callGasLimit |\n userOp.maxFeePerGas | userOp.maxPriorityFeePerGas;\n require(maxGasValues <= type(uint120).max, \"AA94 gas values overflow\");\n\n uint256 gasUsedByValidateAccountPrepayment;\n (uint256 requiredPreFund) = _getRequiredPrefund(mUserOp);\n (gasUsedByValidateAccountPrepayment, validationData) = _validateAccountPrepayment(opIndex, userOp, outOpInfo, requiredPreFund);\n\n if (!_validateAndUpdateNonce(mUserOp.sender, mUserOp.nonce)) {\n revert FailedOp(opIndex, \"AA25 invalid account nonce\");\n }\n\n //a \"marker\" where account opcode validation is done and paymaster opcode validation is about to start\n // (used only by off-chain simulateValidation)\n numberMarker();\n\n bytes memory context;\n if (mUserOp.paymaster != address(0)) {\n (context, paymasterValidationData) = _validatePaymasterPrepayment(opIndex, userOp, outOpInfo, requiredPreFund, gasUsedByValidateAccountPrepayment);\n }\n unchecked {\n uint256 gasUsed = preGas - gasleft();\n\n if (userOp.verificationGasLimit < gasUsed) {\n revert FailedOp(opIndex, \"AA40 over verificationGasLimit\");\n }\n outOpInfo.prefund = requiredPreFund;\n outOpInfo.contextOffset = getOffsetOfMemoryBytes(context);\n outOpInfo.preOpGas = preGas - gasleft() + userOp.preVerificationGas;\n }\n }\n\n /**\n * process post-operation.\n * called just after the callData is executed.\n * if a paymaster is defined and its validation returned a non-empty context, its postOp is called.\n * the excess amount is refunded to the account (or paymaster - if it was used in the request)\n * @param opIndex index in the batch\n * @param mode - whether is called from innerHandleOp, or outside (postOpReverted)\n * @param opInfo userOp fields and info collected during validation\n * @param context the context returned in validatePaymasterUserOp\n * @param actualGas the gas used so far by this user operation\n */\n function _handlePostOp(uint256 opIndex, IPaymaster.PostOpMode mode, UserOpInfo memory opInfo, bytes memory context, uint256 actualGas) private returns (uint256 actualGasCost) {\n uint256 preGas = gasleft();\n unchecked {\n address refundAddress;\n MemoryUserOp memory mUserOp = opInfo.mUserOp;\n uint256 gasPrice = getUserOpGasPrice(mUserOp);\n\n address paymaster = mUserOp.paymaster;\n if (paymaster == address(0)) {\n refundAddress = mUserOp.sender;\n } else {\n refundAddress = paymaster;\n if (context.length > 0) {\n actualGasCost = actualGas * gasPrice;\n if (mode != IPaymaster.PostOpMode.postOpReverted) {\n IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost);\n } else {\n // solhint-disable-next-line no-empty-blocks\n try IPaymaster(paymaster).postOp{gas : mUserOp.verificationGasLimit}(mode, context, actualGasCost) {}\n catch Error(string memory reason) {\n revert FailedOp(opIndex, string.concat(\"AA50 postOp reverted: \", reason));\n }\n catch {\n revert FailedOp(opIndex, \"AA50 postOp revert\");\n }\n }\n }\n }\n actualGas += preGas - gasleft();\n actualGasCost = actualGas * gasPrice;\n if (opInfo.prefund < actualGasCost) {\n revert FailedOp(opIndex, \"AA51 prefund below actualGasCost\");\n }\n uint256 refund = opInfo.prefund - actualGasCost;\n _incrementDeposit(refundAddress, refund);\n bool success = mode == IPaymaster.PostOpMode.opSucceeded;\n emit UserOperationEvent(opInfo.userOpHash, mUserOp.sender, mUserOp.paymaster, mUserOp.nonce, success, actualGasCost, actualGas);\n } // unchecked\n }\n\n /**\n * the gas price this UserOp agrees to pay.\n * relayer/block builder might submit the TX with higher priorityFee, but the user should not\n */\n function getUserOpGasPrice(MemoryUserOp memory mUserOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = mUserOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = mUserOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n function getOffsetOfMemoryBytes(bytes memory data) internal pure returns (uint256 offset) {\n assembly {offset := data}\n }\n\n function getMemoryBytesFromOffset(uint256 offset) internal pure returns (bytes memory data) {\n assembly {data := offset}\n }\n\n //place the NUMBER opcode in the code.\n // this is used as a marker during simulation, as this OP is completely banned from the simulated code of the\n // account and paymaster.\n function numberMarker() internal view {\n assembly {mstore(0, number())}\n }\n}\n\n"
+ },
+ "contracts/core/Helpers.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\n/**\n * returned data from validateUserOp.\n * validateUserOp returns a uint256, with is created by `_packedValidationData` and parsed by `_parseValidationData`\n * @param aggregator - address(0) - the account validated the signature by itself.\n * address(1) - the account failed to validate the signature.\n * otherwise - this is an address of a signature aggregator that must be used to validate the signature.\n * @param validAfter - this UserOp is valid only after this timestamp.\n * @param validaUntil - this UserOp is valid only up to this timestamp.\n */\n struct ValidationData {\n address aggregator;\n uint48 validAfter;\n uint48 validUntil;\n }\n\n//extract sigFailed, validAfter, validUntil.\n// also convert zero validUntil to type(uint48).max\n function _parseValidationData(uint validationData) pure returns (ValidationData memory data) {\n address aggregator = address(uint160(validationData));\n uint48 validUntil = uint48(validationData >> 160);\n if (validUntil == 0) {\n validUntil = type(uint48).max;\n }\n uint48 validAfter = uint48(validationData >> (48 + 160));\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n// intersect account and paymaster ranges.\n function _intersectTimeRange(uint256 validationData, uint256 paymasterValidationData) pure returns (ValidationData memory) {\n ValidationData memory accountValidationData = _parseValidationData(validationData);\n ValidationData memory pmValidationData = _parseValidationData(paymasterValidationData);\n address aggregator = accountValidationData.aggregator;\n if (aggregator == address(0)) {\n aggregator = pmValidationData.aggregator;\n }\n uint48 validAfter = accountValidationData.validAfter;\n uint48 validUntil = accountValidationData.validUntil;\n uint48 pmValidAfter = pmValidationData.validAfter;\n uint48 pmValidUntil = pmValidationData.validUntil;\n\n if (validAfter < pmValidAfter) validAfter = pmValidAfter;\n if (validUntil > pmValidUntil) validUntil = pmValidUntil;\n return ValidationData(aggregator, validAfter, validUntil);\n }\n\n/**\n * helper to pack the return value for validateUserOp\n * @param data - the ValidationData to pack\n */\n function _packValidationData(ValidationData memory data) pure returns (uint256) {\n return uint160(data.aggregator) | (uint256(data.validUntil) << 160) | (uint256(data.validAfter) << (160 + 48));\n }\n\n/**\n * helper to pack the return value for validateUserOp, when not using an aggregator\n * @param sigFailed - true for signature failure, false for success\n * @param validUntil last timestamp this UserOperation is valid (or zero for infinite)\n * @param validAfter first timestamp this UserOperation is valid\n */\n function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) pure returns (uint256) {\n return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48));\n }\n\n/**\n * keccak function over calldata.\n * @dev copy calldata into memory, do keccak and drop allocated memory. Strangely, this is more efficient than letting solidity do it.\n */\n function calldataKeccak(bytes calldata data) pure returns (bytes32 ret) {\n assembly {\n let mem := mload(0x40)\n let len := data.length\n calldatacopy(mem, data.offset, len)\n ret := keccak256(mem, len)\n }\n }\n\n"
+ },
+ "contracts/core/NonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IEntryPoint.sol\";\n\n/**\n * nonce management functionality\n */\ncontract NonceManager is INonceManager {\n\n /**\n * The next valid sequence number for a given nonce key.\n */\n mapping(address => mapping(uint192 => uint256)) public nonceSequenceNumber;\n\n function getNonce(address sender, uint192 key)\n public view override returns (uint256 nonce) {\n return nonceSequenceNumber[sender][key] | (uint256(key) << 64);\n }\n\n // allow an account to manually increment its own nonce.\n // (mainly so that during construction nonce can be made non-zero,\n // to \"absorb\" the gas cost of first nonce increment to 1st transaction (construction),\n // not to 2nd transaction)\n function incrementNonce(uint192 key) public override {\n nonceSequenceNumber[msg.sender][key]++;\n }\n\n /**\n * validate nonce uniqueness for this account.\n * called just after validateUserOp()\n */\n function _validateAndUpdateNonce(address sender, uint256 nonce) internal returns (bool) {\n\n uint192 key = uint192(nonce >> 64);\n uint64 seq = uint64(nonce);\n return nonceSequenceNumber[sender][key]++ == seq;\n }\n\n}\n"
+ },
+ "contracts/core/SenderCreator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/**\n * helper contract for EntryPoint, to call userOp.initCode from a \"neutral\" address,\n * which is explicitly not the entryPoint itself.\n */\ncontract SenderCreator {\n\n /**\n * call the \"initCode\" factory to create and return the sender account address\n * @param initCode the initCode value from a UserOp. contains 20 bytes of factory address, followed by calldata\n * @return sender the returned address of the created account, or zero address on failure.\n */\n function createSender(bytes calldata initCode) external returns (address sender) {\n address factory = address(bytes20(initCode[0 : 20]));\n bytes memory initCallData = initCode[20 :];\n bool success;\n /* solhint-disable no-inline-assembly */\n assembly {\n success := call(gas(), factory, 0, add(initCallData, 0x20), mload(initCallData), 0, 32)\n sender := mload(0)\n }\n if (!success) {\n sender = address(0);\n }\n }\n}\n"
+ },
+ "contracts/core/StakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\nimport \"../interfaces/IStakeManager.sol\";\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable not-rely-on-time */\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by a paymaster.\n */\nabstract contract StakeManager is IStakeManager {\n\n /// maps paymaster to their deposits and stakes\n mapping(address => DepositInfo) public deposits;\n\n /// @inheritdoc IStakeManager\n function getDepositInfo(address account) public view returns (DepositInfo memory info) {\n return deposits[account];\n }\n\n // internal method to return just the stake info\n function _getStakeInfo(address addr) internal view returns (StakeInfo memory info) {\n DepositInfo storage depositInfo = deposits[addr];\n info.stake = depositInfo.stake;\n info.unstakeDelaySec = depositInfo.unstakeDelaySec;\n }\n\n /// return the deposit (for gas payment) of the account\n function balanceOf(address account) public view returns (uint256) {\n return deposits[account].deposit;\n }\n\n receive() external payable {\n depositTo(msg.sender);\n }\n\n function _incrementDeposit(address account, uint256 amount) internal {\n DepositInfo storage info = deposits[account];\n uint256 newAmount = info.deposit + amount;\n require(newAmount <= type(uint112).max, \"deposit overflow\");\n info.deposit = uint112(newAmount);\n }\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) public payable {\n _incrementDeposit(account, msg.value);\n DepositInfo storage info = deposits[account];\n emit Deposited(account, info.deposit);\n }\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 unstakeDelaySec) public payable {\n DepositInfo storage info = deposits[msg.sender];\n require(unstakeDelaySec > 0, \"must specify unstake delay\");\n require(unstakeDelaySec >= info.unstakeDelaySec, \"cannot decrease unstake time\");\n uint256 stake = info.stake + msg.value;\n require(stake > 0, \"no stake specified\");\n require(stake <= type(uint112).max, \"stake overflow\");\n deposits[msg.sender] = DepositInfo(\n info.deposit,\n true,\n uint112(stake),\n unstakeDelaySec,\n 0\n );\n emit StakeLocked(msg.sender, stake, unstakeDelaySec);\n }\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external {\n DepositInfo storage info = deposits[msg.sender];\n require(info.unstakeDelaySec != 0, \"not staked\");\n require(info.staked, \"already unstaking\");\n uint48 withdrawTime = uint48(block.timestamp) + info.unstakeDelaySec;\n info.withdrawTime = withdrawTime;\n info.staked = false;\n emit StakeUnlocked(msg.sender, withdrawTime);\n }\n\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external {\n DepositInfo storage info = deposits[msg.sender];\n uint256 stake = info.stake;\n require(stake > 0, \"No stake to withdraw\");\n require(info.withdrawTime > 0, \"must call unlockStake() first\");\n require(info.withdrawTime <= block.timestamp, \"Stake withdrawal is not due\");\n info.unstakeDelaySec = 0;\n info.withdrawTime = 0;\n info.stake = 0;\n emit StakeWithdrawn(msg.sender, withdrawAddress, stake);\n (bool success,) = withdrawAddress.call{value : stake}(\"\");\n require(success, \"failed to withdraw stake\");\n }\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external {\n DepositInfo storage info = deposits[msg.sender];\n require(withdrawAmount <= info.deposit, \"Withdraw amount too large\");\n info.deposit = uint112(info.deposit - withdrawAmount);\n emit Withdrawn(msg.sender, withdrawAddress, withdrawAmount);\n (bool success,) = withdrawAddress.call{value : withdrawAmount}(\"\");\n require(success, \"failed to withdraw\");\n }\n}\n"
+ },
+ "contracts/interfaces/IAccount.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\ninterface IAccount {\n\n /**\n * Validate user's signature and nonce\n * the entryPoint will make the call to the recipient only if this validation call returns successfully.\n * signature failure should be reported by returning SIG_VALIDATION_FAILED (1).\n * This allows making a \"simulation call\" without a valid signature\n * Other failures (e.g. nonce mismatch, or invalid signature format) should still revert to signal failure.\n *\n * @dev Must validate caller is the entryPoint.\n * Must validate the signature and nonce\n * @param userOp the operation that is about to be executed.\n * @param userOpHash hash of the user's request data. can be used as the basis for signature.\n * @param missingAccountFunds missing funds on the account's deposit in the entrypoint.\n * This is the minimum amount to transfer to the sender(entryPoint) to be able to make the call.\n * The excess is left as a deposit in the entrypoint, for future calls.\n * can be withdrawn anytime using \"entryPoint.withdrawTo()\"\n * In case there is a paymaster in the request (or the current deposit is high enough), this value will be zero.\n * @return validationData packaged ValidationData structure. use `_packValidationData` and `_unpackValidationData` to encode and decode\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * If an account doesn't use time-range, it is enough to return SIG_VALIDATION_FAILED value (1) for signature failure.\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)\n external returns (uint256 validationData);\n}\n"
+ },
+ "contracts/interfaces/IAggregator.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * Aggregated Signatures validator.\n */\ninterface IAggregator {\n\n /**\n * validate aggregated signature.\n * revert if the aggregated signature does not match the given list of operations.\n */\n function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) external view;\n\n /**\n * validate signature of a single userOp\n * This method is should be called by bundler after EntryPoint.simulateValidation() returns (reverts) with ValidationResultWithAggregation\n * First it validates the signature over the userOp. Then it returns data to be used when creating the handleOps.\n * @param userOp the userOperation received from the user.\n * @return sigForUserOp the value to put into the signature field of the userOp when calling handleOps.\n * (usually empty, unless account and aggregator support some kind of \"multisig\"\n */\n function validateUserOpSignature(UserOperation calldata userOp)\n external view returns (bytes memory sigForUserOp);\n\n /**\n * aggregate multiple signatures into a single value.\n * This method is called off-chain to calculate the signature to pass with handleOps()\n * bundler MAY use optimized custom code perform this aggregation\n * @param userOps array of UserOperations to collect the signatures from.\n * @return aggregatedSignature the aggregated signature\n */\n function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatedSignature);\n}\n"
+ },
+ "contracts/interfaces/IEntryPoint.sol": {
+ "content": "/**\n ** Account-Abstraction (EIP-4337) singleton EntryPoint implementation.\n ** Only one instance required on each chain.\n **/\n// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable avoid-low-level-calls */\n/* solhint-disable no-inline-assembly */\n/* solhint-disable reason-string */\n\nimport \"./UserOperation.sol\";\nimport \"./IStakeManager.sol\";\nimport \"./IAggregator.sol\";\nimport \"./INonceManager.sol\";\n\ninterface IEntryPoint is IStakeManager, INonceManager {\n\n /***\n * An event emitted after each successful request\n * @param userOpHash - unique identifier for the request (hash its entire content, except signature).\n * @param sender - the account that generates this request.\n * @param paymaster - if non-null, the paymaster that pays for this request.\n * @param nonce - the nonce value from the request.\n * @param success - true if the sender transaction succeeded, false if reverted.\n * @param actualGasCost - actual amount paid (by account or paymaster) for this UserOperation.\n * @param actualGasUsed - total gas used by this UserOperation (including preVerification, creation, validation and execution).\n */\n event UserOperationEvent(bytes32 indexed userOpHash, address indexed sender, address indexed paymaster, uint256 nonce, bool success, uint256 actualGasCost, uint256 actualGasUsed);\n\n /**\n * account \"sender\" was deployed.\n * @param userOpHash the userOp that deployed this account. UserOperationEvent will follow.\n * @param sender the account that is deployed\n * @param factory the factory used to deploy this account (in the initCode)\n * @param paymaster the paymaster used by this UserOp\n */\n event AccountDeployed(bytes32 indexed userOpHash, address indexed sender, address factory, address paymaster);\n\n /**\n * An event emitted if the UserOperation \"callData\" reverted with non-zero length\n * @param userOpHash the request unique identifier.\n * @param sender the sender of this request\n * @param nonce the nonce used in the request\n * @param revertReason - the return bytes from the (reverted) call to \"callData\".\n */\n event UserOperationRevertReason(bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason);\n\n /**\n * an event emitted by handleOps(), before starting the execution loop.\n * any event emitted before this event, is part of the validation.\n */\n event BeforeExecution();\n\n /**\n * signature aggregator used by the following UserOperationEvents within this bundle.\n */\n event SignatureAggregatorChanged(address indexed aggregator);\n\n /**\n * a custom revert error of handleOps, to identify the offending op.\n * NOTE: if simulateValidation passes successfully, there should be no reason for handleOps to fail on it.\n * @param opIndex - index into the array of ops to the failed one (in simulateValidation, this is always zero)\n * @param reason - revert reason\n * The string starts with a unique code \"AAmn\", where \"m\" is \"1\" for factory, \"2\" for account and \"3\" for paymaster issues,\n * so a failure can be attributed to the correct entity.\n * Should be caught in off-chain handleOps simulation and not happen on-chain.\n * Useful for mitigating DoS attempts against batchers or for troubleshooting of factory/account/paymaster reverts.\n */\n error FailedOp(uint256 opIndex, string reason);\n\n /**\n * error case when a signature aggregator fails to verify the aggregated signature it had created.\n */\n error SignatureValidationFailed(address aggregator);\n\n /**\n * Successful result from simulateValidation.\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n */\n error ValidationResult(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);\n\n /**\n * Successful result from simulateValidation, if the account returns a signature aggregator\n * @param returnInfo gas and time-range returned values\n * @param senderInfo stake information about the sender\n * @param factoryInfo stake information about the factory (if any)\n * @param paymasterInfo stake information about the paymaster (if any)\n * @param aggregatorInfo signature aggregation info (if the account requires signature aggregator)\n * bundler MUST use it to verify the signature, or reject the UserOperation\n */\n error ValidationResultWithAggregation(ReturnInfo returnInfo,\n StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,\n AggregatorStakeInfo aggregatorInfo);\n\n /**\n * return value of getSenderAddress\n */\n error SenderAddressResult(address sender);\n\n /**\n * return value of simulateHandleOp\n */\n error ExecutionResult(uint256 preOpGas, uint256 paid, uint48 validAfter, uint48 validUntil, bool targetSuccess, bytes targetResult);\n\n //UserOps handled, per aggregator\n struct UserOpsPerAggregator {\n UserOperation[] userOps;\n\n // aggregator address\n IAggregator aggregator;\n // aggregated signature\n bytes signature;\n }\n\n /**\n * Execute a batch of UserOperation.\n * no signature aggregator is used.\n * if any account requires an aggregator (that is, it returned an aggregator when\n * performing simulateValidation), then handleAggregatedOps() must be used instead.\n * @param ops the operations to execute\n * @param beneficiary the address to receive the fees\n */\n function handleOps(UserOperation[] calldata ops, address payable beneficiary) external;\n\n /**\n * Execute a batch of UserOperation with Aggregators\n * @param opsPerAggregator the operations to execute, grouped by aggregator (or address(0) for no-aggregator accounts)\n * @param beneficiary the address to receive the fees\n */\n function handleAggregatedOps(\n UserOpsPerAggregator[] calldata opsPerAggregator,\n address payable beneficiary\n ) external;\n\n /**\n * generate a request Id - unique identifier for this request.\n * the request ID is a hash over the content of the userOp (except the signature), the entrypoint and the chainid.\n */\n function getUserOpHash(UserOperation calldata userOp) external view returns (bytes32);\n\n /**\n * Simulate a call to account.validateUserOp and paymaster.validatePaymasterUserOp.\n * @dev this method always revert. Successful result is ValidationResult error. other errors are failures.\n * @dev The node must also verify it doesn't use banned opcodes, and that it doesn't reference storage outside the account's data.\n * @param userOp the user operation to validate.\n */\n function simulateValidation(UserOperation calldata userOp) external;\n\n /**\n * gas and return values during simulation\n * @param preOpGas the gas used for validation (including preValidationGas)\n * @param prefund the required prefund for this operation\n * @param sigFailed validateUserOp's (or paymaster's) signature check failed\n * @param validAfter - first timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param validUntil - last timestamp this UserOp is valid (merging account and paymaster time-range)\n * @param paymasterContext returned by validatePaymasterUserOp (to be passed into postOp)\n */\n struct ReturnInfo {\n uint256 preOpGas;\n uint256 prefund;\n bool sigFailed;\n uint48 validAfter;\n uint48 validUntil;\n bytes paymasterContext;\n }\n\n /**\n * returned aggregated signature info.\n * the aggregator returned by the account, and its current stake.\n */\n struct AggregatorStakeInfo {\n address aggregator;\n StakeInfo stakeInfo;\n }\n\n /**\n * Get counterfactual sender address.\n * Calculate the sender contract address that will be generated by the initCode and salt in the UserOperation.\n * this method always revert, and returns the address in SenderAddressResult error\n * @param initCode the constructor code to be passed into the UserOperation.\n */\n function getSenderAddress(bytes memory initCode) external;\n\n\n /**\n * simulate full execution of a UserOperation (including both validation and target execution)\n * this method will always revert with \"ExecutionResult\".\n * it performs full validation of the UserOperation, but ignores signature error.\n * an optional target address is called after the userop succeeds, and its value is returned\n * (before the entire call is reverted)\n * Note that in order to collect the the success/failure of the target call, it must be executed\n * with trace enabled to track the emitted events.\n * @param op the UserOperation to simulate\n * @param target if nonzero, a target address to call after userop simulation. If called, the targetSuccess and targetResult\n * are set to the return from that call.\n * @param targetCallData callData to pass to target address\n */\n function simulateHandleOp(UserOperation calldata op, address target, bytes calldata targetCallData) external;\n}\n\n"
+ },
+ "contracts/interfaces/INonceManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\ninterface INonceManager {\n\n /**\n * Return the next nonce for this sender.\n * Within a given key, the nonce values are sequenced (starting with zero, and incremented by one on each userop)\n * But UserOp with different keys can come with arbitrary order.\n *\n * @param sender the account address\n * @param key the high 192 bit of the nonce\n * @return nonce a full nonce to pass for next UserOp with this sender.\n */\n function getNonce(address sender, uint192 key)\n external view returns (uint256 nonce);\n\n /**\n * Manually increment the nonce of the sender.\n * This method is exposed just for completeness..\n * Account does NOT need to call it, neither during validation, nor elsewhere,\n * as the EntryPoint will update the nonce regardless.\n * Possible use-case is call it with various keys to \"initialize\" their nonces to one, so that future\n * UserOperations will not pay extra for the first transaction with a given key.\n */\n function incrementNonce(uint192 key) external;\n}\n"
+ },
+ "contracts/interfaces/IPaymaster.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\nimport \"./UserOperation.sol\";\n\n/**\n * the interface exposed by a paymaster contract, who agrees to pay the gas for user's operations.\n * a paymaster must hold a stake to cover the required entrypoint stake and also the gas for the transaction.\n */\ninterface IPaymaster {\n\n enum PostOpMode {\n opSucceeded, // user op succeeded\n opReverted, // user op reverted. still has to pay for gas.\n postOpReverted //user op succeeded, but caused postOp to revert. Now it's a 2nd call, after user's op was deliberately reverted.\n }\n\n /**\n * payment validation: check if paymaster agrees to pay.\n * Must verify sender is the entryPoint.\n * Revert to reject this request.\n * Note that bundlers will reject this method if it changes the state, unless the paymaster is trusted (whitelisted)\n * The paymaster pre-pays using its deposit, and receive back a refund after the postOp method returns.\n * @param userOp the user operation\n * @param userOpHash hash of the user's request data.\n * @param maxCost the maximum cost of this transaction (based on maximum gas and gas price from userOp)\n * @return context value to send to a postOp\n * zero length to signify postOp is not required.\n * @return validationData signature and time-range of this operation, encoded the same as the return value of validateUserOperation\n * <20-byte> sigAuthorizer - 0 for valid signature, 1 to mark signature failure,\n * otherwise, an address of an \"authorizer\" contract.\n * <6-byte> validUntil - last timestamp this operation is valid. 0 for \"indefinite\"\n * <6-byte> validAfter - first timestamp this operation is valid\n * Note that the validation code cannot use block.timestamp (or block.number) directly.\n */\n function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)\n external returns (bytes memory context, uint256 validationData);\n\n /**\n * post-operation handler.\n * Must verify sender is the entryPoint\n * @param mode enum with the following options:\n * opSucceeded - user operation succeeded.\n * opReverted - user op reverted. still has to pay for gas.\n * postOpReverted - user op succeeded, but caused postOp (in mode=opSucceeded) to revert.\n * Now this is the 2nd call, after user's op was deliberately reverted.\n * @param context - the context value returned by validatePaymasterUserOp\n * @param actualGasCost - actual gas used so far (without this postOp call).\n */\n function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external;\n}\n"
+ },
+ "contracts/interfaces/IStakeManager.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.12;\n\n/**\n * manage deposits and stakes.\n * deposit is just a balance used to pay for UserOperations (either by a paymaster or an account)\n * stake is value locked for at least \"unstakeDelay\" by the staked entity.\n */\ninterface IStakeManager {\n\n event Deposited(\n address indexed account,\n uint256 totalDeposit\n );\n\n event Withdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /// Emitted when stake or unstake delay are modified\n event StakeLocked(\n address indexed account,\n uint256 totalStaked,\n uint256 unstakeDelaySec\n );\n\n /// Emitted once a stake is scheduled for withdrawal\n event StakeUnlocked(\n address indexed account,\n uint256 withdrawTime\n );\n\n event StakeWithdrawn(\n address indexed account,\n address withdrawAddress,\n uint256 amount\n );\n\n /**\n * @param deposit the entity's deposit\n * @param staked true if this entity is staked.\n * @param stake actual amount of ether staked for this entity.\n * @param unstakeDelaySec minimum delay to withdraw the stake.\n * @param withdrawTime - first block timestamp where 'withdrawStake' will be callable, or zero if already locked\n * @dev sizes were chosen so that (deposit,staked, stake) fit into one cell (used during handleOps)\n * and the rest fit into a 2nd cell.\n * 112 bit allows for 10^15 eth\n * 48 bit for full timestamp\n * 32 bit allows 150 years for unstake delay\n */\n struct DepositInfo {\n uint112 deposit;\n bool staked;\n uint112 stake;\n uint32 unstakeDelaySec;\n uint48 withdrawTime;\n }\n\n //API struct used by getStakeInfo and simulateValidation\n struct StakeInfo {\n uint256 stake;\n uint256 unstakeDelaySec;\n }\n\n /// @return info - full deposit information of given account\n function getDepositInfo(address account) external view returns (DepositInfo memory info);\n\n /// @return the deposit (for gas payment) of the account\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * add to the deposit of the given account\n */\n function depositTo(address account) external payable;\n\n /**\n * add to the account's stake - amount and delay\n * any pending unstake is first cancelled.\n * @param _unstakeDelaySec the new lock duration before the deposit can be withdrawn.\n */\n function addStake(uint32 _unstakeDelaySec) external payable;\n\n /**\n * attempt to unlock the stake.\n * the value can be withdrawn (using withdrawStake) after the unstake delay.\n */\n function unlockStake() external;\n\n /**\n * withdraw from the (unlocked) stake.\n * must first call unlockStake and wait for the unstakeDelay to pass\n * @param withdrawAddress the address to send withdrawn value.\n */\n function withdrawStake(address payable withdrawAddress) external;\n\n /**\n * withdraw from the deposit.\n * @param withdrawAddress the address to send withdrawn value.\n * @param withdrawAmount the amount to withdraw.\n */\n function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external;\n}\n"
+ },
+ "contracts/interfaces/UserOperation.sol": {
+ "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity ^0.8.12;\n\n/* solhint-disable no-inline-assembly */\n\nimport {calldataKeccak} from \"../core/Helpers.sol\";\n\n/**\n * User Operation struct\n * @param sender the sender account of this request.\n * @param nonce unique value the sender uses to verify it is not a replay.\n * @param initCode if set, the account contract will be created by this constructor/\n * @param callData the method call to execute on this account.\n * @param callGasLimit the gas limit passed to the callData method call.\n * @param verificationGasLimit gas used for validateUserOp and validatePaymasterUserOp.\n * @param preVerificationGas gas not calculated by the handleOps method, but added to the gas paid. Covers batch overhead.\n * @param maxFeePerGas same as EIP-1559 gas parameter.\n * @param maxPriorityFeePerGas same as EIP-1559 gas parameter.\n * @param paymasterAndData if set, this field holds the paymaster address and paymaster-specific data. the paymaster will pay for the transaction instead of the sender.\n * @param signature sender-verified signature over the entire request, the EntryPoint address and the chain ID.\n */\n struct UserOperation {\n\n address sender;\n uint256 nonce;\n bytes initCode;\n bytes callData;\n uint256 callGasLimit;\n uint256 verificationGasLimit;\n uint256 preVerificationGas;\n uint256 maxFeePerGas;\n uint256 maxPriorityFeePerGas;\n bytes paymasterAndData;\n bytes signature;\n }\n\n/**\n * Utility functions helpful when working with UserOperation structs.\n */\nlibrary UserOperationLib {\n\n function getSender(UserOperation calldata userOp) internal pure returns (address) {\n address data;\n //read sender from userOp, which is first userOp member (saves 800 gas...)\n assembly {data := calldataload(userOp)}\n return address(uint160(data));\n }\n\n //relayer/block builder might submit the TX with higher priorityFee, but the user should not\n // pay above what he signed for.\n function gasPrice(UserOperation calldata userOp) internal view returns (uint256) {\n unchecked {\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n if (maxFeePerGas == maxPriorityFeePerGas) {\n //legacy mode (for networks that don't support basefee opcode)\n return maxFeePerGas;\n }\n return min(maxFeePerGas, maxPriorityFeePerGas + block.basefee);\n }\n }\n\n function pack(UserOperation calldata userOp) internal pure returns (bytes memory ret) {\n address sender = getSender(userOp);\n uint256 nonce = userOp.nonce;\n bytes32 hashInitCode = calldataKeccak(userOp.initCode);\n bytes32 hashCallData = calldataKeccak(userOp.callData);\n uint256 callGasLimit = userOp.callGasLimit;\n uint256 verificationGasLimit = userOp.verificationGasLimit;\n uint256 preVerificationGas = userOp.preVerificationGas;\n uint256 maxFeePerGas = userOp.maxFeePerGas;\n uint256 maxPriorityFeePerGas = userOp.maxPriorityFeePerGas;\n bytes32 hashPaymasterAndData = calldataKeccak(userOp.paymasterAndData);\n\n return abi.encode(\n sender, nonce,\n hashInitCode, hashCallData,\n callGasLimit, verificationGasLimit, preVerificationGas,\n maxFeePerGas, maxPriorityFeePerGas,\n hashPaymasterAndData\n );\n }\n\n function hash(UserOperation calldata userOp) internal pure returns (bytes32) {\n return keccak256(pack(userOp));\n }\n\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n}\n"
+ },
+ "contracts/utils/Exec.sol": {
+ "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.5 <0.9.0;\n\n// solhint-disable no-inline-assembly\n\n/**\n * Utility functions helpful when making different kinds of contract calls in Solidity.\n */\nlibrary Exec {\n\n function call(\n address to,\n uint256 value,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := call(txGas, to, value, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function staticcall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal view returns (bool success) {\n assembly {\n success := staticcall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n function delegateCall(\n address to,\n bytes memory data,\n uint256 txGas\n ) internal returns (bool success) {\n assembly {\n success := delegatecall(txGas, to, add(data, 0x20), mload(data), 0, 0)\n }\n }\n\n // get returned data from last call or calldelegate\n function getReturnData(uint256 maxLen) internal pure returns (bytes memory returnData) {\n assembly {\n let len := returndatasize()\n if gt(len, maxLen) {\n len := maxLen\n }\n let ptr := mload(0x40)\n mstore(0x40, add(ptr, add(len, 0x20)))\n mstore(ptr, len)\n returndatacopy(add(ptr, 0x20), 0, len)\n returnData := ptr\n }\n }\n\n // revert with explicit byte array (probably reverted info from call)\n function revertWithData(bytes memory returnData) internal pure {\n assembly {\n revert(add(returnData, 32), mload(returnData))\n }\n }\n\n function callAndRevert(address to, bytes memory data, uint256 maxLen) internal {\n bool success = call(to,0,data,gasleft());\n if (!success) {\n revertWithData(getReturnData(maxLen));\n }\n }\n}\n"
+ }
+ },
+ "settings": {
+ "optimizer": {
+ "enabled": true,
+ "runs": 1000000
+ },
+ "viaIR": true,
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode",
+ "evm.deployedBytecode",
+ "evm.methodIdentifiers",
+ "metadata"
+ ],
+ "": [
+ "ast"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/SoulWalletCore/lib/account-abstraction/eip/EIPS/eip-4337.md b/lib/SoulWalletCore/lib/account-abstraction/eip/EIPS/eip-4337.md
new file mode 100644
index 00000000..67e47fbb
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/eip/EIPS/eip-4337.md
@@ -0,0 +1,932 @@
+---
+eip: 4337
+title: Account Abstraction Using Alt Mempool
+description: An account abstraction proposal which completely avoids consensus-layer protocol changes, instead relying on higher-layer infrastructure.
+author: Vitalik Buterin (@vbuterin), Yoav Weiss (@yoavw), Kristof Gazso (@kristofgazso), Namra Patel (@namrapatel), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn), Tjaden Hess (@tjade273)
+discussions-to: https://ethereum-magicians.org/t/erc-4337-account-abstraction-via-entry-point-contract-specification/7160
+status: Draft
+type: Standards Track
+category: ERC
+created: 2021-09-29
+---
+
+## Abstract
+
+An account abstraction proposal which completely avoids the need for consensus-layer protocol changes. Instead of adding new protocol features and changing the bottom-layer transaction type, this proposal instead introduces a higher-layer pseudo-transaction object called a `UserOperation`. Users send `UserOperation` objects into a separate mempool. A special class of actor called bundlers (either block builders, or users that can send transactions to block builders through a bundle marketplace) package up a set of these objects into a transaction making a `handleOps` call to a special contract, and that transaction then gets included in a block.
+
+## Motivation
+
+See also `https://ethereum-magicians.org/t/implementing-account-abstraction-as-part-of-eth1-x/4020` and the links therein for historical work and motivation, and [EIP-2938](./eip-2938.md) for a consensus layer proposal for implementing the same goal.
+
+This proposal takes a different approach, avoiding any adjustments to the consensus layer. It seeks to achieve the following goals:
+
+* **Achieve the key goal of account abstraction**: allow users to use smart contract wallets containing arbitrary verification logic instead of EOAs as their primary account. Completely remove any need at all for users to also have EOAs (as status quo SC wallets and [EIP-3074](./eip-3074.md) both require)
+* **Decentralization**
+ * Allow any bundler (think: block builder) to participate in the process of including account-abstracted user operations
+ * Work with all activity happening over a public mempool; users do not need to know the direct communication addresses (eg. IP, onion) of any specific actors
+ * Avoid trust assumptions on bundlers
+* **Do not require any Ethereum consensus changes**: Ethereum consensus layer development is focusing on the merge and later on scalability-oriented features, and there may not be any opportunity for further protocol changes for a long time. Hence, to increase the chance of faster adoption, this proposal avoids Ethereum consensus changes.
+* **Try to support other use cases**
+ * Privacy-preserving applications
+ * Atomic multi-operations (similar goal to [EIP-3074](./eip-3074.md))
+ * Pay tx fees with [ERC-20](./eip-20.md) tokens, allow developers to pay fees for their users, and [EIP-3074](./eip-3074.md)-like **sponsored transaction** use cases more generally
+ * Support aggregated signature (e.g. BLS)
+
+## Specification
+
+### Definitions
+
+* **UserOperation** - a structure that describes a transaction to be sent on behalf of a user. To avoid confusion, it is not named "transaction".
+ * Like a transaction, it contains "sender", "to", "calldata", "maxFeePerGas", "maxPriorityFee", "signature", "nonce"
+ * unlike a transaction, it contains several other fields, described below
+ * also, the "nonce" and "signature" fields usage is not defined by the protocol, but by each account implementation
+* **Sender** - the account contract sending a user operation.
+* **EntryPoint** - a singleton contract to execute bundles of UserOperations. Bundlers/Clients whitelist the supported entrypoint.
+* **Bundler** - a node (block builder) that bundles multiple UserOperations and create an EntryPoint.handleOps() transaction. Note that not all block-builders on the network are required to be bundlers
+* **Aggregator** - a helper contract trusted by accounts to validate an aggregated signature. Bundlers/Clients whitelist the supported aggregators.
+
+
+To avoid Ethereum consensus changes, we do not attempt to create new transaction types for account-abstracted transactions. Instead, users package up the action they want their account to take in an ABI-encoded struct called a `UserOperation`:
+
+| Field | Type | Description
+| - | - | - |
+| `sender` | `address` | The account making the operation |
+| `nonce` | `uint256` | Anti-replay parameter |
+| `initCode` | `bytes` | The initCode of the account (needed if and only if the account is not yet on-chain and needs to be created) |
+| `callData` | `bytes` | The data to pass to the `sender` during the main execution call |
+| `callGasLimit` | `uint256` | The amount of gas to allocate the main execution call |
+| `verificationGasLimit` | `uint256` | The amount of gas to allocate for the verification step |
+| `preVerificationGas` | `uint256` | The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata |
+| `maxFeePerGas` | `uint256` | Maximum fee per gas (similar to [EIP-1559](./eip-1559.md) `max_fee_per_gas`) |
+| `maxPriorityFeePerGas` | `uint256` | Maximum priority fee per gas (similar to EIP-1559 `max_priority_fee_per_gas`) |
+| `paymasterAndData` | `bytes` | Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster (empty for self-sponsored transaction) |
+| `signature` | `bytes` | Data passed into the account along with the nonce during the verification step |
+
+Users send `UserOperation` objects to a dedicated user operation mempool. A specialized class of actors called **bundlers** (either block builders running special-purpose code, or users that can relay transactions to block builders eg. through a bundle marketplace such as Flashbots that can guarantee next-block-or-never inclusion) listen in on the user operation mempool, and create **bundle transactions**. A bundle transaction packages up multiple `UserOperation` objects into a single `handleOps` call to a pre-published global **entry point contract**.
+
+To prevent replay attacks (both cross-chain and multiple `EntryPoint` implementations), the `signature` should depend on `chainid` and the `EntryPoint` address.
+
+The core interface of the entry point contract is as follows:
+
+```solidity
+function handleOps(UserOperation[] calldata ops, address payable beneficiary);
+
+function handleAggregatedOps(
+ UserOpsPerAggregator[] calldata opsPerAggregator,
+ address payable beneficiary
+);
+
+
+struct UserOpsPerAggregator {
+ UserOperation[] userOps;
+ IAggregator aggregator;
+ bytes signature;
+}
+function simulateValidation(UserOperation calldata userOp);
+
+error ValidationResult(ReturnInfo returnInfo,
+ StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo);
+
+error ValidationResultWithAggregation(ReturnInfo returnInfo,
+ StakeInfo senderInfo, StakeInfo factoryInfo, StakeInfo paymasterInfo,
+ AggregatorStakeInfo aggregatorInfo);
+
+struct ReturnInfo {
+ uint256 preOpGas;
+ uint256 prefund;
+ bool sigFailed;
+ uint48 validAfter;
+ uint48 validUntil;
+ bytes paymasterContext;
+}
+
+struct StakeInfo {
+ uint256 stake;
+ uint256 unstakeDelaySec;
+}
+
+struct AggregatorStakeInfo {
+ address actualAggregator;
+ StakeInfo stakeInfo;
+}
+```
+
+The core interface required for an account to have is:
+
+```solidity
+interface IAccount {
+ function validateUserOp
+ (UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)
+ external returns (uint256 validationData);
+}
+```
+
+The `userOpHash` is a hash over the userOp (except signature), entryPoint and chainId.
+
+The account:
+
+* MUST validate the caller is a trusted EntryPoint
+* If the account does not support signature aggregation, it MUST validate the signature is a valid signature of the `userOpHash`, and
+ SHOULD return SIG_VALIDATION_FAILED (and not revert) on signature mismatch. Any other error should revert.
+* The MAY check the nonce field, but should not implement the replay protection mechanism: the EntryPoint maintains uniqueness of nonces per user account.
+* MUST pay the entryPoint (caller) at least the "missingAccountFunds" (which might be zero, in case current account's deposit is high enough)
+* The account MAY pay more than this minimum, to cover future transactions (it can always issue `withdrawTo` to retrieve it)
+* The return value MUST be packed of `authorizer`, `validUntil` and `validAfter` timestamps.
+ * authorizer - 0 for valid signature, 1 to mark signature failure. Otherwise, an address of an authorizer contract. This ERC defines "signature aggregator" as authorizer.
+ * `validUntil` is 6-byte timestamp value, or zero for "infinite". The UserOp is valid only up to this time.
+ * `validAfter` is 6-byte timestamp. The UserOp is valid only after this time.
+
+An account that works with aggregated signature, should return its signature aggregator address in the "sigAuthorizer" return value of validateUserOp.
+It MAY ignore the signature field
+
+The core interface required by an aggregator is:
+
+```solidity
+interface IAggregator {
+
+ function validateUserOpSignature(UserOperation calldata userOp)
+ external view returns (bytes memory sigForUserOp);
+
+ function aggregateSignatures(UserOperation[] calldata userOps) external view returns (bytes memory aggregatesSignature);
+
+ function validateSignatures(UserOperation[] calldata userOps, bytes calldata signature) view external;
+}
+```
+
+* If an account uses an aggregator (returns it from validateUserOp), then its address is returned by `simulateValidation()` reverting with `ValidationResultWithAggregator` instead of `ValidationResult`
+* To accept the UserOp, the bundler must call **validateUserOpSignature()** to validate the userOp's signature.
+* **aggregateSignatures()** must aggregate all UserOp signature into a single value.
+* Note that the above methods are helper method for the bundler. The bundler MAY use a native library to perform the same validation and aggregation logic.
+* **validateSignatures()** MUST validate the aggregated signature matches for all UserOperations in the array, and revert otherwise.
+ This method is called on-chain by `handleOps()`
+
+#### Using signature aggregators
+
+An account signifies it uses signature aggregation returning its address from `validateUserOp`.
+During `simulateValidation`, this aggregator is returned (in the `ValidationResultWithAggregator`)
+
+The bundler should first accept the aggregator (validate its stake info and that it is not throttled/banned)
+Then it MUST verify the userOp using `aggregator.validateUserOpSignature()`
+
+Signature aggregator SHOULD stake just like a paymaster, unless it is exempt due to not accessing global storage - see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details. Bundlers MAY throttle down and ban aggregators in case they take too much
+resources (or revert) when the above methods are called in view mode, or if the signature aggregation fails.
+
+### Required entry point contract functionality
+
+There are 2 separate entry point methods: `handleOps` and `handleAggregatedOps`
+
+* `handleOps` handle userOps of accounts that don't require any signature aggregator.
+* `handleAggregatedOps` can handle a batch that contains userOps of multiple aggregators (and also requests without any aggregator)
+* `handleAggregatedOps` performs the same logic below as `handleOps`, but it must transfer the correct aggregator to each userOp, and also must call `validateSignatures` on each aggregator after doing all the per-account validation.
+The entry point's `handleOps` function must perform the following steps (we first describe the simpler non-paymaster case). It must make two loops, the **verification loop** and the **execution loop**. In the verification loop, the `handleOps` call must perform the following steps for each `UserOperation`:
+
+* **Create the account if it does not yet exist**, using the initcode provided in the `UserOperation`. If the account does not exist, _and_ the initcode is empty, or does not deploy a contract at the "sender" address, the call must fail.
+* **Call `validateUserOp` on the account**, passing in the `UserOperation`, the required fee and aggregator (if there is one). The account should verify the operation's signature, and pay the fee if the account considers the operation valid. If any `validateUserOp` call fails, `handleOps` must skip execution of at least that operation, and may revert entirely.
+* Validate the account's deposit in the entryPoint is high enough to cover the max possible cost (cover the already-done verification and max execution gas)
+* Validate the nonce uniqueness. see [Keep Nonce Uniqueness](#keep-nonce-uniqueness) below
+
+In the execution loop, the `handleOps` call must perform the following steps for each `UserOperation`:
+
+* **Call the account with the `UserOperation`'s calldata**. It's up to the account to choose how to parse the calldata; an expected workflow is for the account to have an `execute` function that parses the remaining calldata as a series of one or more calls that the account should make.
+
+![](../assets/eip-4337/image1.png)
+
+Before accepting a `UserOperation`, bundlers should use an RPC method to locally call the `simulateValidation` function of the entry point, to verify that the signature is correct and the operation actually pays fees; see the [Simulation section below](#simulation) for details.
+A node/bundler SHOULD drop (not add to the mempool) a `UserOperation` that fails the validation
+
+### Keep Nonce Uniqueness
+
+The EntryPoint maintains nonce uniqueness for each submitted UserOperation using the following algorithm:
+* The nonce is treated as 2 separate fields:
+ * 64-bit "sequence"
+ * 192-bit "key"
+* Within each "key", the "sequence" value must have consecutive values, starting with zero.
+* That is, a nonce with a new "key" value is allowed, as long as the "sequence" part is zero. The next nonce for that key must be "1", and so on.
+* The EntryPoint exports a method `getNonce(address sender, uint192 key)` to return the next valid nonce for this key.
+* The behaviour of a "classic" sequential nonce can be achieved by validating that the "key" part is always zero.
+
+### Extension: paymasters
+
+We extend the entry point logic to support **paymasters** that can sponsor transactions for other users. This feature can be used to allow application developers to subsidize fees for their users, allow users to pay fees with [ERC-20](./eip-20.md) tokens and many other use cases. When the paymaster is not equal to the zero address, the entry point implements a different flow:
+
+![](../assets/eip-4337/image2.png)
+
+During the verification loop, in addition to calling `validateUserOp`, the `handleOps` execution also must check that the paymaster has enough ETH deposited with the entry point to pay for the operation, and then call `validatePaymasterUserOp` on the paymaster to verify that the paymaster is willing to pay for the operation. Note that in this case, the `validateUserOp` is called with a `missingAccountFunds` of 0 to reflect that the account's deposit is not used for payment for this userOp.
+
+If the paymaster's validatePaymasterUserOp returns a "context", then `handleOps` must call `postOp` on the paymaster after making the main execution call. It must guarantee the execution of `postOp`, by making the main execution inside an inner call context, and if the inner call context reverts attempting to call `postOp` again in an outer call context.
+
+Maliciously crafted paymasters _can_ DoS the system. To prevent this, we use a reputation system. paymaster must either limit its storage usage, or have a stake. see the [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details.
+
+The paymaster interface is as follows:
+
+```c++
+ function validatePaymasterUserOp
+ (UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
+ external returns (bytes memory context, uint256 validationData);
+
+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
+}
+```
+
+
+```c++
+// add a paymaster stake (must be called by the paymaster)
+function addStake(uint32 _unstakeDelaySec) external payable
+
+// unlock the stake (must wait unstakeDelay before can withdraw)
+function unlockStake() external
+
+// withdraw the unlocked stake
+function withdrawStake(address payable withdrawAddress) external
+```
+
+The paymaster must also have a deposit, which the entry point will charge UserOperation costs from.
+The deposit (for paying gas fees) is separate from the stake (which is locked).
+
+The entry point must implement the following interface to allow paymasters (and optionally accounts) manage their deposit:
+
+```c++
+// return the deposit of an account
+function balanceOf(address account) public view returns (uint256)
+
+// add to the deposit of the given account
+function depositTo(address account) public payable
+
+// withdraw from the deposit
+function withdrawTo(address payable withdrawAddress, uint256 withdrawAmount) external
+```
+
+### Client behavior upon receiving a UserOperation
+
+When a client receives a `UserOperation`, it must first run some basic sanity checks, namely that:
+
+* Either the `sender` is an existing contract, or the `initCode` is not empty (but not both)
+* If `initCode` is not empty, parse its first 20 bytes as a factory address. Record whether the factory is staked, in case the later simulation indicates that it needs to be. If the factory accesses global state, it must be staked - see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details.
+* The `verificationGasLimit` is sufficiently low (`<= MAX_VERIFICATION_GAS`) and the `preVerificationGas` is sufficiently high (enough to pay for the calldata gas cost of serializing the `UserOperation` plus `PRE_VERIFICATION_OVERHEAD_GAS`)
+* The `paymasterAndData` is either empty, or start with the **paymaster** address, which is a contract that (i) currently has nonempty code on chain, (ii) has a sufficient deposit to pay for the UserOperation, and (iii) is not currently banned. During simulation, the paymaster's stake is also checked, depending on its storage usage - see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details.
+* The callgas is at least the cost of a `CALL` with non-zero value.
+* The `maxFeePerGas` and `maxPriorityFeePerGas` are above a configurable minimum value that the client is willing to accept. At the minimum, they are sufficiently high to be included with the current `block.basefee`.
+* The sender doesn't have another `UserOperation` already present in the pool (or it replaces an existing entry with the same sender and nonce, with a higher `maxPriorityFeePerGas` and an equally increased `maxFeePerGas`). Only one `UserOperation` per sender may be included in a single batch. A sender is exempt from this rule and may have multiple `UserOperations` in the pool and in a batch if it is staked (see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) below), but this exception is of limited use to normal accounts.
+
+If the `UserOperation` object passes these sanity checks, the client must next run the first op simulation, and if the simulation succeeds, the client must add the op to the pool. A second simulation must also happen during bundling to make sure the UserOperation is still valid.
+
+### Simulation
+
+#### Simulation Rationale
+
+In order to add a UserOperation into the mempool (and later to add it into a bundle) we need to "simulate" its validation to make sure it is valid, and that it is capable of paying for its own execution.
+In addition, we need to verify that the same will hold true when executed on-chain.
+For this purpose, a UserOperation is not allowed to access any information that might change between simulation and execution, such as current block time, number, hash etc.
+In addition, a UserOperation is only allowed to access data related to this sender address: Multiple UserOperations should not access the same storage, so that it is impossible to invalidate a large number of UserOperations with a single state change.
+There are 3 special contracts that interact with the account: the factory (initCode) that deploys the contract, the paymaster that can pay for the gas, and signature aggregator (described later)
+Each of these contracts is also restricted in its storage access, to make sure UserOperation validations are isolated.
+
+#### Specification:
+
+To simulate a `UserOperation` validation, the client makes a view call to `simulateValidation(userop)`
+
+This method always revert with `ValidationResult` as successful response.
+If the call reverts with other error, the client rejects this `userOp`.
+
+The simulated call performs the full validation, by calling:
+
+1. If `initCode` is present, create the account.
+2. `account.validateUserOp`.
+3. if specified a paymaster: `paymaster.validatePaymasterUserOp`.
+
+Either `validateUserOp` or `validatePaymasterUserOp` may return a "validAfter" and "validUntil" timestamps, which is the time-range that this UserOperation is valid on-chain.
+The simulateValidation call returns this range.
+A node MAY drop a UserOperation if it expires too soon (e.g. wouldn't make it to the next block)
+If the `ValidationResult` includes `sigFail`, the client SHOULD drop the `UserOperation`.
+
+The operations differ in their opcode banning policy.
+In order to distinguish between them, there is a call to the NUMBER opcode (`block.number`), used as a delimiter between the 3 functions.
+While simulating `userOp` validation, the client should make sure that:
+
+1. May not invokes any **forbidden opcodes**
+2. Must not use GAS opcode (unless followed immediately by one of { `CALL`, `DELEGATECALL`, `CALLCODE`, `STATICCALL` }.)
+3. Storage access is limited as follows:
+ 1. self storage (of factory/paymaster, respectively) is allowed, but only if self entity is staked
+ 2. account storage access is allowed (see Storage access by Slots, below),
+ 3. in any case, may not use storage used by another UserOp `sender` in the same bundle (that is, paymaster and factory are not allowed as senders)
+4. Limitation on "CALL" opcodes (`CALL`, `DELEGATECALL`, `CALLCODE`, `STATICCALL`):
+ 1. must not use value (except from account to the entrypoint)
+ 2. must not revert with out-of-gas
+ 3. destination address must have code (EXTCODESIZE>0)
+ 4. cannot call EntryPoint's methods, except `depositFor` (to avoid recursion)
+5. `EXTCODEHASH` of every address accessed (by any opcode) does not change between first and second simulations of the op.
+6. `EXTCODEHASH`, `EXTCODELENGTH`, `EXTCODECOPY` may not access address with no code.
+7. If `op.initcode.length != 0` , allow only one `CREATE2` opcode call (in the first (deployment) block), otherwise forbid `CREATE2`.
+
+#### Storage associated with an address
+
+We define storage slots as "associated with an address" as all the slots that uniquely related on this address, and cannot be related with any other address.
+In solidity, this includes all storage of the contract itself, and any storage of other contracts that use this contract address as a mapping key.
+
+An address `A` is associated with:
+
+1. Slots of contract `A` address itself.
+2. Slot `A` on any other address.
+3. Slots of type `keccak256(A || X) + n` on any other address. (to cover `mapping(address => value)`, which is usually used for balance in ERC-20 tokens).
+ `n` is an offset value up to 128, to allow accessing fields in the format `mapping(address => struct)`
+
+
+#### Alternative Mempools
+
+The simulation rules above are strict and prevent the ability of paymasters and signature aggregators to grief the system.
+However, there might be use-cases where specific paymasters (and signature aggregators) can be validated
+(through manual auditing) and verified that they cannot cause any problem, while still require relaxing of the opcode rules.
+A bundler cannot simply "whitelist" request from a specific paymaster: if that paymaster is not accepted by all
+bundlers, then its support will be sporadic at best.
+Instead, we introduce the term "alternate mempool".
+UserOperations that use whitelisted paymasters (or signature aggregators) are put into a separate mempool.
+Only bundlers that support this whitelist will use UserOperations from this mempool.
+These UserOperations can be bundled together with UserOperations from the main mempool
+
+### Bundling
+
+During bundling, the client should:
+
+* Exclude UserOps that access any sender address of another UserOp in the same batch.
+* Exclude UserOps that access any address created by another UserOp validation in the same batch (via a factory).
+* For each paymaster used in the batch, keep track of the balance while adding UserOps. Ensure that it has sufficient deposit to pay for all the UserOps that use it.
+* Sort UserOps by aggregator, to create the lists of UserOps-per-aggregator.
+* For each aggregator, run the aggregator-specific code to create aggregated signature, and update the UserOps
+
+After creating the batch, before including the transaction in a block, the client should:
+
+* Run `eth_estimateGas` with maximum possible gas, to verify the entire `handleOps` batch transaction, and use the estimated gas for the actual transaction execution.
+* If the call reverted, check the `FailedOp` event. A `FailedOp` during `handleOps` simulation is an unexpected event since it was supposed to be caught by the single-UserOperation simulation. Remove the failed op that caused the revert from the batch and drop from the mempool.
+ If the error is caused by a factory (error code is "AA1.") or paymaster (error code is "AA3."), then also drop from mempool all other UserOps of this entity.
+ Repeat until `eth_estimateGas` succeeds.
+
+In practice, restrictions (2) and (3) basically mean that the only external accesses that the account and the paymaster can make are reading code of other contracts if their code is guaranteed to be immutable (eg. this is useful for calling or delegatecalling to libraries).
+
+If any of the three conditions is violated, the client should reject the `op`. If both calls succeed (or, if `op.paymaster == ZERO_ADDRESS` and the first call succeeds)without violating the three conditions, the client should accept the op. On a bundler node, the storage keys accessed by both calls must be saved as the `accessList` of the `UserOperation`
+
+When a bundler includes a bundle in a block it must ensure that earlier transactions in the block don't make any UserOperation fail. It should either use access lists to prevent conflicts, or place the bundle as the first transaction in the block.
+
+#### Forbidden opcodes
+
+The forbidden opcodes are to be forbidden when `depth > 2` (i.e. when it is the factory, account, paymaster, or other contracts called by them that are being executed). They are: `GASPRICE`, `GASLIMIT`, `DIFFICULTY`, `TIMESTAMP`, `BASEFEE`, `BLOCKHASH`, `NUMBER`, `SELFBALANCE`, `BALANCE`, `ORIGIN`, `GAS`, `CREATE`, `COINBASE`, `SELFDESTRUCT`. They should only be forbidden during verification, not execution. These opcodes are forbidden because their outputs may differ between simulation and execution, so simulation of calls using these opcodes does not reliably tell what would happen if these calls are later done on-chain.
+
+Exceptions to the forbidden opcodes:
+
+1. A single `CREATE2` is allowed if `op.initcode.length != 0` and must result in the deployment of a previously-undeployed `UserOperation.sender`.
+2. `GAS` is allowed if followed immediately by one of { `CALL`, `DELEGATECALL`, `CALLCODE`, `STATICCALL` }.
+ (that is, making calls is allowed, using `gasleft()` or `gas` opcode directly is forbidden)
+
+### Reputation scoring and throttling/banning for global entities
+
+#### Reputation Rationale.
+
+UserOperation's storage access rules prevent them from interfere with each other.
+But "global" entities - paymasters, factories and aggregators are accessed by multiple UserOperations, and thus might invalidate multiple previously-valid UserOperations.
+
+To prevent abuse, we throttle down (or completely ban for a period of time) an entity that causes invalidation of large number of UserOperations in the mempool.
+To prevent such entities from "sybil-attack", we require them to stake with the system, and thus make such DoS attack very expensive.
+Note that this stake is never slashed, and can be withdrawn any time (after unstake delay)
+
+Unstaked entities are allowed, under the rules below.
+
+When staked, an entity is also allowed to use its own associated storage, in addition to sender's associated storage.
+
+The stake value is not enforced on-chain, but specifically by each node while simulating a transaction.
+The stake is expected to be above MIN_STAKE_VALUE, and unstake delay above MIN_UNSTAKE_DELAY
+The value of MIN_UNSTAKE_DELAY is 84600 (one day)
+The value of MIN_STAKE_VALUE is determined per chain, and specified in the "bundler specification test suite"
+
+#### Un-staked entities
+
+Under the following special conditions, unstaked entities still can be used:
+
+* An entity that doesn't use any storage at all, or only the senders's storage (not the entity's storage - that does require a stake)
+* If the UserOp doesn't create a new account (that is initCode is empty), then the entity may also use [storage associated with the sender](#storage-associated-with-an-address))
+* A paymaster that has a “postOp()” method (that is, validatePaymasterUserOp returns “context”) must be staked
+
+#### Specification.
+
+In the following specification, "entity" is either address that is explicitly referenced by the UserOperation: sender, factory, paymaster and aggregator.
+Clients maintain two mappings with a value for staked entities:
+
+* `opsSeen: Map[Address, int]`
+* `opsIncluded: Map[Address, int]`
+
+If an entity doesn't use storage at all, or only reference storage associated with the "sender" (see [Storage associated with an address](#storage-associated-with-an-address)), then it is considered "OK", without using the rules below.
+
+When the client learns of a new staked entity, it sets `opsSeen[paymaster] = 0` and `opsIncluded[paymaster] = 0` .
+
+The client sets `opsSeen[entity] +=1` each time it adds an op with that `entity` to the `UserOperationPool`, and the client sets `opsIncluded[entity] += 1` each time an op that was in the `UserOperationPool` is included on-chain.
+
+Every hour, the client sets `opsSeen[entity] -= opsSeen[entity] // 24` and `opsIncluded[entity] -= opsIncluded[entity] // 24` for all entities (so both values are 24-hour exponential moving averages).
+
+We define the **status** of an entity as follows:
+
+```python
+OK, THROTTLED, BANNED = 0, 1, 2
+
+def status(paymaster: Address,
+ opsSeen: Map[Address, int],
+ opsIncluded: Map[Address, int]):
+ if paymaster not in opsSeen:
+ return OK
+ min_expected_included = opsSeen[paymaster] // MIN_INCLUSION_RATE_DENOMINATOR
+ if min_expected_included <= opsIncluded[paymaster] + THROTTLING_SLACK:
+ return OK
+ elif min_expected_included <= opsIncluded[paymaster] + BAN_SLACK:
+ return THROTTLED
+ else:
+ return BANNED
+```
+
+Stated in simpler terms, we expect at least `1 / MIN_INCLUSION_RATE_DENOMINATOR` of all ops seen on the network to get included. If an entity falls too far behind this minimum, it gets **throttled** (meaning, the client does not accept ops from that paymaster if there is already an op with that entity, and an op only stays in the pool for 10 blocks), If the entity falls even further behind, it gets **banned**. Throttling and banning naturally decay over time because of the exponential-moving-average rule.
+
+**Non-bundling clients and bundlers should use different settings for the above params**:
+
+| Param | Client setting | Bundler setting |
+| - | - | - |
+| `MIN_INCLUSION_RATE_DENOMINATOR` | 100 | 10 |
+| `THROTTLING_SLACK` | 10 | 10 |
+| `BAN_SLACK` | 50 | 50 |
+
+To help make sense of these params, note that a malicious paymaster can at most cause the network (only the p2p network, not the blockchain) to process `BAN_SLACK * MIN_INCLUSION_RATE_DENOMINATOR / 24` non-paying ops per hour.
+
+## Rationale
+
+The main challenge with a purely smart contract wallet based account abstraction system is DoS safety: how can a block builder including an operation make sure that it will actually pay fees, without having to first execute the entire operation? Requiring the block builder to execute the entire operation opens a DoS attack vector, as an attacker could easily send many operations that pretend to pay a fee but then revert at the last moment after a long execution. Similarly, to prevent attackers from cheaply clogging the mempool, nodes in the P2P network need to check if an operation will pay a fee before they are willing to forward it.
+
+In this proposal, we expect accounts to have a `validateUserOp` method that takes as input a `UserOperation`, and verify the signature and pay the fee. This method is required to be almost-pure: it is only allowed to access the storage of the account itself, cannot use environment opcodes (eg. `TIMESTAMP`), and can only edit the storage of the account, and can also send out ETH (needed to pay the entry point). The method is gas-limited by the `verificationGasLimit` of the `UserOperation`; nodes can choose to reject operations whose `verificationGasLimit` is too high. These restrictions allow block builders and network nodes to simulate the verification step locally, and be confident that the result will match the result when the operation actually gets included into a block.
+
+The entry point-based approach allows for a clean separation between verification and execution, and keeps accounts' logic simple. The alternative would be to require accounts to follow a template where they first self-call to verify and then self-call to execute (so that the execution is sandboxed and cannot cause the fee payment to revert); template-based approaches were rejected due to being harder to implement, as existing code compilation and verification tooling is not designed around template verification.
+
+### Paymasters
+
+Paymasters facilitate transaction sponsorship, allowing third-party-designed mechanisms to pay for transactions. Many of these mechanisms _could_ be done by having the paymaster wrap a `UserOperation` with their own, but there are some important fundamental limitations to that approach:
+
+* No possibility for "passive" paymasters (eg. that accept fees in some ERC-20 token at an exchange rate pulled from an on-chain DEX)
+* Paymasters run the risk of getting griefed, as users could send ops that appear to pay the paymaster but then change their behavior after a block
+
+The paymaster scheme allows a contract to passively pay on users' behalf under arbitrary conditions. It even allows ERC-20 token paymasters to secure a guarantee that they would only need to pay if the user pays them: the paymaster contract can check that there is sufficient approved ERC-20 balance in the `validatePaymasterUserOp` method, and then extract it with `transferFrom` in the `postOp` call; if the op itself transfers out or de-approves too much of the ERC-20s, the inner `postOp` will fail and revert the execution and the outer `postOp` can extract payment (note that because of storage access restrictions the ERC-20 would need to be a wrapper defined within the paymaster itself).
+
+### First-time account creation
+
+It is an important design goal of this proposal to replicate the key property of EOAs that users do not need to perform some custom action or rely on an existing user to create their wallet; they can simply generate an address locally and immediately start accepting funds.
+
+The wallet creation itself is done by a "factory" contract, with wallet-specific data.
+The factory is expected to use CREATE2 (not CREATE) to create the wallet, so that the order of creation of wallets doesn't interfere with the generated addresses.
+The `initCode` field (if non-zero length) is parsed as a 20-byte address, followed by "calldata" to pass to this address.
+This method call is expected to create a wallet and return its address.
+If the factory does use CREATE2 or some other deterministic method to create the wallet, it's expected to return the wallet address even if the wallet has already been created. This is to make it easier for clients to query the address without knowing if the wallet has already been deployed, by simulating a call to `entryPoint.getSenderAddress()`, which calls the factory under the hood.
+When `initCode` is specified, if either the `sender` address points to an existing contract, or (after calling the initCode) the `sender` address still does not exist,
+then the operation is aborted.
+The `initCode` MUST NOT be called directly from the entryPoint, but from another address.
+The contract created by this factory method should accept a call to `validateUserOp` to validate the UserOp's signature.
+For security reasons, it is important that the generated contract address will depend on the initial signature.
+This way, even if someone can create a wallet at that address, he can't set different credentials to control it.
+The factory has to be staked if it accesses global storage - see [reputation, throttling and banning section](#reputation-scoring-and-throttlingbanning-for-global-entities) for details.
+
+NOTE: In order for the wallet to determine the "counterfactual" address of the wallet (prior its creation),
+it should make a static call to the `entryPoint.getSenderAddress()`
+
+### Entry point upgrading
+
+Accounts are encouraged to be DELEGATECALL forwarding contracts for gas efficiency and to allow account upgradability. The account code is expected to hard-code the entry point into their code for gas efficiency. If a new entry point is introduced, whether to add new functionality, improve gas efficiency, or fix a critical security bug, users can self-call to replace their account's code address with a new code address containing code that points to a new entry point. During an upgrade process, it's expected that two mempools will run in parallel.
+
+### RPC methods (eth namespace)
+
+#### * eth_sendUserOperation
+
+eth_sendUserOperation submits a User Operation object to the User Operation pool of the client. The client MUST validate the UserOperation, and return a result accordingly.
+
+The result `SHOULD` be set to the **userOpHash** if and only if the request passed simulation and was accepted in the client's User Operation pool. If the validation, simulation, or User Operation pool inclusion fails, `result` `SHOULD NOT` be returned. Rather, the client `SHOULD` return the failure reason.
+
+##### Parameters:
+
+1. **UserOperation** a full user-operation struct. All fields MUST be set as hex values. empty `bytes` block (e.g. empty `initCode`) MUST be set to `"0x"`
+2. **EntryPoint** the entrypoint address the request should be sent through. this MUST be one of the entry points returned by the `supportedEntryPoints` rpc call.
+
+##### Return value:
+
+* If the UserOperation is valid, the client MUST return the calculated **userOpHash** for it
+* in case of failure, MUST return an `error` result object, with `code` and `message`. The error code and message SHOULD be set as follows:
+ * **code: -32602** - invalid UserOperation struct/fields
+ * **code: -32500** - transaction rejected by entryPoint's simulateValidation, during wallet creation or validation
+ * The `message` field MUST be set to the FailedOp's "`AAxx`" error message from the EntryPoint
+ * **code: -32501** - transaction rejected by paymaster's validatePaymasterUserOp
+ * The `message` field SHOULD be set to the revert message from the paymaster
+ * The `data` field MUST contain a `paymaster` value
+ * **code: -32502** - transaction rejected because of opcode validation
+ * **code: -32503** - UserOperation out of time-range: either wallet or paymaster returned a time-range, and it is already expired (or will expire soon)
+ * The `data` field SHOULD contain the `validUntil` and `validAfter` values
+ * The `data` field SHOULD contain a `paymaster` value, if this error was triggered by the paymaster
+ * **code: -32504** - transaction rejected because paymaster (or signature aggregator) is throttled/banned
+ * The `data` field SHOULD contain a `paymaster` or `aggregator` value, depending on the failed entity
+ * **code: -32505** - transaction rejected because paymaster (or signature aggregator) stake or unstake-delay is too low
+ * The `data` field SHOULD contain a `paymaster` or `aggregator` value, depending on the failed entity
+ * The `data` field SHOULD contain a `minimumStake` and `minimumUnstakeDelay`
+ * **code: -32506** - transaction rejected because wallet specified unsupported signature aggregator
+ * The `data` field SHOULD contain an `aggregator` value
+ * **code: -32507** - transaction rejected because of wallet signature check failed (or paymaster signature, if the paymaster uses its data as signature)
+
+##### Example:
+
+Request:
+
+```json=
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "eth_sendUserOperation",
+ "params": [
+ {
+ sender, // address
+ nonce, // uint256
+ initCode, // bytes
+ callData, // bytes
+ callGasLimit, // uint256
+ verificationGasLimit, // uint256
+ preVerificationGas, // uint256
+ maxFeePerGas, // uint256
+ maxPriorityFeePerGas, // uint256
+ paymasterAndData, // bytes
+ signature // bytes
+ },
+ entryPoint // address
+ ]
+}
+
+```
+
+Response:
+
+```
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "0x1234...5678"
+}
+```
+
+##### Example failure responses:
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "error": {
+ "message": "AA21 didn't pay prefund",
+ "code": -32500
+ }
+}
+```
+
+```json
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "error": {
+ "message": "paymaster stake too low",
+ "data": {
+ "paymaster": "0x123456789012345678901234567890123456790",
+ "minimumStake": "0xde0b6b3a7640000",
+ "minimumUnstakeDelay": "0x15180"
+ },
+ "code": -32504
+ }
+}
+```
+
+
+#### * eth_estimateUserOperationGas
+
+Estimate the gas values for a UserOperation.
+Given UserOperation optionally without gas limits and gas prices, return the needed gas limits.
+The signature field is ignored by the wallet, so that the operation will not require user's approval.
+Still, it might require putting a "semi-valid" signature (e.g. a signature in the right length)
+
+**Parameters**: same as `eth_sendUserOperation`
+ gas limits (and prices) parameters are optional, but are used if specified.
+ `maxFeePerGas` and `maxPriorityFeePerGas` default to zero, so no payment is required by neither account nor paymaster.
+
+**Return Values:**
+
+* **preVerificationGas** gas overhead of this UserOperation
+* **verificationGasLimit** actual gas used by the validation of this UserOperation
+* **callGasLimit** value used by inner account execution
+
+##### Error Codes:
+
+Same as `eth_sendUserOperation`
+This operation may also return an error if the inner call to the account contract reverts.
+
+#### * eth_getUserOperationByHash
+
+Return a UserOperation based on a hash (userOpHash) returned by `eth_sendUserOperation`
+
+**Parameters**
+
+* **hash** a userOpHash value returned by `eth_sendUserOperation`
+
+**Return value**:
+
+`null` in case the UserOperation is not yet included in a block, or a full UserOperation, with the addition of `entryPoint`, `blockNumber`, `blockHash` and `transactionHash`
+
+#### * eth_getUserOperationReceipt
+
+Return a UserOperation receipt based on a hash (userOpHash) returned by `eth_sendUserOperation`
+
+**Parameters**
+
+* **hash** a userOpHash value returned by `eth_sendUserOperation`
+
+**Return value**:
+
+`null` in case the UserOperation is not yet included in a block, or:
+
+* **userOpHash** the request hash
+* **entryPoint**
+* **sender**
+* **nonce**
+* **paymaster** the paymaster used for this userOp (or empty)
+* **actualGasCost** - actual amount paid (by account or paymaster) for this UserOperation
+* **actualGasUsed** - total gas used by this UserOperation (including preVerification, creation, validation and execution)
+* **success** boolean - did this execution completed without revert
+* **reason** in case of revert, this is the revert reason
+* **logs** the logs generated by this UserOperation (not including logs of other UserOperations in the same bundle)
+* **receipt** the TransactionReceipt object.
+ Note that the returned TransactionReceipt is for the entire bundle, not only for this UserOperation.
+
+#### * eth_supportedEntryPoints
+
+Returns an array of the entryPoint addresses supported by the client. The first element of the array `SHOULD` be the entryPoint addressed preferred by the client.
+
+```json=
+# Request
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "eth_supportedEntryPoints",
+ "params": []
+}
+
+# Response
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": [
+ "0xcd01C8aa8995A59eB7B2627E69b40e0524B5ecf8",
+ "0x7A0A0d159218E6a2f407B99173A2b12A6DDfC2a6"
+ ]
+}
+```
+
+#### * eth_chainId
+
+Returns [EIP-155](./eip-155.md) Chain ID.
+
+```json=
+# Request
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "eth_chainId",
+ "params": []
+}
+
+# Response
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "0x1"
+}
+```
+
+### RPC methods (debug Namespace)
+
+This api must only be available on testing mode and is required by the compatibility test suite. In production, any `debug_*` rpc calls should be blocked.
+
+#### * debug_bundler_clearState
+
+Clears the bundler mempool and reputation data of paymasters/accounts/factories/aggregators.
+
+```json=
+# Request
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "debug_bundler_clearState",
+ "params": []
+}
+
+# Response
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "ok"
+}
+```
+
+#### * debug_bundler_dumpMempool
+
+Dumps the current UserOperations mempool
+
+**Parameters:**
+
+* **EntryPoint** the entrypoint used by eth_sendUserOperation
+
+**Returns:**
+
+`array` - Array of UserOperations currently in the mempool.
+
+```json=
+# Request
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "debug_bundler_dumpMempool",
+ "params": ["0x1306b01bC3e4AD202612D3843387e94737673F53"]
+}
+
+# Response
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": [
+ {
+ sender, // address
+ nonce, // uint256
+ initCode, // bytes
+ callData, // bytes
+ callGasLimit, // uint256
+ verificationGasLimit, // uint256
+ preVerificationGas, // uint256
+ maxFeePerGas, // uint256
+ maxPriorityFeePerGas, // uint256
+ paymasterAndData, // bytes
+ signature // bytes
+ }
+ ]
+}
+```
+
+#### * debug_bundler_sendBundleNow
+
+Forces the bundler to build and execute a bundle from the mempool as `handleOps()` transaction.
+
+Returns: `transactionHash`
+
+```json=
+# Request
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "debug_bundler_sendBundleNow",
+ "params": []
+}
+
+# Response
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "0xdead9e43632ac70c46b4003434058b18db0ad809617bd29f3448d46ca9085576"
+}
+```
+
+#### * debug_bundler_setBundlingMode
+
+Sets bundling mode.
+
+After setting mode to "manual", an explicit call to debug_bundler_sendBundleNow is required to send a bundle.
+
+##### parameters:
+
+`mode` - 'manual' | 'auto'
+
+```json=
+# Request
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "debug_bundler_setBundlingMode",
+ "params": ["manual"]
+}
+
+# Response
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "ok"
+}
+```
+
+#### * debug_bundler_setReputation
+
+Sets reputation of given addresses. parameters:
+
+**Parameters:**
+
+* An array of reputation entries to add/replace, with the fields:
+
+ * `address` - The address to set the reputation for.
+ * `opsSeen` - number of times a user operations with that entity was seen and added to the mempool
+ * `opsIncluded` - number of times a user operations that uses this entity was included on-chain
+ * `status` - (string) The status of the address in the bundler 'ok' | 'throttled' | 'banned'.
+
+* **EntryPoint** the entrypoint used by eth_sendUserOperation
+
+```json=
+# Request
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "debug_bundler_setReputation",
+ "params": [
+ [
+ {
+ "address": "0x7A0A0d159218E6a2f407B99173A2b12A6DDfC2a6",
+ "opsSeen": 20,
+ "opsIncluded": 13
+ }
+ ],
+ "0x1306b01bC3e4AD202612D3843387e94737673F53"
+ ]
+}
+
+# Response
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": "ok"
+}
+```
+
+
+#### * debug_bundler_dumpReputation
+
+Returns the reputation data of all observed addresses.
+Returns an array of reputation objects, each with the fields described above in `debug_bundler_setReputation` with the
+
+
+**Parameters:**
+
+* **EntryPoint** the entrypoint used by eth_sendUserOperation
+
+**Return value:**
+
+An array of reputation entries with the fields:
+
+* `address` - The address to set the reputation for.
+* `opsSeen` - number of times a user operations with that entity was seen and added to the mempool
+* `opsIncluded` - number of times a user operations that uses this entity was included on-chain
+* `status` - (string) The status of the address in the bundler 'ok' | 'throttled' | 'banned'.
+
+```json=
+# Request
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "method": "debug_bundler_dumpReputation",
+ "params": ["0x1306b01bC3e4AD202612D3843387e94737673F53"]
+}
+
+# Response
+{
+ "jsonrpc": "2.0",
+ "id": 1,
+ "result": [
+ { "address": "0x7A0A0d159218E6a2f407B99173A2b12A6DDfC2a6",
+ "opsSeen": 20,
+ "opsIncluded": 19,
+ "status": "ok"
+ }
+ ]
+}
+```
+
+## Backwards Compatibility
+
+This EIP does not change the consensus layer, so there are no backwards compatibility issues for Ethereum as a whole. Unfortunately it is not easily compatible with pre-[ERC-4337](./eip-4337.md) accounts, because those accounts do not have a `validateUserOp` function. If the account has a function for authorizing a trusted op submitter, then this could be fixed by creating an [ERC-4337](./eip-4337.md) compatible account that re-implements the verification logic as a wrapper and setting it to be the original account's trusted op submitter.
+
+## Reference Implementation
+
+See `https://github.com/eth-infinitism/account-abstraction/tree/main/contracts`
+
+## Security Considerations
+
+The entry point contract will need to be very heavily audited and formally verified, because it will serve as a central trust point for _all_ [EIP-4337](./eip-4337.md). In total, this architecture reduces auditing and formal verification load for the ecosystem, because the amount of work that individual _accounts_ have to do becomes much smaller (they need only verify the `validateUserOp` function and its "check signature, and pay fees" logic) and check that other functions are `msg.sender == ENTRY_POINT` gated (perhaps also allowing `msg.sender == self`), but it is nevertheless the case that this is done precisely by concentrating security risk in the entry point contract that needs to be verified to be very robust.
+
+Verification would need to cover two primary claims (not including claims needed to protect paymasters, and claims needed to establish p2p-level DoS resistance):
+
+* **Safety against arbitrary hijacking**: The entry point only calls an account generically if `validateUserOp` to that specific account has passed (and with `op.calldata` equal to the generic call's calldata)
+* **Safety against fee draining**: If the entry point calls `validateUserOp` and passes, it also must make the generic call with calldata equal to `op.calldata`
+
+## Copyright
+
+Copyright and related rights waived via [CC0](../LICENSE.md).
diff --git a/lib/SoulWalletCore/lib/account-abstraction/eip/assets/eip-4337/image1.png b/lib/SoulWalletCore/lib/account-abstraction/eip/assets/eip-4337/image1.png
new file mode 100644
index 00000000..ced8ea57
Binary files /dev/null and b/lib/SoulWalletCore/lib/account-abstraction/eip/assets/eip-4337/image1.png differ
diff --git a/lib/SoulWalletCore/lib/account-abstraction/eip/assets/eip-4337/image2.png b/lib/SoulWalletCore/lib/account-abstraction/eip/assets/eip-4337/image2.png
new file mode 100644
index 00000000..6d0c6f71
Binary files /dev/null and b/lib/SoulWalletCore/lib/account-abstraction/eip/assets/eip-4337/image2.png differ
diff --git a/lib/SoulWalletCore/lib/account-abstraction/gascalc/0-init-gas-checker.ts b/lib/SoulWalletCore/lib/account-abstraction/gascalc/0-init-gas-checker.ts
new file mode 100644
index 00000000..78d6b7fc
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/gascalc/0-init-gas-checker.ts
@@ -0,0 +1,12 @@
+import { GasCheckCollector, GasChecker } from './GasChecker'
+
+describe('gas calculations', function () {
+ this.timeout(60000)
+ const g = new GasChecker()
+
+ it('warmup', async function () {
+ await GasCheckCollector.init()
+ // dummy run - first run is slower.
+ await g.runTest({ title: 'simple', count: 1, diffLastGas: false })
+ })
+})
diff --git a/lib/SoulWalletCore/lib/account-abstraction/gascalc/1-simple-wallet.gas.ts b/lib/SoulWalletCore/lib/account-abstraction/gascalc/1-simple-wallet.gas.ts
new file mode 100644
index 00000000..0943d1f0
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/gascalc/1-simple-wallet.gas.ts
@@ -0,0 +1,17 @@
+import { GasChecker } from './GasChecker'
+
+context('simple account', function () {
+ this.timeout(60000)
+ const g = new GasChecker()
+
+ it('simple 1', async function () {
+ await g.addTestRow({ title: 'simple', count: 1, diffLastGas: false })
+ await g.addTestRow({ title: 'simple - diff from previous', count: 2, diffLastGas: true })
+ })
+
+ it('simple 10', async function () {
+ if (g.skipLong()) this.skip()
+ await g.addTestRow({ title: 'simple', count: 10, diffLastGas: false })
+ await g.addTestRow({ title: 'simple - diff from previous', count: 11, diffLastGas: true })
+ })
+})
diff --git a/lib/SoulWalletCore/lib/account-abstraction/gascalc/2-paymaster.gas.ts b/lib/SoulWalletCore/lib/account-abstraction/gascalc/2-paymaster.gas.ts
new file mode 100644
index 00000000..89a5d3dc
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/gascalc/2-paymaster.gas.ts
@@ -0,0 +1,43 @@
+import { parseEther } from 'ethers/lib/utils'
+import { TestPaymasterAcceptAll__factory } from '../typechain'
+import { ethers } from 'hardhat'
+import { GasChecker } from './GasChecker'
+import { Create2Factory } from '../src/Create2Factory'
+import { hexValue } from '@ethersproject/bytes'
+
+const ethersSigner = ethers.provider.getSigner()
+
+context('Minimal Paymaster', function () {
+ this.timeout(60000)
+ const g = new GasChecker()
+
+ let paymasterAddress: string
+ before(async () => {
+ const paymasterInit = hexValue(new TestPaymasterAcceptAll__factory(ethersSigner).getDeployTransaction(g.entryPoint().address).data!)
+ paymasterAddress = await new Create2Factory(ethers.provider, ethersSigner).deploy(paymasterInit, 0)
+ const paymaster = TestPaymasterAcceptAll__factory.connect(paymasterAddress, ethersSigner)
+ await paymaster.addStake(1, { value: 1 })
+ await g.entryPoint().depositTo(paymaster.address, { value: parseEther('10') })
+ })
+ it('simple paymaster', async function () {
+ await g.addTestRow({ title: 'simple paymaster', count: 1, paymaster: paymasterAddress, diffLastGas: false })
+ await g.addTestRow({
+ title: 'simple paymaster with diff',
+ count: 2,
+ paymaster: paymasterAddress,
+ diffLastGas: true
+ })
+ })
+
+ it('simple paymaster 10', async function () {
+ if (g.skipLong()) this.skip()
+
+ await g.addTestRow({ title: 'simple paymaster', count: 10, paymaster: paymasterAddress, diffLastGas: false })
+ await g.addTestRow({
+ title: 'simple paymaster with diff',
+ count: 11,
+ paymaster: paymasterAddress,
+ diffLastGas: true
+ })
+ })
+})
diff --git a/lib/SoulWalletCore/lib/account-abstraction/gascalc/3-huge-tx-gas.ts b/lib/SoulWalletCore/lib/account-abstraction/gascalc/3-huge-tx-gas.ts
new file mode 100644
index 00000000..ae762478
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/gascalc/3-huge-tx-gas.ts
@@ -0,0 +1,17 @@
+import { DefaultGasTestInfo, GasChecker } from './GasChecker'
+
+context('huge tx - 5k', function () {
+ this.timeout(60000)
+ const huge = DefaultGasTestInfo.destCallData!.padEnd(10240, 'f')
+ const g = new GasChecker()
+
+ it('big tx 5k', async () => {
+ await g.addTestRow({ title: 'big tx 5k', count: 1, destCallData: huge, diffLastGas: false })
+ await g.addTestRow({ title: 'big tx - diff from previous', count: 2, destCallData: huge, diffLastGas: true })
+ })
+ it('big tx 10', async function () {
+ if (g.skipLong()) this.skip()
+ await g.addTestRow({ title: 'big tx 5k', count: 10, destCallData: huge, diffLastGas: false })
+ await g.addTestRow({ title: 'big tx - diff from previous', count: 11, destCallData: huge, diffLastGas: true })
+ })
+})
diff --git a/lib/SoulWalletCore/lib/account-abstraction/gascalc/GasChecker.ts b/lib/SoulWalletCore/lib/account-abstraction/gascalc/GasChecker.ts
new file mode 100644
index 00000000..393e1174
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/gascalc/GasChecker.ts
@@ -0,0 +1,394 @@
+// calculate gas usage of different bundle sizes
+import '../test/aa.init'
+import { defaultAbiCoder, formatEther, hexConcat, parseEther } from 'ethers/lib/utils'
+import {
+ AddressZero,
+ checkForGeth,
+ createAddress,
+ createAccountOwner,
+ deployEntryPoint
+} from '../test/testutils'
+import {
+ EntryPoint, EntryPoint__factory, SimpleAccountFactory,
+ SimpleAccountFactory__factory, SimpleAccount__factory
+} from '../typechain'
+import { BigNumberish, Wallet } from 'ethers'
+import hre from 'hardhat'
+import { fillAndSign, fillUserOp, signUserOp } from '../test/UserOp'
+import { TransactionReceipt } from '@ethersproject/abstract-provider'
+import { table, TableUserConfig } from 'table'
+import { Create2Factory } from '../src/Create2Factory'
+import * as fs from 'fs'
+import { SimpleAccountInterface } from '../typechain/contracts/samples/SimpleAccount'
+import { UserOperation } from '../test/UserOperation'
+
+const gasCheckerLogFile = './reports/gas-checker.txt'
+
+const ethers = hre.ethers
+const provider = hre.ethers.provider
+let ethersSigner = provider.getSigner()
+let lastGasUsed: number
+
+const minDepositOrBalance = parseEther('0.1')
+
+const getBalance = hre.ethers.provider.getBalance
+
+function range (n: number): number[] {
+ return Array(n).fill(0).map((val, index) => index)
+}
+
+interface GasTestInfo {
+ title: string
+ diffLastGas: boolean
+ paymaster: string
+ count: number
+ // address, or 'random' or 'self' (for account itself)
+ dest: string
+ destValue: BigNumberish
+ destCallData: string
+ beneficiary: string
+ gasPrice: number
+}
+
+export const DefaultGasTestInfo: Partial = {
+ dest: 'self', // destination is the account itself.
+ destValue: parseEther('0'),
+ destCallData: '0xb0d691fe', // entryPoint()
+ gasPrice: 10e9
+}
+
+interface GasTestResult {
+ title: string
+ count: number
+ gasUsed: number // actual gas used
+ accountEst: number // estimateGas of the inner transaction (from EP to account)
+ gasDiff?: number // different from last test's gas used
+ receipt?: TransactionReceipt
+}
+
+/**
+ * singleton contract used by all GasChecker modules ("tests")
+ * init() static method -
+ * - create the singleton the first time (or return its existing instance)
+ * run
+ */
+
+// gas estimate of the "execFromSingleton" methods
+// we assume a given call signature has the same gas usage
+// (TODO: the estimate also depends on contract code. for test purposes, assume each contract implementation has different method signature)
+// at the end of the checks, we report the gas usage of all those method calls
+const gasEstimatePerExec: { [key: string]: { title: string, accountEst: number } } = {}
+
+/**
+ * helper contract to generate gas test.
+ * see runTest() method for "test template" info
+ * override for different account implementation:
+ * - accountInitCode() - the constructor code
+ * - accountExec() the account execution method.
+ */
+export class GasChecker {
+ accounts: { [account: string]: Wallet } = {}
+
+ accountOwner: Wallet
+
+ accountInterface: SimpleAccountInterface
+
+ constructor () {
+ this.accountOwner = createAccountOwner()
+ this.accountInterface = SimpleAccount__factory.createInterface()
+ void GasCheckCollector.init()
+ }
+
+ // generate the "exec" calldata for this account
+ accountExec (dest: string, value: BigNumberish, data: string): string {
+ return this.accountInterface.encodeFunctionData('execute', [dest, value, data])
+ }
+
+ // generate the account "creation code"
+ accountInitCode (factory: SimpleAccountFactory, salt: BigNumberish): string {
+ return hexConcat([
+ factory.address,
+ factory.interface.encodeFunctionData('createAccount', [this.accountOwner.address, salt])
+ ])
+ }
+
+ createdAccounts = new Set()
+
+ /**
+ * create accounts up to this counter.
+ * make sure they all have balance.
+ * do nothing for account already created
+ * @param count
+ */
+ async createAccounts1 (count: number): Promise {
+ const create2Factory = new Create2Factory(this.entryPoint().provider)
+ const factoryAddress = await create2Factory.deploy(
+ hexConcat([
+ SimpleAccountFactory__factory.bytecode,
+ defaultAbiCoder.encode(['address'], [this.entryPoint().address])
+ ]), 0, 2885201)
+ console.log('factaddr', factoryAddress)
+ const fact = SimpleAccountFactory__factory.connect(factoryAddress, ethersSigner)
+ // create accounts
+ const creationOps: UserOperation[] = []
+ for (const n of range(count)) {
+ const salt = n
+ // const initCode = this.accountInitCode(fact, salt)
+
+ const addr = await fact.getAddress(this.accountOwner.address, salt)
+
+ if (!this.createdAccounts.has(addr)) {
+ // explicit call to fillUseROp with no "entryPoint", to make sure we manually fill everything and
+ // not attempt to fill from blockchain.
+ const op = signUserOp(await fillUserOp({
+ sender: addr,
+ nonce: 0,
+ callGasLimit: 30000,
+ verificationGasLimit: 1000000,
+ // paymasterAndData: paymaster,
+ preVerificationGas: 1,
+ maxFeePerGas: 0
+ }), this.accountOwner, this.entryPoint().address, await provider.getNetwork().then(net => net.chainId))
+ creationOps.push(op)
+ this.createdAccounts.add(addr)
+ }
+
+ this.accounts[addr] = this.accountOwner
+ // deploy if not already deployed.
+ await fact.createAccount(this.accountOwner.address, salt)
+ const accountBalance = await GasCheckCollector.inst.entryPoint.balanceOf(addr)
+ if (accountBalance.lte(minDepositOrBalance)) {
+ await GasCheckCollector.inst.entryPoint.depositTo(addr, { value: minDepositOrBalance.mul(5) })
+ }
+ }
+ await this.entryPoint().handleOps(creationOps, ethersSigner.getAddress())
+ }
+
+ /**
+ * helper: run a test scenario, and add a table row
+ * @param params - test parameters. missing values filled in from DefaultGasTestInfo
+ * note that 2 important params are methods: accountExec() and accountInitCode()
+ */
+ async addTestRow (params: Partial): Promise {
+ await GasCheckCollector.init()
+ GasCheckCollector.inst.addRow(await this.runTest(params))
+ }
+
+ /**
+ * run a single test scenario
+ * @param params - test parameters. missing values filled in from DefaultGasTestInfo
+ * note that 2 important params are methods: accountExec() and accountInitCode()
+ */
+ async runTest (params: Partial): Promise {
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
+ const info: GasTestInfo = { ...DefaultGasTestInfo, ...params } as GasTestInfo
+
+ console.debug('== running test count=', info.count)
+
+ // fill accounts up to this code.
+ await this.createAccounts1(info.count)
+
+ let accountEst: number = 0
+ const userOps = await Promise.all(range(info.count)
+ .map(index => Object.entries(this.accounts)[index])
+ .map(async ([account, accountOwner]) => {
+ const paymaster = info.paymaster
+
+ let { dest, destValue, destCallData } = info
+ if (dest === 'self') {
+ dest = account
+ } else if (dest === 'random') {
+ dest = createAddress()
+ const destBalance = await getBalance(dest)
+ if (destBalance.eq(0)) {
+ console.log('dest replenish', dest)
+ await ethersSigner.sendTransaction({ to: dest, value: 1 })
+ }
+ }
+ const accountExecFromEntryPoint = this.accountExec(dest, destValue, destCallData)
+
+ // remove the "dest" from the key to the saved estimations
+ // so we have a single estimation per method.
+ const estimateGasKey = this.accountExec(AddressZero, destValue, destCallData)
+
+ let est = gasEstimatePerExec[estimateGasKey]
+ // technically, each UserOp needs estimate - but we know they are all the same for each test.
+ if (est == null) {
+ const accountEst = (await ethers.provider.estimateGas({
+ from: GasCheckCollector.inst.entryPoint.address,
+ to: account,
+ data: accountExecFromEntryPoint
+ })).toNumber()
+ est = gasEstimatePerExec[estimateGasKey] = { accountEst, title: info.title }
+ }
+ // console.debug('== account est=', accountEst.toString())
+ accountEst = est.accountEst
+ const op = await fillAndSign({
+ sender: account,
+ callData: accountExecFromEntryPoint,
+ maxPriorityFeePerGas: info.gasPrice,
+ maxFeePerGas: info.gasPrice,
+ callGasLimit: accountEst,
+ verificationGasLimit: 1000000,
+ paymasterAndData: paymaster,
+ preVerificationGas: 1
+ }, accountOwner, GasCheckCollector.inst.entryPoint)
+ // const packed = packUserOp(op, false)
+ // console.log('== packed cost=', callDataCost(packed), packed)
+ return op
+ }))
+
+ const txdata = GasCheckCollector.inst.entryPoint.interface.encodeFunctionData('handleOps', [userOps, info.beneficiary])
+ console.log('=== encoded data=', txdata.length)
+ const gasEst = await GasCheckCollector.inst.entryPoint.estimateGas.handleOps(
+ userOps, info.beneficiary, {}
+ )
+ const ret = await GasCheckCollector.inst.entryPoint.handleOps(userOps, info.beneficiary, { gasLimit: gasEst.mul(3).div(2) })
+ const rcpt = await ret.wait()
+ const gasUsed = rcpt.gasUsed.toNumber()
+ console.debug('count', info.count, 'gasUsed', gasUsed)
+ const gasDiff = gasUsed - lastGasUsed
+ if (info.diffLastGas) {
+ console.debug('\tgas diff=', gasDiff)
+ }
+ lastGasUsed = gasUsed
+ console.debug('handleOps tx.hash=', rcpt.transactionHash)
+ const ret1: GasTestResult = {
+ count: info.count,
+ gasUsed,
+ accountEst,
+ title: info.title
+ // receipt: rcpt
+ }
+ if (info.diffLastGas) {
+ ret1.gasDiff = gasDiff
+ }
+ console.debug(ret1)
+ return ret1
+ }
+
+ // helper methods to access the GasCheckCollector singleton
+ addRow (res: GasTestResult): void {
+ GasCheckCollector.inst.addRow(res)
+ }
+
+ entryPoint (): EntryPoint {
+ return GasCheckCollector.inst.entryPoint
+ }
+
+ skipLong (): boolean {
+ return process.env.SKIP_LONG != null
+ }
+}
+
+export class GasCheckCollector {
+ static inst: GasCheckCollector
+ static initPromise?: Promise
+
+ entryPoint: EntryPoint
+
+ static async init (): Promise {
+ if (this.inst == null) {
+ if (this.initPromise == null) {
+ this.initPromise = new GasCheckCollector()._init()
+ }
+ this.inst = await this.initPromise
+ }
+ }
+
+ async _init (entryPointAddressOrTest: string = 'test'): Promise {
+ console.log('signer=', await ethersSigner.getAddress())
+ DefaultGasTestInfo.beneficiary = createAddress()
+
+ const bal = await getBalance(ethersSigner.getAddress())
+ if (bal.gt(parseEther('100000000'))) {
+ console.log('bal=', formatEther(bal))
+ console.log('DONT use geth miner.. use account 2 instead')
+ await checkForGeth()
+ ethersSigner = ethers.provider.getSigner(2)
+ }
+
+ if (entryPointAddressOrTest === 'test') {
+ this.entryPoint = await deployEntryPoint(provider)
+ } else {
+ this.entryPoint = EntryPoint__factory.connect(entryPointAddressOrTest, ethersSigner)
+ }
+
+ const tableHeaders = [
+ 'handleOps description ',
+ 'count',
+ 'total gasUsed',
+ 'per UserOp gas\n(delta for\none UserOp)',
+ // 'account.exec()\nestimateGas',
+ 'per UserOp overhead\n(compared to\naccount.exec())'
+ ]
+
+ this.initTable(tableHeaders)
+ return this
+ }
+
+ tableConfig: TableUserConfig
+ tabRows: any[]
+
+ /**
+ * initialize our formatted table.
+ * each header define the width of the column, so make sure to pad with spaces
+ * (we stream the table, so can't learn the content length)
+ */
+ initTable (tableHeaders: string[]): void {
+ console.log('inittable')
+
+ // multiline header - check the length of the longest line.
+ // function columnWidth (header: string): number {
+ // return Math.max(...header.split('\n').map(s => s.length))
+ // }
+
+ this.tableConfig = {
+ columnDefault: { alignment: 'right' },
+ columns: [{ alignment: 'left' }]
+ // columns: tableHeaders.map((header, index) => ({
+ // alignment: index == 0 ? 'left' : 'right',
+ // width: columnWidth(header)
+ // })),
+ // columnCount: tableHeaders.length
+ }
+ this.tabRows = [tableHeaders]
+ }
+
+ doneTable (): void {
+ fs.rmSync(gasCheckerLogFile, { force: true })
+ const write = (s: string): void => {
+ console.log(s)
+ fs.appendFileSync(gasCheckerLogFile, s + '\n')
+ }
+
+ write('== gas estimate of direct calling the account\'s "execute" method')
+ write(' the destination is "account.entryPoint()", which is known to be "hot" address used by this account')
+ write(' it little higher than EOA call: its an exec from entrypoint (or account owner) into account contract, verifying msg.sender and exec to target)')
+
+ write(table(Object.values(gasEstimatePerExec).map((row) => [
+ `gas estimate "${row.title}"`, row.accountEst
+ ]), this.tableConfig))
+
+ const tableOutput = table(this.tabRows, this.tableConfig)
+ write(tableOutput)
+ process.exit(0)
+ }
+
+ addRow (res: GasTestResult): void {
+ const gasUsed = res.gasDiff != null ? '' : res.gasUsed // hide "total gasUsed" if there is a diff
+ const perOp = res.gasDiff != null ? res.gasDiff - res.accountEst : ''
+
+ this.tabRows.push([
+ res.title,
+ res.count,
+ gasUsed,
+ res.gasDiff ?? '',
+ // res.accountEst,
+ perOp])
+ }
+}
+
+after(() => {
+ GasCheckCollector.inst.doneTable()
+})
diff --git a/lib/SoulWalletCore/lib/account-abstraction/hardhat.config.ts b/lib/SoulWalletCore/lib/account-abstraction/hardhat.config.ts
new file mode 100644
index 00000000..22446c26
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/hardhat.config.ts
@@ -0,0 +1,75 @@
+import '@nomiclabs/hardhat-waffle'
+import '@typechain/hardhat'
+import { HardhatUserConfig } from 'hardhat/config'
+import 'hardhat-deploy'
+import '@nomiclabs/hardhat-etherscan'
+
+import 'solidity-coverage'
+
+import * as fs from 'fs'
+
+const mnemonicFileName = process.env.MNEMONIC_FILE ?? `${process.env.HOME}/.secret/testnet-mnemonic.txt`
+let mnemonic = 'test '.repeat(11) + 'junk'
+if (fs.existsSync(mnemonicFileName)) { mnemonic = fs.readFileSync(mnemonicFileName, 'ascii') }
+
+function getNetwork1 (url: string): { url: string, accounts: { mnemonic: string } } {
+ return {
+ url,
+ accounts: { mnemonic }
+ }
+}
+
+function getNetwork (name: string): { url: string, accounts: { mnemonic: string } } {
+ return getNetwork1(`https://${name}.infura.io/v3/${process.env.INFURA_ID}`)
+ // return getNetwork1(`wss://${name}.infura.io/ws/v3/${process.env.INFURA_ID}`)
+}
+
+const optimizedComilerSettings = {
+ version: '0.8.20',
+ settings: {
+ optimizer: { enabled: true, runs: 1000000 },
+ viaIR: true
+ }
+}
+
+// You need to export an object to set up your config
+// Go to https://hardhat.org/config/ to learn more
+
+const config: HardhatUserConfig = {
+ solidity: {
+ compilers: [{
+ version: '0.8.20',
+ settings: {
+ optimizer: { enabled: true, runs: 1000000 }
+ }
+ }],
+ overrides: {
+ 'contracts/core/EntryPoint.sol': optimizedComilerSettings,
+ 'contracts/samples/SimpleAccount.sol': optimizedComilerSettings
+ }
+ },
+ networks: {
+ dev: { url: 'http://localhost:8545' },
+ // github action starts localgeth service, for gas calculations
+ localgeth: { url: 'http://localgeth:8545' },
+ goerli: getNetwork('goerli'),
+ sepolia: getNetwork('sepolia'),
+ proxy: getNetwork1('http://localhost:8545')
+ },
+ mocha: {
+ timeout: 10000
+ },
+
+ etherscan: {
+ apiKey: process.env.ETHERSCAN_API_KEY
+ }
+
+}
+
+// coverage chokes on the "compilers" settings
+if (process.env.COVERAGE != null) {
+ // @ts-ignore
+ config.solidity = config.solidity.compilers[0]
+}
+
+export default config
diff --git a/lib/SoulWalletCore/lib/account-abstraction/package.json b/lib/SoulWalletCore/lib/account-abstraction/package.json
new file mode 100644
index 00000000..0168ad10
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/package.json
@@ -0,0 +1,70 @@
+{
+ "name": "accountabstraction",
+ "version": "0.6.0",
+ "description": "ERC-4337 Account Abstraction Implementation",
+ "scripts": {
+ "clean": "rm -rf cache artifacts typechain typechain-types",
+ "compile": "./scripts/hh-wrapper compile",
+ "tsc": "tsc",
+ "lint": "yarn compile && yarn run lint:sol && yarn run lint:js ",
+ "lint:js": "eslint -f unix .",
+ "lint-fix": "eslint -f unix . --fix",
+ "lint:sol": "solhint -f unix \"contracts/**/*.sol\" --max-warnings 0",
+ "gas-calc": "./scripts/gascalc",
+ "mocha-gascalc": "TS_NODE_TRANSPILE_ONLY=1 npx ts-mocha --bail gascalc/*",
+ "test": "./scripts/hh-wrapper test",
+ "coverage": "COVERAGE=1 hardhat coverage",
+ "deploy": "./scripts/hh-wrapper deploy",
+ "test-dev": "hardhat test --network dev",
+ "ci": "yarn compile && hardhat test && yarn run runop",
+ "ci-gas-calc": "yarn gas-calc && yarn check-gas-reports",
+ "check-gas-reports": "./scripts/check-gas-reports",
+ "runop": "hardhat run src/runop.ts ",
+ "runop-goerli": "AA_URL=https://account-abstraction-goerli.nethermind.io yarn runop --network goerli",
+ "runop3": "hardhat run src/runop3.ts "
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "devDependencies": {
+ "@nomiclabs/hardhat-ethers": "^2.0.2",
+ "@nomiclabs/hardhat-waffle": "^2.0.1",
+ "@typechain/ethers-v5": "^10.1.0",
+ "@types/chai": "^4.2.21",
+ "@types/node": "^16.4.12",
+ "@typescript-eslint/eslint-plugin": "^5.30.5",
+ "@typescript-eslint/parser": "^5.30.5",
+ "chai": "^4.3.4",
+ "eslint": "^8.19.0",
+ "eslint-config-standard": "^17.0.0",
+ "eslint-config-standard-with-typescript": "^21.0.1",
+ "eslint-plugin-import": "^2.26.0",
+ "eslint-plugin-node": "^11.1.0",
+ "eslint-plugin-promise": "^6.0.0",
+ "eslint-plugin-standard": "^5.0.0",
+ "ethereum-waffle": "^3.4.0",
+ "ethers": "^5.4.2",
+ "hardhat": "^2.6.6",
+ "solhint": "^3.3.7",
+ "ts-generator": "^0.1.1",
+ "ts-mocha": "^10.0.0",
+ "ts-node": "^10.1.0",
+ "typechain": "^8.1.0"
+ },
+ "dependencies": {
+ "@gnosis.pm/safe-contracts": "^1.3.0",
+ "@nomiclabs/hardhat-etherscan": "^2.1.6",
+ "@openzeppelin/contracts": "^5.0.0",
+ "@thehubbleproject/bls": "^0.5.1",
+ "@typechain/hardhat": "^2.3.0",
+ "@types/mocha": "^9.0.0",
+ "ethereumjs-util": "^7.1.0",
+ "ethereumjs-wallet": "^1.0.1",
+ "hardhat-deploy": "^0.11.23",
+ "hardhat-deploy-ethers": "^0.3.0-beta.11",
+ "solidity-coverage": "^0.8.2",
+ "source-map-support": "^0.5.19",
+ "table": "^6.8.0",
+ "typescript": "^4.3.5"
+ }
+}
diff --git a/lib/SoulWalletCore/lib/account-abstraction/reports/gas-checker.txt b/lib/SoulWalletCore/lib/account-abstraction/reports/gas-checker.txt
new file mode 100644
index 00000000..17dea2e6
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/reports/gas-checker.txt
@@ -0,0 +1,39 @@
+== gas estimate of direct calling the account's "execute" method
+ the destination is "account.entryPoint()", which is known to be "hot" address used by this account
+ it little higher than EOA call: its an exec from entrypoint (or account owner) into account contract, verifying msg.sender and exec to target)
+╔══════════════════════════╤════════╗
+║ gas estimate "simple" │ 29014 ║
+╟──────────────────────────┼────────╢
+║ gas estimate "big tx 5k" │ 125260 ║
+╚══════════════════════════╧════════╝
+
+╔════════════════════════════════╤═══════╤═══════════════╤════════════════╤═════════════════════╗
+║ handleOps description │ count │ total gasUsed │ per UserOp gas │ per UserOp overhead ║
+║ │ │ │ (delta for │ (compared to ║
+║ │ │ │ one UserOp) │ account.exec()) ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ simple │ 1 │ 81901 │ │ ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ simple - diff from previous │ 2 │ │ 44212 │ 15198 ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ simple │ 10 │ 479854 │ │ ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ simple - diff from previous │ 11 │ │ 44236 │ 15222 ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ simple paymaster │ 1 │ 88172 │ │ ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ simple paymaster with diff │ 2 │ │ 43165 │ 14151 ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ simple paymaster │ 10 │ 476994 │ │ ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ simple paymaster with diff │ 11 │ │ 43260 │ 14246 ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ big tx 5k │ 1 │ 182958 │ │ ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ big tx - diff from previous │ 2 │ │ 144723 │ 19463 ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ big tx 5k │ 10 │ 1485438 │ │ ║
+╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢
+║ big tx - diff from previous │ 11 │ │ 144712 │ 19452 ║
+╚════════════════════════════════╧═══════╧═══════════════╧════════════════╧═════════════════════╝
+
diff --git a/lib/SoulWalletCore/lib/account-abstraction/scripts/check-gas-reports b/lib/SoulWalletCore/lib/account-abstraction/scripts/check-gas-reports
new file mode 100755
index 00000000..d0af47d1
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/scripts/check-gas-reports
@@ -0,0 +1,17 @@
+#!/bin/bash
+# make sure gas reports are checked in with this commit
+# dump report diff
+# exit with "1" if there is a diff, zero if no diff
+
+folder=${1:-reports}
+git diff --color=always $folder
+git diff ${folder} | grep -q .
+
+if [ "$?" == 1 ]; then
+ #diff with no error - ok
+ exit
+else
+ echo ERROR: found above unchecked reports.
+ exit 1
+fi
+
diff --git a/lib/SoulWalletCore/lib/account-abstraction/scripts/docker-gascalc b/lib/SoulWalletCore/lib/account-abstraction/scripts/docker-gascalc
new file mode 100755
index 00000000..e3cdc723
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/scripts/docker-gascalc
@@ -0,0 +1,5 @@
+# run "yarn gas-calc" using geth with docker.
+# (if you have geth running on localhost:8545, its faster with "HARDHAT_NETWORK=dev yarn gas-calc")
+docker-compose -f `dirname $0`/docker-gascalc.yml up --abort-on-container-exit
+docker-compose -f `dirname $0`/docker-gascalc.yml down
+
diff --git a/lib/SoulWalletCore/lib/account-abstraction/scripts/docker-gascalc.yml b/lib/SoulWalletCore/lib/account-abstraction/scripts/docker-gascalc.yml
new file mode 100644
index 00000000..ed944339
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/scripts/docker-gascalc.yml
@@ -0,0 +1,20 @@
+version: '2'
+
+services:
+ test:
+ image: node
+ container_name: gascalc
+ depends_on:
+ - localgeth
+ volumes:
+ - ..:/app
+ working_dir: /app
+ restart: "no"
+ environment:
+ - HARDHAT_NETWORK=localgeth
+ command: "yarn mocha-gascalc"
+
+ #configuration is a copy of github/.workflows/build.xml
+ localgeth:
+ image: dtr22/geth-dev
+ container_name: localgeth
diff --git a/lib/SoulWalletCore/lib/account-abstraction/scripts/gascalc b/lib/SoulWalletCore/lib/account-abstraction/scripts/gascalc
new file mode 100755
index 00000000..b82f5327
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/scripts/gascalc
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+# run gascalc, assuming "geth" is running on localhost, port 8545
+cd `dirname $0`/..
+function getClientVersion() {
+ curl -m 1 -s -d '{"method":"web3_clientVersion","params":[],"id":1234,"jsonrpc":"2.0"}' -H content-type:application/json localhost:8545
+}
+
+if [[ `getClientVersion` =~ "Geth" ]]; then
+ echo Using GETH on localhost:8545
+ HARDHAT_NETWORK=dev yarn mocha-gascalc
+else
+ echo No GETH running on localhost:8545. Using docker..
+ ./scripts/docker-gascalc
+fi
diff --git a/lib/SoulWalletCore/lib/account-abstraction/scripts/hh-wrapper b/lib/SoulWalletCore/lib/account-abstraction/scripts/hh-wrapper
new file mode 100755
index 00000000..ada7d62d
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/scripts/hh-wrapper
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+set -euo pipefail
+export FORCE_COLOR=1
+hardhat "$@" 2>&1 | `dirname $0`/solcErrors
diff --git a/lib/SoulWalletCore/lib/account-abstraction/scripts/postpack-contracts-package.sh b/lib/SoulWalletCore/lib/account-abstraction/scripts/postpack-contracts-package.sh
new file mode 100755
index 00000000..e5ad7bfc
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/scripts/postpack-contracts-package.sh
@@ -0,0 +1,6 @@
+#!/bin/bash -xe
+#echo postpack for "contracts" package
+cd `dirname $0`/..
+pwd
+rm -rf contracts/artifacts contracts/types contracts/dist
+
diff --git a/lib/SoulWalletCore/lib/account-abstraction/scripts/prepack-contracts-package.sh b/lib/SoulWalletCore/lib/account-abstraction/scripts/prepack-contracts-package.sh
new file mode 100755
index 00000000..8d4c69aa
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/scripts/prepack-contracts-package.sh
@@ -0,0 +1,19 @@
+#!/bin/bash -xe
+#echo prepack for "contracts" package
+
+cd `dirname $0`/..
+pwd
+if git status contracts | grep -v 'nothing to commit'|tee /dev/stderr |grep -q Untracked; then
+ exit 1
+fi
+
+yarn clean
+yarn compile
+cd contracts
+
+rm -rf artifacts types dist
+
+mkdir -p artifacts
+cp `find ../artifacts/contracts -type f | grep -v -E 'Test|dbg|gnosis|bls|IOracle'` artifacts/
+npx typechain --target ethers-v5 --out-dir types artifacts/**
+npx tsc index.ts -d --outDir dist
diff --git a/lib/SoulWalletCore/lib/account-abstraction/scripts/sample-script.js b/lib/SoulWalletCore/lib/account-abstraction/scripts/sample-script.js
new file mode 100644
index 00000000..a2885d53
--- /dev/null
+++ b/lib/SoulWalletCore/lib/account-abstraction/scripts/sample-script.js
@@ -0,0 +1,32 @@
+// We require the Hardhat Runtime Environment explicitly here. This is optional
+// but useful for running the script in a standalone fashion through `node