diff --git a/README.md b/README.md index e06d9f3d..b4d95dbf 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,6 @@ Documentation: (https://github.com/bcnmy/nexus/wiki) ## Getting Started -To kickstart, follow these steps: To kickstart, follow these steps: ### Prerequisites @@ -111,11 +110,10 @@ Generate documentation from NatSpec comments. ### 🚀 Deploy Contracts -```bash -yarn run deploy:hardhat --network hardhat -``` +Nexus contracts are pre-deployed on most EVM chains. +Please see the addresses [here](https://docs.biconomy.io/contractsAndAudits). -Deploys contracts onto the blockchain network. +If you need to deploy Nexus on your own chain or you want to deploy the contracts with different addresses, please see [this](https://github.com/bcnmy/nexus/tree/deploy-v1.0.1/scripts/bash-deploy) script. Or the same script on differnet deploy branches. ### 🎨 Lint Code @@ -148,20 +146,7 @@ To generate reports of the storage layout for potential upgrades safety using `h | Auditor | Date | Final Report Link | | ---------------- | ---------- | ----------------------- | | CodeHawks-Cyfrin | 17-09-2024 | [View Report](./audits/CodeHawks-Cyfrin-17-09-2024.pdf) | -| Firm Name | DD-MM-YYYY | [View Report](./audits) | - -## 🏆 Biconomy Champions League 🏆 - -Welcome to the Champions League, a place where your contributions to Biconomy are celebrated and immortalized in our Hall of Fame. This elite group showcases individuals who have significantly advanced our mission, from enhancing code efficiency to strengthening security, and enriching our documentation. - -### Champions Roster - -| 🍊 Contributor | 🛡️ Domain | -| -------------- | ----------------- | -| @user1 | Code Optimization | -| @user2 | Security | -| @user3 | Documentation | -| ... | ... | +| Spearbit | 10/11-2024 | [View Report](./audits/report-cantinacode-biconomy-0708-final.pdf) / [View Add-on](./audits/report-cantinacode-biconomy-erc7739-addon-final.pdf) | ### Entering the League diff --git a/audits/assets/DefiSafety.Process_Quality_Review.Biconomy_Nexus.pdf b/audits/assets/DefiSafety.Process_Quality_Review.Biconomy_Nexus.pdf new file mode 100644 index 00000000..4b0111a1 Binary files /dev/null and b/audits/assets/DefiSafety.Process_Quality_Review.Biconomy_Nexus.pdf differ diff --git a/audits/report-cantinacode-biconomy-erc7739-addon-final.pdf b/audits/report-cantinacode-biconomy-erc7739-addon-final.pdf new file mode 100644 index 00000000..02cb4bd1 Binary files /dev/null and b/audits/report-cantinacode-biconomy-erc7739-addon-final.pdf differ diff --git a/contracts/Nexus.sol b/contracts/Nexus.sol index c6e83e75..265dc1de 100644 --- a/contracts/Nexus.sol +++ b/contracts/Nexus.sol @@ -18,11 +18,10 @@ import { ExecLib } from "./lib/ExecLib.sol"; import { INexus } from "./interfaces/INexus.sol"; import { BaseAccount } from "./base/BaseAccount.sol"; import { IERC7484 } from "./interfaces/IERC7484.sol"; -import { IERC7739 } from "./interfaces/IERC7739.sol"; import { ModuleManager } from "./base/ModuleManager.sol"; import { ExecutionHelper } from "./base/ExecutionHelper.sol"; import { IValidator } from "./interfaces/modules/IValidator.sol"; -import { MODULE_TYPE_VALIDATOR, MODULE_TYPE_EXECUTOR, MODULE_TYPE_FALLBACK, MODULE_TYPE_HOOK, MODULE_TYPE_MULTI, SUPPORTS_NESTED_TYPED_DATA_SIGN } from "./types/Constants.sol"; +import { MODULE_TYPE_VALIDATOR, MODULE_TYPE_EXECUTOR, MODULE_TYPE_FALLBACK, MODULE_TYPE_HOOK, MODULE_TYPE_MULTI, SUPPORTS_ERC7739 } from "./types/Constants.sol"; import { ModeLib, ExecutionMode, ExecType, CallType, CALLTYPE_BATCH, CALLTYPE_SINGLE, CALLTYPE_DELEGATECALL, EXECTYPE_DEFAULT, EXECTYPE_TRY } from "./lib/ModeLib.sol"; import { NonceLib } from "./lib/NonceLib.sol"; import { SentinelListLib, SENTINEL, ZERO_ADDRESS } from "sentinellist/SentinelList.sol"; @@ -39,6 +38,7 @@ contract Nexus is INexus, BaseAccount, ExecutionHelper, ModuleManager, UUPSUpgra using ModeLib for ExecutionMode; using ExecLib for bytes; using NonceLib for uint256; + using SentinelListLib for SentinelListLib.SentinelList; /// @dev The timelock period for emergency hook uninstallation. uint256 internal constant _EMERGENCY_TIMELOCK = 1 days; @@ -226,6 +226,15 @@ contract Nexus is INexus, BaseAccount, ExecutionHelper, ModuleManager, UUPSUpgra /// bytes4(keccak256("isValidSignature(bytes32,bytes)") = 0x1626ba7e /// @dev Delegates the validation to a validator module specified within the signature data. function isValidSignature(bytes32 hash, bytes calldata signature) external view virtual override returns (bytes4) { + // Handle potential ERC7739 support detection request + if (signature.length == 0) { + // Forces the compiler to optimize for smaller bytecode size. + if (uint256(hash) == (~signature.length / 0xffff) * 0x7739) { + return checkERC7739Support(hash, signature); + } + } + // else proceed with normal signature verification + // First 20 bytes of data will be validator address and rest of the bytes is complete signature. address validator = address(bytes20(signature[0:20])); require(_isValidatorInstalled(validator), ValidatorNotInstalled(validator)); @@ -320,19 +329,30 @@ contract Nexus is INexus, BaseAccount, ExecutionHelper, ModuleManager, UUPSUpgra UUPSUpgradeable.upgradeToAndCall(newImplementation, data); } - /// @dev For automatic detection that the smart account supports the nested EIP-712 workflow - /// Offchain usage only - /// Iterates over all the validators - function supportsNestedTypedDataSign() public view virtual returns (bytes32) { - SentinelListLib.SentinelList storage validators = _getAccountStorage().validators; - address next = validators.entries[SENTINEL]; - while (next != ZERO_ADDRESS && next != SENTINEL) { - try IERC7739(next).supportsNestedTypedDataSign() returns (bytes32 res) { - if (res == SUPPORTS_NESTED_TYPED_DATA_SIGN) return SUPPORTS_NESTED_TYPED_DATA_SIGN; - } catch {} - next = validators.entries[next]; + /// @dev For automatic detection that the smart account supports the ERC7739 workflow + /// Iterates over all the validators but only if this is a detection request + /// ERC-7739 spec assumes that if the account doesn't support ERC-7739 + /// it will try to handle the detection request as it was normal sig verification + /// request and will return 0xffffffff since it won't be able to verify the 0x signature + /// against 0x7739...7739 hash. + /// So this approach is consistent with the ERC-7739 spec. + /// If no validator supports ERC-7739, this function returns false + /// thus the account will proceed with normal signature verification + /// and return 0xffffffff as a result. + function checkERC7739Support(bytes32 hash, bytes calldata signature) public view virtual returns (bytes4) { + bytes4 result; + unchecked { + SentinelListLib.SentinelList storage validators = _getAccountStorage().validators; + address next = validators.entries[SENTINEL]; + while (next != ZERO_ADDRESS && next != SENTINEL) { + bytes4 support = IValidator(next).isValidSignatureWithSender(msg.sender, hash, signature); + if (bytes2(support) == bytes2(SUPPORTS_ERC7739) && support > result) { + result = support; + } + next = validators.getNext(next); + } } - return bytes4(0xffffffff); + return result == bytes4(0) ? bytes4(0xffffffff) : result; } /// @dev Ensures that only authorized callers can upgrade the smart contract implementation. @@ -343,6 +363,6 @@ contract Nexus is INexus, BaseAccount, ExecutionHelper, ModuleManager, UUPSUpgra /// @dev EIP712 domain name and version. function _domainNameAndVersion() internal pure override returns (string memory name, string memory version) { name = "Nexus"; - version = "1.0.0"; + version = "1.0.1"; } } diff --git a/contracts/base/ERC7739Validator.sol b/contracts/base/ERC7739Validator.sol deleted file mode 100644 index 1c97dae6..00000000 --- a/contracts/base/ERC7739Validator.sol +++ /dev/null @@ -1,310 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.27; - -import { IERC7739 } from "../interfaces/IERC7739.sol"; -import { EIP712 } from "solady/utils/EIP712.sol"; - -/// @title ERC-7739: Nested Typed Data Sign Support for ERC-7579 Validators - -abstract contract ERC7739Validator is IERC7739 { - /// @dev `keccak256("PersonalSign(bytes prefixed)")`. - bytes32 internal constant _PERSONAL_SIGN_TYPEHASH = 0x983e65e5148e570cd828ead231ee759a8d7958721a768f93bc4483ba005c32de; - bytes32 internal constant _DOMAIN_TYPEHASH = 0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f; - - /// @dev For automatic detection that the smart account supports the nested EIP-712 workflow. - /// By default, it returns `bytes32(bytes4(keccak256("supportsNestedTypedDataSign()")))`, - /// denoting support for the default behavior, as implemented in - /// `_erc1271IsValidSignatureViaNestedEIP712`, which is called in `isValidSignature`. - /// Future extensions should return a different non-zero `result` to denote different behavior. - /// This method intentionally returns bytes32 to allow freedom for future extensions. - function supportsNestedTypedDataSign() public view virtual returns (bytes32 result) { - result = bytes4(0xd620c85a); - } - - /*////////////////////////////////////////////////////////////////////////// - INTERNAL - //////////////////////////////////////////////////////////////////////////*/ - - /// @dev Returns whether the `signature` is valid for the `hash. - /// Use this in your validator's `isValidSignatureWithSender` implementation. - function _erc1271IsValidSignatureWithSender(address sender, bytes32 hash, bytes calldata signature) internal view virtual returns (bool) { - return - _erc1271IsValidSignatureViaSafeCaller(sender, hash, signature) || - _erc1271IsValidSignatureViaNestedEIP712(hash, signature) || - _erc1271IsValidSignatureViaRPC(hash, signature); - } - - /// @dev Returns whether the `msg.sender` is considered safe, such - /// that we don't need to use the nested EIP-712 workflow. - /// Override to return true for more callers. - /// See: https://mirror.xyz/curiousapple.eth/pFqAdW2LiJ-6S4sg_u1z08k4vK6BCJ33LcyXpnNb8yU - function _erc1271CallerIsSafe(address sender) internal view virtual returns (bool) { - // The canonical `MulticallerWithSigner` at 0x000000000000D9ECebf3C23529de49815Dac1c4c - // is known to include the account in the hash to be signed. - return sender == 0x000000000000D9ECebf3C23529de49815Dac1c4c; - } - - /// @dev Returns whether the `hash` and `signature` are valid. - /// Obtains the authorized signer's credentials and calls some - /// module's specific internal function to validate the signature - /// against credentials. - /// Override for your module's custom logic. - function _erc1271IsValidSignatureNowCalldata(bytes32 hash, bytes calldata signature) internal view virtual returns (bool); - - /// @dev Unwraps and returns the signature. - function _erc1271UnwrapSignature(bytes calldata signature) internal view virtual returns (bytes calldata result) { - result = signature; - /// @solidity memory-safe-assembly - assembly { - // Unwraps the ERC6492 wrapper if it exists. - // See: https://eips.ethereum.org/EIPS/eip-6492 - if eq( - calldataload(add(result.offset, sub(result.length, 0x20))), - mul(0x6492, div(not(mload(0x60)), 0xffff)) // `0x6492...6492`. - ) { - let o := add(result.offset, calldataload(add(result.offset, 0x40))) - result.length := calldataload(o) - result.offset := add(o, 0x20) - } - } - } - - /// @dev Performs the signature validation without nested EIP-712 if the caller is - /// a safe caller. A safe caller must include the address of this account in the hash. - function _erc1271IsValidSignatureViaSafeCaller( - address sender, - bytes32 hash, - bytes calldata signature - ) internal view virtual returns (bool result) { - if (_erc1271CallerIsSafe(sender)) result = _erc1271IsValidSignatureNowCalldata(hash, signature); - } - - /// @dev ERC1271 signature validation (Nested EIP-712 workflow). - /// - /// This uses ECDSA recovery by default (see: `_erc1271IsValidSignatureNowCalldata`). - /// It also uses a nested EIP-712 approach to prevent signature replays when a single EOA - /// owns multiple smart contract accounts, - /// while still enabling wallet UIs (e.g. Metamask) to show the EIP-712 values. - /// - /// Crafted for phishing resistance, efficiency, flexibility. - /// __________________________________________________________________________________________ - /// - /// Glossary: - /// - /// - `APP_DOMAIN_SEPARATOR`: The domain separator of the `hash` passed in by the application. - /// Provided by the front end. Intended to be the domain separator of the contract - /// that will call `isValidSignature` on this account. - /// - /// - `ACCOUNT_DOMAIN_SEPARATOR`: The domain separator of this account. - /// See: `EIP712._domainSeparator()`. - /// __________________________________________________________________________________________ - /// - /// For the `TypedDataSign` workflow, the final hash will be: - /// ``` - /// keccak256(\x19\x01 ‖ APP_DOMAIN_SEPARATOR ‖ - /// hashStruct(TypedDataSign({ - /// contents: hashStruct(originalStruct), - /// name: keccak256(bytes(eip712Domain().name)), - /// version: keccak256(bytes(eip712Domain().version)), - /// chainId: eip712Domain().chainId, - /// verifyingContract: eip712Domain().verifyingContract, - /// salt: eip712Domain().salt, - /// extensions: keccak256(abi.encodePacked(eip712Domain().extensions)) - /// })) - /// ) - /// ``` - /// where `‖` denotes the concatenation operator for bytes. - /// The order of the fields is important: `contents` comes before `name`. - /// - /// The signature will be `r ‖ s ‖ v ‖ - /// APP_DOMAIN_SEPARATOR ‖ contents ‖ contentsType ‖ uint16(contentsType.length)`, - /// where `contents` is the bytes32 struct hash of the original struct. - /// - /// The `APP_DOMAIN_SEPARATOR` and `contents` will be used to verify if `hash` is indeed correct. - /// __________________________________________________________________________________________ - /// - /// For the `PersonalSign` workflow, the final hash will be: - /// ``` - /// keccak256(\x19\x01 ‖ ACCOUNT_DOMAIN_SEPARATOR ‖ - /// hashStruct(PersonalSign({ - /// prefixed: keccak256(bytes(\x19Ethereum Signed Message:\n ‖ - /// base10(bytes(someString).length) ‖ someString)) - /// })) - /// ) - /// ``` - /// where `‖` denotes the concatenation operator for bytes. - /// - /// The `PersonalSign` type hash will be `keccak256("PersonalSign(bytes prefixed)")`. - /// The signature will be `r ‖ s ‖ v`. - /// __________________________________________________________________________________________ - /// - /// For demo and typescript code, see: - /// - https://github.com/junomonster/nested-eip-712 - /// - https://github.com/frangio/eip712-wrapper-for-eip1271 - /// - /// Their nomenclature may differ from ours, although the high-level idea is similar. - /// - /// Of course, if you have control over the codebase of the wallet client(s) too, - /// you can choose a more minimalistic signature scheme like - /// `keccak256(abi.encode(address(this), hash))` instead of all these acrobatics. - /// All these are just for widespread out-of-the-box compatibility with other wallet clients. - /// We want to create bazaars, not walled castles. - /// And we'll use push the Turing Completeness of the EVM to the limits to do so. - function _erc1271IsValidSignatureViaNestedEIP712(bytes32 hash, bytes calldata signature) internal view virtual returns (bool result) { - bytes32 t = _typedDataSignFieldsForAccount(msg.sender); - /// @solidity memory-safe-assembly - assembly { - let m := mload(0x40) // Cache the free memory pointer. - // `c` is `contentsType.length`, which is stored in the last 2 bytes of the signature. - let c := shr(240, calldataload(add(signature.offset, sub(signature.length, 2)))) - for {} 1 {} { - let l := add(0x42, c) // Total length of appended data (32 + 32 + c + 2). - let o := add(signature.offset, sub(signature.length, l)) // Offset of appended data. - mstore(0x00, 0x1901) // Store the "\x19\x01" prefix. - calldatacopy(0x20, o, 0x40) // Copy the `APP_DOMAIN_SEPARATOR` and `contents` struct hash. - // Use the `PersonalSign` workflow if the reconstructed hash doesn't match, - // or if the appended data is invalid, i.e. - // `appendedData.length > signature.length || contentsType.length == 0`. - if or(xor(keccak256(0x1e, 0x42), hash), or(lt(signature.length, l), iszero(c))) { - t := 0 // Set `t` to 0, denoting that we need to `hash = _hashTypedData(hash)`. - mstore(t, _PERSONAL_SIGN_TYPEHASH) - mstore(0x20, hash) // Store the `prefixed`. - hash := keccak256(t, 0x40) // Compute the `PersonalSign` struct hash. - break - } - // Else, use the `TypedDataSign` workflow. - // `TypedDataSign({ContentsName} contents,bytes1 fields,...){ContentsType}`. - mstore(m, "TypedDataSign(") // Store the start of `TypedDataSign`'s type encoding. - let p := add(m, 0x0e) // Advance 14 bytes to skip "TypedDataSign(". - calldatacopy(p, add(o, 0x40), c) // Copy `contentsType` to extract `contentsName`. - // `d & 1 == 1` means that `contentsName` is invalid. - let d := shr(byte(0, mload(p)), 0x7fffffe000000000000010000000000) // Starts with `[a-z(]`. - // Store the end sentinel '(', and advance `p` until we encounter a '(' byte. - for { - mstore(add(p, c), 40) - } iszero(eq(byte(0, mload(p)), 40)) { - p := add(p, 1) - } { - d := or(shr(byte(0, mload(p)), 0x120100000001), d) // Has a byte in ", )\x00". - } - mstore(p, " contents,bytes1 fields,string n") // Store the rest of the encoding. - mstore(add(p, 0x20), "ame,string version,uint256 chain") - mstore(add(p, 0x40), "Id,address verifyingContract,byt") - mstore(add(p, 0x60), "es32 salt,uint256[] extensions)") - p := add(p, 0x7f) - calldatacopy(p, add(o, 0x40), c) // Copy `contentsType`. - // Fill in the missing fields of the `TypedDataSign`. - calldatacopy(t, o, 0x40) // Copy the `contents` struct hash to `add(t, 0x20)`. - mstore(t, keccak256(m, sub(add(p, c), m))) // Store `typedDataSignTypehash`. - // The "\x19\x01" prefix is already at 0x00. - // `APP_DOMAIN_SEPARATOR` is already at 0x20. - mstore(0x40, keccak256(t, 0x120)) // `hashStruct(typedDataSign)`. - // Compute the final hash, corrupted if `contentsName` is invalid. - hash := keccak256(0x1e, add(0x42, and(1, d))) - signature.length := sub(signature.length, l) // Truncate the signature. - break - } - mstore(0x40, m) // Restore the free memory pointer. - } - if (t == bytes32(0)) hash = _hashTypedDataForAccount(msg.sender, hash); // `PersonalSign` workflow. - result = _erc1271IsValidSignatureNowCalldata(hash, signature); - } - - /// @dev Performs the signature validation without nested EIP-712 to allow for easy sign ins. - /// This function must always return false or revert if called on-chain. - function _erc1271IsValidSignatureViaRPC(bytes32 hash, bytes calldata signature) internal view virtual returns (bool result) { - // Non-zero gasprice is a heuristic to check if a call is on-chain, - // but we can't fully depend on it because it can be manipulated. - // See: https://x.com/NoahCitron/status/1580359718341484544 - if (tx.gasprice == uint256(0)) { - /// @solidity memory-safe-assembly - assembly { - mstore(gasprice(), gasprice()) - // See: https://gist.github.com/Vectorized/3c9b63524d57492b265454f62d895f71 - let b := 0x000000000000378eDCD5B5B0A24f5342d8C10485 // Basefee contract, - pop(staticcall(0xffff, b, codesize(), gasprice(), gasprice(), 0x20)) - // If `gasprice < basefee`, the call cannot be on-chain, and we can skip the gas burn. - if iszero(mload(gasprice())) { - let m := mload(0x40) // Cache the free memory pointer. - mstore(gasprice(), 0x1626ba7e) // `isValidSignature(bytes32,bytes)`. - mstore(0x20, b) // Recycle `b` to denote if we need to burn gas. - mstore(0x40, 0x40) - let gasToBurn := or(add(0xffff, gaslimit()), gaslimit()) - // Burns gas computationally efficiently. Also, requires that `gas > gasToBurn`. - if or(eq(hash, b), lt(gas(), gasToBurn)) { - invalid() - } - // Make a call to this with `b`, efficiently burning the gas provided. - // No valid transaction can consume more than the gaslimit. - // See: https://ethereum.github.io/yellowpaper/paper.pdf - // Most RPCs perform calls with a gas budget greater than the gaslimit. - pop(staticcall(gasToBurn, address(), 0x1c, 0x64, gasprice(), gasprice())) - mstore(0x40, m) // Restore the free memory pointer. - } - } - result = _erc1271IsValidSignatureNowCalldata(hash, signature); - } - } - - /// @dev For use in `_erc1271IsValidSignatureViaNestedEIP712`, - function _typedDataSignFieldsForAccount(address account) private view returns (bytes32 m) { - ( - bytes1 fields, - string memory name, - string memory version, - uint256 chainId, - address verifyingContract, - bytes32 salt, - uint256[] memory extensions - ) = EIP712(account).eip712Domain(); - /// @solidity memory-safe-assembly - assembly { - m := mload(0x40) // Grab the free memory pointer. - mstore(0x40, add(m, 0x120)) // Allocate the memory. - // Skip 2 words for the `typedDataSignTypehash` and `contents` struct hash. - mstore(add(m, 0x40), shl(248, byte(0, fields))) - mstore(add(m, 0x60), keccak256(add(name, 0x20), mload(name))) - mstore(add(m, 0x80), keccak256(add(version, 0x20), mload(version))) - mstore(add(m, 0xa0), chainId) - mstore(add(m, 0xc0), shr(96, shl(96, verifyingContract))) - mstore(add(m, 0xe0), salt) - mstore(add(m, 0x100), keccak256(add(extensions, 0x20), shl(5, mload(extensions)))) - } - } - - /// @notice Hashes typed data according to eip-712 - /// Uses account's domain separator - /// @param account the smart account, who's domain separator will be used - /// @param structHash the typed data struct hash - function _hashTypedDataForAccount(address account, bytes32 structHash) private view returns (bytes32 digest) { - ( - , - /*bytes1 fields*/ string memory name, - string memory version, - uint256 chainId, - address verifyingContract /*bytes32 salt*/ /*uint256[] memory extensions*/, - , - - ) = EIP712(account).eip712Domain(); - - /// @solidity memory-safe-assembly - assembly { - //Rebuild domain separator out of 712 domain - let m := mload(0x40) // Load the free memory pointer. - mstore(m, _DOMAIN_TYPEHASH) - mstore(add(m, 0x20), keccak256(add(name, 0x20), mload(name))) // Name hash. - mstore(add(m, 0x40), keccak256(add(version, 0x20), mload(version))) // Version hash. - mstore(add(m, 0x60), chainId) - mstore(add(m, 0x80), verifyingContract) - digest := keccak256(m, 0xa0) //domain separator - - // Hash typed data - mstore(0x00, 0x1901000000000000) // Store "\x19\x01". - mstore(0x1a, digest) // Store the domain separator. - mstore(0x3a, structHash) // Store the struct hash. - digest := keccak256(0x18, 0x42) - // Restore the part of the free memory slot that was overwritten. - mstore(0x3a, 0) - } - } -} diff --git a/contracts/interfaces/IERC7739.sol b/contracts/interfaces/IERC7739.sol deleted file mode 100644 index 51e73547..00000000 --- a/contracts/interfaces/IERC7739.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.27; - -interface IERC7739 { - function supportsNestedTypedDataSign() external view returns (bytes32); -} diff --git a/contracts/lib/BootstrapLib.sol b/contracts/lib/BootstrapLib.sol index c9b45297..5c614ec9 100644 --- a/contracts/lib/BootstrapLib.sol +++ b/contracts/lib/BootstrapLib.sol @@ -15,7 +15,7 @@ library BootstrapLib { /// @param module The address of the module. /// @param data The initialization data for the module. /// @return config A BootstrapConfig structure containing the module and its data. - function createSingleConfig(address module, bytes memory data) public pure returns (BootstrapConfig memory config) { + function createSingleConfig(address module, bytes memory data) internal pure returns (BootstrapConfig memory config) { config.module = module; config.data = data; } @@ -24,7 +24,7 @@ library BootstrapLib { /// @param module The address of the module. /// @param data The initialization data for the module. /// @return config An array containing a single BootstrapConfig structure. - function createArrayConfig(address module, bytes memory data) public pure returns (BootstrapConfig[] memory config) { + function createArrayConfig(address module, bytes memory data) internal pure returns (BootstrapConfig[] memory config) { config = new BootstrapConfig[](1); config[0].module = module; config[0].data = data; @@ -34,7 +34,7 @@ library BootstrapLib { /// @param modules An array of module addresses. /// @param datas An array of initialization data for each module. /// @return configs An array of BootstrapConfig structures. - function createMultipleConfigs(address[] memory modules, bytes[] memory datas) public pure returns (BootstrapConfig[] memory configs) { + function createMultipleConfigs(address[] memory modules, bytes[] memory datas) internal pure returns (BootstrapConfig[] memory configs) { require(modules.length == datas.length, "BootstrapLib: length mismatch"); configs = new BootstrapConfig[](modules.length); diff --git a/contracts/mocks/MockValidator.sol b/contracts/mocks/MockValidator.sol index e7fb8b66..5a216f4f 100644 --- a/contracts/mocks/MockValidator.sol +++ b/contracts/mocks/MockValidator.sol @@ -8,7 +8,7 @@ import { PackedUserOperation } from "account-abstraction/interfaces/PackedUserOp import { ECDSA } from "solady/utils/ECDSA.sol"; import { SignatureCheckerLib } from "solady/utils/SignatureCheckerLib.sol"; import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; -import { ERC7739Validator } from "../base/ERC7739Validator.sol"; +import { ERC7739Validator } from "erc7739Validator/ERC7739Validator.sol"; contract MockValidator is ERC7739Validator { mapping(address => address) public smartAccountOwners; @@ -24,15 +24,7 @@ contract MockValidator is ERC7739Validator { bytes calldata signature ) external view virtual returns (bytes4 sigValidationResult) { // can put additional checks based on sender here - - // check if sig is valid - bool success = _erc1271IsValidSignatureWithSender(sender, hash, _erc1271UnwrapSignature(signature)); - /// @solidity memory-safe-assembly - assembly { - // `success ? bytes4(keccak256("isValidSignature(bytes32,bytes)")) : 0xffffffff`. - // We use `0xffffffff` for invalid, in convention with the reference implementation. - sigValidationResult := shl(224, or(0x1626ba7e, sub(0, iszero(success)))) - } + return _erc1271IsValidSignatureWithSender(sender, hash, _erc1271UnwrapSignature(signature)); } // ISessionValidator interface for smart session diff --git a/contracts/mocks/MockValidator_7739v2.sol b/contracts/mocks/MockValidator_7739v2.sol new file mode 100644 index 00000000..acfc86f5 --- /dev/null +++ b/contracts/mocks/MockValidator_7739v2.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.27; + +import { IModule } from "../interfaces/modules/IModule.sol"; +import { IModuleManager } from "../interfaces/base/IModuleManager.sol"; +import { VALIDATION_SUCCESS, VALIDATION_FAILED, MODULE_TYPE_VALIDATOR, ERC1271_MAGICVALUE, ERC1271_INVALID } from "../types/Constants.sol"; +import { PackedUserOperation } from "account-abstraction/interfaces/PackedUserOperation.sol"; +import { ECDSA } from "solady/utils/ECDSA.sol"; +import { SignatureCheckerLib } from "solady/utils/SignatureCheckerLib.sol"; +import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; +import { ERC7739Validator } from "erc7739Validator/ERC7739Validator.sol"; + +contract MockValidator_7739v2 is ERC7739Validator { + mapping(address => address) public smartAccountOwners; + + function validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) external view returns (uint256 validation) { + address owner = smartAccountOwners[msg.sender]; + return _validateSignatureForOwner(owner, userOpHash, userOp.signature) ? VALIDATION_SUCCESS : VALIDATION_FAILED; + } + + function isValidSignatureWithSender( + address sender, + bytes32 hash, + bytes calldata signature + ) external view virtual returns (bytes4) { + return 0x77390002; + } + + // ISessionValidator interface for smart session + function validateSignatureWithData(bytes32 hash, bytes calldata sig, bytes calldata data) external view returns (bool validSig) { + address owner = address(bytes20(data[0:20])); + return _validateSignatureForOwner(owner, hash, sig); + } + + function _validateSignatureForOwner(address owner, bytes32 hash, bytes calldata signature) internal view returns (bool) { + if (SignatureCheckerLib.isValidSignatureNowCalldata(owner, hash, signature)) { + return true; + } + if (SignatureCheckerLib.isValidSignatureNowCalldata(owner, MessageHashUtils.toEthSignedMessageHash(hash), signature)) { + return true; + } + return false; + } + + /// @dev Returns whether the `hash` and `signature` are valid. + /// Obtains the authorized signer's credentials and calls some + /// module's specific internal function to validate the signature + /// against credentials. + function _erc1271IsValidSignatureNowCalldata(bytes32 hash, bytes calldata signature) internal view override returns (bool) { + // obtain credentials + address owner = smartAccountOwners[msg.sender]; + + // call custom internal function to validate the signature against credentials + return _validateSignatureForOwner(owner, hash, signature); + } + + /// @dev Returns whether the `sender` is considered safe, such + /// that we don't need to use the nested EIP-712 workflow. + /// See: https://mirror.xyz/curiousapple.eth/pFqAdW2LiJ-6S4sg_u1z08k4vK6BCJ33LcyXpnNb8yU + // The canonical `MulticallerWithSigner` at 0x000000000000D9ECebf3C23529de49815Dac1c4c + // is known to include the account in the hash to be signed. + // msg.sender = Smart Account + // sender = 1271 og request sender + function _erc1271CallerIsSafe(address sender) internal view virtual override returns (bool) { + return (sender == 0x000000000000D9ECebf3C23529de49815Dac1c4c || // MulticallerWithSigner + sender == msg.sender); + } + + function onInstall(bytes calldata data) external { + require(IModuleManager(msg.sender).isModuleInstalled(MODULE_TYPE_VALIDATOR, address(this), ""), "Validator is still installed"); + smartAccountOwners[msg.sender] = address(bytes20(data)); + } + + function onUninstall(bytes calldata data) external { + data; + require(!IModuleManager(msg.sender).isModuleInstalled(MODULE_TYPE_VALIDATOR, address(this), ""), "Validator is still installed"); + delete smartAccountOwners[msg.sender]; + } + + function isModuleType(uint256 moduleTypeId) external pure returns (bool) { + return moduleTypeId == MODULE_TYPE_VALIDATOR; + } + + function isOwner(address account, address owner) external view returns (bool) { + return smartAccountOwners[account] == owner; + } + + function isInitialized(address) external pure returns (bool) { + return false; + } + + function getOwner(address account) external view returns (address) { + return smartAccountOwners[account]; + } +} diff --git a/contracts/modules/validators/K1Validator.sol b/contracts/modules/validators/K1Validator.sol index 2d5dbf76..110fcfc2 100644 --- a/contracts/modules/validators/K1Validator.sol +++ b/contracts/modules/validators/K1Validator.sol @@ -14,7 +14,7 @@ pragma solidity ^0.8.27; import { ECDSA } from "solady/utils/ECDSA.sol"; import { PackedUserOperation } from "account-abstraction/interfaces/PackedUserOperation.sol"; -import { ERC7739Validator } from "../../base/ERC7739Validator.sol"; +import { ERC7739Validator } from "erc7739Validator/ERC7739Validator.sol"; import { IValidator } from "../../interfaces/modules/IValidator.sol"; import { EnumerableSet } from "../../lib/EnumerableSet4337.sol"; import { MODULE_TYPE_VALIDATOR, VALIDATION_SUCCESS, VALIDATION_FAILED } from "../../types/Constants.sol"; @@ -109,6 +109,11 @@ contract K1Validator is IValidator, ERC7739Validator { _safeSenders.remove(msg.sender, sender); } + /// @notice Checks if a sender is in the _safeSenders list for the smart account + function isSafeSender(address sender, address smartAccount) external view returns (bool) { + return _safeSenders.contains(smartAccount, sender); + } + /** * Check if the module is initialized * @param smartAccount The smart account to check @@ -141,6 +146,10 @@ contract K1Validator is IValidator, ERC7739Validator { /** * Validates an ERC-1271 signature + * @dev implements signature malleability prevention + * see: https://eips.ethereum.org/EIPS/eip-1271#reference-implementation + * Please note, that this prevention does not protect against replay attacks in general + * So the protocol using ERC-1271 should make sure hash is replay-safe. * * @param sender The sender of the ERC-1271 call to the account * @param hash The hash of the message @@ -149,20 +158,15 @@ contract K1Validator is IValidator, ERC7739Validator { * @return sigValidationResult the result of the signature validation, which can be: * - EIP1271_SUCCESS if the signature is valid * - EIP1271_FAILED if the signature is invalid + * - 0x7739000X if this is the ERC-7739 support detection request. + * Where X is the version of the ERC-7739 support. */ function isValidSignatureWithSender( address sender, bytes32 hash, bytes calldata signature - ) external view virtual override returns (bytes4 sigValidationResult) { - // check if sig is valid - bool success = _erc1271IsValidSignatureWithSender(sender, hash, _erc1271UnwrapSignature(signature)); - /// @solidity memory-safe-assembly - assembly { - // `success ? bytes4(keccak256("isValidSignature(bytes32,bytes)")) : 0xffffffff`. - // We use `0xffffffff` for invalid, in convention with the reference implementation. - sigValidationResult := shl(224, or(0x1626ba7e, sub(0, iszero(success)))) - } + ) external view virtual override returns (bytes4) { + return _erc1271IsValidSignatureWithSender(sender, hash, _erc1271UnwrapSignature(signature)); } /// @notice ISessionValidator interface for smart session @@ -188,7 +192,7 @@ contract K1Validator is IValidator, ERC7739Validator { /// @notice Returns the version of the module /// @return The version of the module function version() external pure returns (string memory) { - return "1.0.0"; + return "1.0.1"; } /// @notice Checks if the module is of the specified type @@ -238,16 +242,6 @@ contract K1Validator is IValidator, ERC7739Validator { /// @param hash The hash of the data to validate /// @param signature The signature data function _validateSignatureForOwner(address owner, bytes32 hash, bytes calldata signature) internal view returns (bool) { - // Check if the 's' value is valid - bytes32 s; - assembly { - // same as `s := mload(add(signature, 0x40))` but for calldata - s := calldataload(add(signature.offset, 0x20)) - } - if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { - return false; - } - // verify signer // owner can not be zero address in this contract if (_recoverSigner(hash, signature) == owner) return true; diff --git a/contracts/types/Constants.sol b/contracts/types/Constants.sol index 115193b0..22e00ba0 100644 --- a/contracts/types/Constants.sol +++ b/contracts/types/Constants.sol @@ -46,4 +46,5 @@ bytes32 constant MODULE_ENABLE_MODE_TYPE_HASH = keccak256(bytes(MODULE_ENABLE_MO bytes1 constant MODE_VALIDATION = 0x00; bytes1 constant MODE_MODULE_ENABLE = 0x01; -bytes32 constant SUPPORTS_NESTED_TYPED_DATA_SIGN = bytes4(0xd620c85a); +bytes4 constant SUPPORTS_ERC7739 = 0x77390000; +bytes4 constant SUPPORTS_ERC7739_V1 = 0x77390001; \ No newline at end of file diff --git a/coverage-report.html b/coverage-report.html new file mode 100644 index 00000000..5cb04eed --- /dev/null +++ b/coverage-report.html @@ -0,0 +1,165 @@ + + + + + + + LCOV - forge-pruned-lcov.info + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelCoverageTotalHit
Test:forge-pruned-lcov.infoLines:95.7 %604578
Test Date:2024-10-22 14:36:16Functions:95.7 %138132
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by file nameLine Coverage Sort by line coverageFunction Coverage Sort by function coverage
Rate Total Hit Rate Total Hit
contracts/ +
94.1%94.1%
+
94.1 %1019595.5 %2221
contracts/base/ +
96.0%96.0%
+
96.0 %35333998.5 %6766
contracts/common/ +
100.0%
+
100.0 %77100.0 %44
contracts/factory/ +
98.7%98.7%
+
98.7 %797894.7 %1918
contracts/modules/validators/ +
87.8%87.8%
+
87.8 %413684.2 %1916
contracts/utils/ +
100.0%
+
100.0 %2323100.0 %77
+
+
+ + + + +
Generated by: LCOV version 2.1-1
+
+ + + diff --git a/package.json b/package.json index d8298c72..1f3b90e2 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,18 @@ { - "name": "nexus", + "name": "bcnmy-nexus", "description": "Nexus - ERC7579 Modular Smart Account", - "version": "1.0.0", + "version": "1.0.1", "author": { "name": "Biconomy", "url": "https://github.com/bcnmy" }, - "dependencies": { - "@openzeppelin": "https://github.com/OpenZeppelin/openzeppelin-contracts", - "dotenv": "^16.4.5", - "solarray": "github:sablier-labs/solarray", - "viem": "2.7.13" - }, "devDependencies": { + "account-abstraction": "https://github.com/eth-infinitism/account-abstraction#v0.7.0", + "erc7739-validator-base": "https://github.com/erc7579/erc7739Validator#v1.0.0", + "sentinellist": "github:rhinestonewtf/sentinellist#v1.0.0", + "forge-std": "github:foundry-rs/forge-std#v1.8.2", + "solady": "github:vectorized/solady#v0.0.271", + "solarray": "github:sablier-labs/solarray", "@nomicfoundation/hardhat-chai-matchers": "^2.0.6", "@nomicfoundation/hardhat-ethers": "^3.0.6", "@nomicfoundation/hardhat-foundry": "^1.1.2", @@ -20,34 +20,28 @@ "@nomicfoundation/hardhat-toolbox": "^4.0.0", "@nomicfoundation/hardhat-verify": "^2.0.7", "@nomiclabs/hardhat-ethers": "^2.2.3", - "@prb/test": "^0.6.4", "@typechain/ethers-v6": "^0.5.1", "@typechain/hardhat": "^9.1.0", "@types/chai": "^4.3.16", "@types/mocha": ">=10.0.6", "@types/node": ">=20.12.12", - "account-abstraction": "github:eth-infinitism/account-abstraction#develop", "chai": "^4.3.7", "codecov": "^3.8.3", - "ds-test": "github:dapphub/ds-test", "ethers": "^6.12.1", - "forge-std": "github:foundry-rs/forge-std#v1.8.2", "hardhat": "^2.22.4", "hardhat-deploy": "^0.12.4", "hardhat-deploy-ethers": "^0.4.2", "hardhat-gas-reporter": "^1.0.10", "hardhat-storage-layout": "^0.1.7", "husky": "^9.0.11", - "modulekit": "github:rhinestonewtf/modulekit", "prettier": "^3.2.5", "prettier-plugin-solidity": "^1.3.1", - "sentinellist": "github:zeroknots/sentinellist", - "solady": "github:vectorized/solady", "solhint": "^5.0.1", "solhint-plugin-prettier": "^0.1.0", "solidity-coverage": "^0.8.12", "ts-node": ">=10.9.2", "typechain": "^8.3.2", + "dotenv": "^16.4.5", "typescript": ">=5.4.5" }, "keywords": [ diff --git a/remappings.txt b/remappings.txt index 1e5c3fba..1acb59a1 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,9 +1,8 @@ @openzeppelin/=node_modules/@openzeppelin/ -@prb/test/=node_modules/@prb/test/ forge-std/=node_modules/forge-std/src/ account-abstraction/=node_modules/account-abstraction/contracts/ solady/=node_modules/solady/src/ excessively-safe-call/=node_modules/excessively-safe-call/src/ sentinellist/=node_modules/sentinellist/src/ -ds-test/=node_modules/ds-test/src/ solarray/=node_modules/solarray/src/ +erc7739Validator/=node_modules/erc7739-validator-base/src/ diff --git a/scripts/hardhat/deploy-fresh.ts b/scripts/hardhat/deploy-fresh.ts index 5148919f..7bc171de 100644 --- a/scripts/hardhat/deploy-fresh.ts +++ b/scripts/hardhat/deploy-fresh.ts @@ -46,12 +46,7 @@ async function main() { await mockRegistry.waitForDeployment(); const K1ValidatorFactory = await ethers.getContractFactory( - "K1ValidatorFactory", - { - libraries: { - BootstrapLib: await bootstrapLib.getAddress(), - }, - }, + "K1ValidatorFactory" ); const k1ValidatorFactory = await K1ValidatorFactory.deploy( diff --git a/scripts/hardhat/deployToMainnet.ts b/scripts/hardhat/deployToMainnet.ts index 930ee996..3c44f6ae 100644 --- a/scripts/hardhat/deployToMainnet.ts +++ b/scripts/hardhat/deployToMainnet.ts @@ -28,10 +28,7 @@ export async function deployToMainnet() { K1Validator.address, NexusBootstrap.address, Registry.address, - ], - libraries: { - BootstrapLib: BootstrapLib.address, - }, + ] }); const BiconomyMetaFactory = await deployments.deploy("BiconomyMetaFactory", { ...deployOptions, diff --git a/test/foundry/fork/arbitrum/ArbitrumSettings.t.sol b/test/foundry/fork/arbitrum/ArbitrumSettings.t.sol index 1442aabd..a4031298 100644 --- a/test/foundry/fork/arbitrum/ArbitrumSettings.t.sol +++ b/test/foundry/fork/arbitrum/ArbitrumSettings.t.sol @@ -11,13 +11,14 @@ contract ArbitrumSettings is NexusTest_Base { address public constant ENTRYPOINT_ADDRESS = 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789; address public constant MODULE_ADDRESS = 0x0000001c5b32F37F5beA87BDD5374eB2aC54eA8e; address public constant USDC_ADDRESS = 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8; - string public constant DEFAULT_ARBITRUM_RPC_URL = "https://arbitrum.meowrpc.com"; + string public constant DEFAULT_ARBITRUM_RPC_URL = "https://rpc.ankr.com/arbitrum"; // Backup URLs // string public constant DEFAULT_ARBITRUM_RPC_URL = "https://arbitrum.blockpi.network/v1/rpc/public"; //string public constant DEFAULT_ARBITRUM_RPC_URL = "https://public.stackup.sh/api/v1/node/arbitrum-one"; //string public constant DEFAULT_ARBITRUM_RPC_URL = "https://arb-pokt.nodies.app"; //string public constant DEFAULT_ARBITRUM_RPC_URL = "https://rpc.ankr.com/arbitrum"; //string public constant DEFAULT_ARBITRUM_RPC_URL = "https://arbitrum-one-rpc.publicnode.com"; + // string public constant DEFAULT_ARBITRUM_RPC_URL = "https://arbitrum.meowrpc.com"; uint constant BLOCK_NUMBER = 209480000; /// @notice Retrieves the Arbitrum RPC URL from the environment variable or defaults to the hardcoded URL diff --git a/test/foundry/unit/concrete/erc1271/TestERC1271Account_IsValidSignature.t.sol b/test/foundry/unit/concrete/erc1271/TestERC1271Account_IsValidSignature.t.sol index 995a108a..5eeddf77 100644 --- a/test/foundry/unit/concrete/erc1271/TestERC1271Account_IsValidSignature.t.sol +++ b/test/foundry/unit/concrete/erc1271/TestERC1271Account_IsValidSignature.t.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.27; import "../../../utils/Imports.sol"; import "../../../utils/NexusTest_Base.t.sol"; +import "contracts/mocks/MockValidator_7739v2.sol"; /// @title TestERC1271Account_IsValidSignature /// @notice This contract tests the ERC1271 signature validation functionality. @@ -19,31 +20,39 @@ contract TestERC1271Account_IsValidSignature is NexusTest_Base { uint256 missingAccountFunds; } + K1Validator private validator; + bytes32 internal constant APP_DOMAIN_SEPARATOR = 0xa1a044077d7677adbbfa892ded5390979b33993e0e2a457e3f974bbcda53821b; /// @notice Initializes the testing environment. function setUp() public { init(); + validator = new K1Validator(); + bytes memory callData = + abi.encodeWithSelector(IModuleManager.installModule.selector, MODULE_TYPE_VALIDATOR, address(validator), abi.encodePacked(ALICE_ADDRESS)); + // Create an execution array with the installation call data + Execution[] memory execution = new Execution[](1); + execution[0] = Execution(address(ALICE_ACCOUNT), 0, callData); + + // Build a packed user operation for the installation + PackedUserOperation[] memory userOps = buildPackedUserOperation(ALICE, ALICE_ACCOUNT, EXECTYPE_DEFAULT, execution, address(VALIDATOR_MODULE), 0); + + // Execute the user operation to install the modules + ENTRYPOINT.handleOps(userOps, payable(BOB.addr)); } /// @notice Tests the validation of a personal signature using the mock validator. - function test_isValidSignature_PersonalSign_MockValidator_Success() public { + function test_isValidSignature_PersonalSign_K1Validator_Success() public { TestTemps memory t; t.contents = keccak256("123"); bytes32 hashToSign = toERC1271HashPersonalSign(t.contents, address(ALICE_ACCOUNT)); (t.v, t.r, t.s) = vm.sign(ALICE.privateKey, hashToSign); bytes memory signature = abi.encodePacked(t.r, t.s, t.v); - assertEq(ALICE_ACCOUNT.isValidSignature(t.contents, abi.encodePacked(address(VALIDATOR_MODULE), signature)), bytes4(0x1626ba7e)); - - unchecked { - uint256 vs = uint256(t.s) | (uint256(t.v - 27) << 255); - signature = abi.encodePacked(t.r, vs); - assertEq(ALICE_ACCOUNT.isValidSignature(t.contents, abi.encodePacked(address(VALIDATOR_MODULE), signature)), bytes4(0x1626ba7e)); - } + assertEq(ALICE_ACCOUNT.isValidSignature(t.contents, abi.encodePacked(address(validator), signature)), bytes4(0x1626ba7e)); } /// @notice Tests the validation of an EIP-712 signature using the mock validator. - function test_isValidSignature_EIP712Sign_MockValidator_Success() public { + function test_isValidSignature_EIP712Sign_K1Validator_Success() public { TestTemps memory t; t.contents = keccak256("0x1234"); bytes32 dataToSign = toERC1271Hash(t.contents, address(ALICE_ACCOUNT)); @@ -51,27 +60,18 @@ contract TestERC1271Account_IsValidSignature is NexusTest_Base { bytes memory contentsType = "Contents(bytes32 stuff)"; bytes memory signature = abi.encodePacked(t.r, t.s, t.v, APP_DOMAIN_SEPARATOR, t.contents, contentsType, uint16(contentsType.length)); if (random() % 4 == 0) signature = erc6492Wrap(signature); - bytes4 ret = ALICE_ACCOUNT.isValidSignature(toContentsHash(t.contents), abi.encodePacked(address(VALIDATOR_MODULE), signature)); + bytes4 ret = ALICE_ACCOUNT.isValidSignature(toContentsHash(t.contents), abi.encodePacked(address(validator), signature)); assertEq(ret, bytes4(0x1626ba7e)); - - unchecked { - uint256 vs = uint256(t.s) | (uint256(t.v - 27) << 255); - signature = abi.encodePacked(t.r, vs, APP_DOMAIN_SEPARATOR, t.contents, contentsType, uint16(contentsType.length)); - assertEq( - ALICE_ACCOUNT.isValidSignature(toContentsHash(t.contents), abi.encodePacked(address(VALIDATOR_MODULE), signature)), - bytes4(0x1626ba7e) - ); - } } /// @notice Tests the failure of an EIP-712 signature validation due to a wrong signer. - function test_isValidSignature_EIP712Sign_MockValidator_Wrong1271Signer_Fail() public view { + function test_isValidSignature_EIP712Sign_K1Validator_Wrong1271Signer_Fail() public view { TestTemps memory t; t.contents = keccak256("123"); (t.v, t.r, t.s) = vm.sign(BOB.privateKey, toERC1271Hash(t.contents, address(ALICE_ACCOUNT))); bytes memory contentsType = "Contents(bytes32 stuff)"; bytes memory signature = abi.encodePacked(t.r, t.s, t.v, APP_DOMAIN_SEPARATOR, t.contents, contentsType, uint16(contentsType.length)); - bytes4 ret = ALICE_ACCOUNT.isValidSignature(toContentsHash(t.contents), abi.encodePacked(address(VALIDATOR_MODULE), signature)); + bytes4 ret = ALICE_ACCOUNT.isValidSignature(toContentsHash(t.contents), abi.encodePacked(address(validator), signature)); assertEq(ret, bytes4(0xFFFFFFFF)); } @@ -90,7 +90,7 @@ contract TestERC1271Account_IsValidSignature is NexusTest_Base { // Wrap the original signature using the ERC6492 format bytes memory wrappedSignature = erc6492Wrap(signature); - bytes4 ret = ALICE_ACCOUNT.isValidSignature(toContentsHash(t.contents), abi.encodePacked(address(VALIDATOR_MODULE), wrappedSignature)); + bytes4 ret = ALICE_ACCOUNT.isValidSignature(toContentsHash(t.contents), abi.encodePacked(address(validator), wrappedSignature)); assertEq(ret, bytes4(0x1626ba7e)); } @@ -106,15 +106,22 @@ contract TestERC1271Account_IsValidSignature is NexusTest_Base { bytes memory contentsType = "Contents(bytes32 stuff)"; bytes memory signature = abi.encodePacked(t.r, t.s, t.v, APP_DOMAIN_SEPARATOR, t.contents, contentsType, uint16(contentsType.length)); - bytes4 ret = ALICE_ACCOUNT.isValidSignature(toContentsHash(t.contents), abi.encodePacked(address(VALIDATOR_MODULE), signature)); + bytes4 ret = ALICE_ACCOUNT.isValidSignature(toContentsHash(t.contents), abi.encodePacked(address(validator), signature)); assertEq(ret, bytes4(0x1626ba7e)); } - /// @notice Tests the supportsNestedTypedDataSign function. - function test_SupportsNestedTypedDataSign() public { + /// @notice Tests the ERC7739 support detection request. + function test_ERC7739SupportDetectionRequest() public { + MockValidator_7739v2 validator_7739v2 = new MockValidator_7739v2(); + vm.prank(address(ENTRYPOINT)); + ALICE_ACCOUNT.installModule(MODULE_TYPE_VALIDATOR, address(validator_7739v2), abi.encodePacked(ALICE_ADDRESS)); + assertTrue(ALICE_ACCOUNT.isModuleInstalled(MODULE_TYPE_VALIDATOR, address(validator_7739v2), "")); assertEq( - ALICE_ACCOUNT.supportsNestedTypedDataSign(), - bytes4(keccak256("supportsNestedTypedDataSign()")) + ALICE_ACCOUNT.isValidSignature( + 0x7739773977397739773977397739773977397739773977397739773977397739, + "" + ), + bytes4(0x77390002) // SUPPORTS_ERC7739_V2 ); } @@ -127,7 +134,7 @@ contract TestERC1271Account_IsValidSignature is NexusTest_Base { abi.encodePacked( abi.encode( keccak256( - "TypedDataSign(Contents contents,bytes1 fields,string name,string version,uint256 chainId,address verifyingContract,bytes32 salt,uint256[] extensions)Contents(bytes32 stuff)" + "TypedDataSign(Contents contents,string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)Contents(bytes32 stuff)" ), contents ), @@ -149,7 +156,7 @@ contract TestERC1271Account_IsValidSignature is NexusTest_Base { /// @return The ERC-1271 hash for personal sign. function toERC1271HashPersonalSign(bytes32 childHash, address account) internal view returns (bytes32) { AccountDomainStruct memory t; - (t.fields, t.name, t.version, t.chainId, t.verifyingContract, t.salt, t.extensions) = EIP712(account).eip712Domain(); + (/*t.fields*/, t.name, t.version, t.chainId, t.verifyingContract, t.salt, /*t.extensions*/) = EIP712(account).eip712Domain(); bytes32 domainSeparator = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), @@ -164,13 +171,11 @@ contract TestERC1271Account_IsValidSignature is NexusTest_Base { } struct AccountDomainStruct { - bytes1 fields; string name; string version; uint256 chainId; address verifyingContract; bytes32 salt; - uint256[] extensions; } /// @notice Retrieves the EIP-712 domain struct fields. @@ -178,17 +183,15 @@ contract TestERC1271Account_IsValidSignature is NexusTest_Base { /// @return The encoded EIP-712 domain struct fields. function accountDomainStructFields(address account) internal view returns (bytes memory) { AccountDomainStruct memory t; - (t.fields, t.name, t.version, t.chainId, t.verifyingContract, t.salt, t.extensions) = EIP712(account).eip712Domain(); + (/*fields*/, t.name, t.version, t.chainId, t.verifyingContract, t.salt, /*extensions*/) = EIP712(account).eip712Domain(); return abi.encode( - t.fields, keccak256(bytes(t.name)), keccak256(bytes(t.version)), t.chainId, t.verifyingContract, // Use the account address as the verifying contract. - t.salt, - keccak256(abi.encodePacked(t.extensions)) + t.salt ); } diff --git a/test/foundry/unit/concrete/erc1271/TestERC1271Account_MockProtocol.t.sol b/test/foundry/unit/concrete/erc1271/TestERC1271Account_MockProtocol.t.sol index ecf971c4..9d863f1e 100644 --- a/test/foundry/unit/concrete/erc1271/TestERC1271Account_MockProtocol.t.sol +++ b/test/foundry/unit/concrete/erc1271/TestERC1271Account_MockProtocol.t.sol @@ -74,7 +74,7 @@ contract TestERC1271Account_MockProtocol is NexusTest_Base { bytes32 expectedDomainSeparator = BOB_ACCOUNT.DOMAIN_SEPARATOR(); AccountDomainStruct memory t; - (t.fields, t.name, t.version, t.chainId, t.verifyingContract, t.salt, t.extensions) = BOB_ACCOUNT.eip712Domain(); + (/*t.fields*/, t.name, t.version, t.chainId, t.verifyingContract, t.salt, /*t.extensions*/) = BOB_ACCOUNT.eip712Domain(); bytes32 calculatedDomainSeparator = keccak256( abi.encode( @@ -137,13 +137,11 @@ contract TestERC1271Account_MockProtocol is NexusTest_Base { } struct AccountDomainStruct { - bytes1 fields; string name; string version; uint256 chainId; address verifyingContract; bytes32 salt; - uint256[] extensions; } /// @notice Converts the contents hash to an EIP-712 hash. @@ -162,7 +160,7 @@ contract TestERC1271Account_MockProtocol is NexusTest_Base { abi.encodePacked( abi.encode( keccak256( - "TypedDataSign(Contents contents,bytes1 fields,string name,string version,uint256 chainId,address verifyingContract,bytes32 salt,uint256[] extensions)Contents(bytes32 stuff)" + "TypedDataSign(Contents contents,string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)Contents(bytes32 stuff)" ), contents ), @@ -177,17 +175,15 @@ contract TestERC1271Account_MockProtocol is NexusTest_Base { /// @return The EIP-712 domain struct fields encoded. function accountDomainStructFields(address account) internal view returns (bytes memory) { AccountDomainStruct memory t; - (t.fields, t.name, t.version, t.chainId, t.verifyingContract, t.salt, t.extensions) = EIP712(account).eip712Domain(); + (/*t.fields*/, t.name, t.version, t.chainId, t.verifyingContract, t.salt, /*t.extensions*/) = EIP712(account).eip712Domain(); return abi.encode( - t.fields, keccak256(bytes(t.name)), keccak256(bytes(t.version)), t.chainId, t.verifyingContract, // Use the account address as the verifying contract. - t.salt, - keccak256(abi.encodePacked(t.extensions)) + t.salt ); } diff --git a/test/foundry/unit/concrete/modulemanager/TestModuleManager_EnableMode.t.sol b/test/foundry/unit/concrete/modulemanager/TestModuleManager_EnableMode.t.sol index eb08ea70..c6fbd907 100644 --- a/test/foundry/unit/concrete/modulemanager/TestModuleManager_EnableMode.t.sol +++ b/test/foundry/unit/concrete/modulemanager/TestModuleManager_EnableMode.t.sol @@ -482,7 +482,7 @@ contract TestModuleManager_EnableMode is Test, TestModuleManagement_Base { abi.encode( keccak256( abi.encodePacked( - "TypedDataSign(ModuleEnableMode contents,bytes1 fields,string name,string version,uint256 chainId,address verifyingContract,bytes32 salt,uint256[] extensions)", + "TypedDataSign(ModuleEnableMode contents,string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)", MODULE_ENABLE_MODE_NOTATION ) ), @@ -495,13 +495,11 @@ contract TestModuleManager_EnableMode is Test, TestModuleManagement_Base { } struct AccountDomainStruct { - bytes1 fields; string name; string version; uint256 chainId; address verifyingContract; bytes32 salt; - uint256[] extensions; } /// @notice Retrieves the EIP-712 domain struct fields. @@ -509,17 +507,15 @@ contract TestModuleManager_EnableMode is Test, TestModuleManagement_Base { /// @return The encoded EIP-712 domain struct fields. function accountDomainStructFields(address account) internal view returns (bytes memory) { AccountDomainStruct memory t; - (t.fields, t.name, t.version, t.chainId, t.verifyingContract, t.salt, t.extensions) = EIP712(account).eip712Domain(); + (/*t.fields*/, t.name, t.version, t.chainId, t.verifyingContract, t.salt, /*t.extensions*/) = EIP712(account).eip712Domain(); return abi.encode( - t.fields, keccak256(bytes(t.name)), keccak256(bytes(t.version)), t.chainId, t.verifyingContract, // Use the account address as the verifying contract. - t.salt, - keccak256(abi.encodePacked(t.extensions)) + t.salt ); } diff --git a/test/foundry/unit/concrete/modules/TestK1Validator.t.sol b/test/foundry/unit/concrete/modules/TestK1Validator.t.sol index f99ba7a5..47e5dad6 100644 --- a/test/foundry/unit/concrete/modules/TestK1Validator.t.sol +++ b/test/foundry/unit/concrete/modules/TestK1Validator.t.sol @@ -187,7 +187,7 @@ contract TestK1Validator is NexusTest_Base { function test_Version() public { string memory contractVersion = validator.version(); - assertEq(contractVersion, "1.0.0", "Contract version should be '1.0.0'"); + assertEq(contractVersion, "1.0.1", "Contract version should be '1.0.1'"); } /// @notice Tests the isModuleType function to return the correct module type @@ -232,21 +232,35 @@ contract TestK1Validator is NexusTest_Base { assertEq(res, VALIDATION_SUCCESS, "Valid signature should be accepted"); } - /// @notice Tests that a signature with an invalid 's' value is rejected - function test_ValidateUserOp_InvalidSValue() public { - bytes32 originalHash = keccak256(abi.encodePacked("invalid message")); - (uint8 v, bytes32 r, bytes32 s) = vm.sign(BOB.privateKey, originalHash); + /// @notice Tests signature malleability is prevented by nonce in the 4337 flow + function test_ValidateUserOp_Inverted_S_Value_Fails_because_of_nonce() public { + Counter counter = new Counter(); + //build and sign a userOp + Execution[] memory execution = new Execution[](1); + execution[0] = Execution(address(counter), 0, abi.encodeWithSelector(Counter.incrementNumber.selector)); + PackedUserOperation[] memory userOps = buildPackedUserOperation(BOB, BOB_ACCOUNT, EXECTYPE_DEFAULT, execution, address(VALIDATOR_MODULE), 0); + ENTRYPOINT.handleOps(userOps, payable(BOB.addr)); - // Ensure 's' is in the upper range (invalid) - if (uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { - s = bytes32(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A1); // Set an invalid 's' value + // parse the userOp.signature via assembly + bytes32 r; + bytes32 s; + uint8 v; + assembly { + r := mload(add(userOps, 0x20)) + s := mload(add(userOps, 0x40)) + v := byte(0, mload(add(userOps, 0x60))) } - userOp.signature = abi.encodePacked(r, s, v); - - uint256 res = validator.validateUserOp(userOp, originalHash); + // invert signature + bytes32 s1; + if (uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { + s1 = bytes32(115792089237316195423570985008687907852837564279074904382605163141518161494337 - uint256(s)); + } + userOps[0].signature = abi.encodePacked(r, s1, v == 27 ? 28 : v); - assertEq(res, VALIDATION_FAILED, "Signature with invalid 's' value should be rejected"); + bytes memory revertReason = abi.encodeWithSelector(FailedOp.selector, 0, "AA25 invalid account nonce"); + vm.expectRevert(revertReason); + ENTRYPOINT.handleOps(userOps, payable(BOB.addr)); } /// @notice Tests that a valid signature with a valid 's' value is accepted for isValidSignatureWithSender @@ -272,21 +286,30 @@ contract TestK1Validator is NexusTest_Base { } /// @notice Tests that a signature with an invalid 's' value is rejected for isValidSignatureWithSender - function test_IsValidSignatureWithSender_InvalidSValue() public { + function test_IsValidSignatureWithSender_Inverted_S_Value_Fails() public { + // allow vanilla 1271 flow + vm.prank(address(BOB_ACCOUNT)); + validator.addSafeSender(address(this)); + bytes32 originalHash = keccak256(abi.encodePacked("invalid message")); (uint8 v, bytes32 r, bytes32 s) = vm.sign(BOB.privateKey, originalHash); + bytes32 s1; // Ensure 's' is in the upper range (invalid) if (uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { - s = bytes32(0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A1); // Set an invalid 's' value + s1 = bytes32(115792089237316195423570985008687907852837564279074904382605163141518161494337 - uint256(s)); } - + // assert original signature is valid bytes memory signedMessage = abi.encodePacked(r, s, v); - bytes memory completeSignature = abi.encodePacked(address(validator), signedMessage); - - bytes4 result = BOB_ACCOUNT.isValidSignature(originalHash, completeSignature); + vm.prank(address(BOB_ACCOUNT)); + bytes4 result = validator.isValidSignatureWithSender(address(this), originalHash, signedMessage); + assertEq(result, ERC1271_MAGICVALUE, "Valid signature should be accepted"); - assertEq(result, ERC1271_INVALID, "Signature with invalid 's' value should be rejected"); + // invert signature + signedMessage = abi.encodePacked(r, s1, v == 27 ? 28 : v); + vm.prank(address(BOB_ACCOUNT)); + vm.expectRevert(bytes4(keccak256("InvalidSignature()"))); + validator.isValidSignatureWithSender(address(this), originalHash, signedMessage); } function test_IsValidSignatureWithSender_SafeCaller_Success() public { @@ -322,6 +345,36 @@ contract TestK1Validator is NexusTest_Base { assertEq(mockSafe1271Caller.balanceOf(address(BOB_ACCOUNT)), 1); } + /// @notice Tests the addSafeSender function to add a safe sender to the safe senders list + function test_addSafeSender_Success() public { + prank(address(BOB_ACCOUNT)); + validator.addSafeSender(address(mockSafe1271Caller)); + assertTrue(validator.isSafeSender(address(mockSafe1271Caller), address(BOB_ACCOUNT)), "MockSafe1271Caller should be in the safe senders list"); + } + + /// @notice Tests the removeSafeSender function to remove a safe sender from the safe senders list + function test_removeSafeSender_Success() public { + prank(address(BOB_ACCOUNT)); + validator.removeSafeSender(address(mockSafe1271Caller)); + assertFalse(validator.isSafeSender(address(mockSafe1271Caller), address(BOB_ACCOUNT)), "MockSafe1271Caller should be removed from the safe senders list"); + } + + /// @notice Tests the fillSafeSenders function to fill the safe senders list + function test_fillSafeSenders_Success() public { + prank(address(0x03)); + validator.onInstall(abi.encodePacked(address(0xdecaf0), address(0x01), address(0x02))); + assertTrue(validator.isSafeSender(address(0x01), address(0x03))); + assertTrue(validator.isSafeSender(address(0x02), address(0x03))); + } + + /// @notice Tests the isSafeSender function to check if a sender is in the safe senders list + function test_isSafeSender_Success() public { + assertFalse(validator.isSafeSender(address(0x01), address(0x03))); + prank(address(0x03)); + validator.addSafeSender(address(0x01)); + assertTrue(validator.isSafeSender(address(0x01), address(0x03))); + } + /// @notice Generates an ERC-1271 hash for personal sign /// @param childHash The child hash /// @return The ERC-1271 hash for personal sign @@ -330,7 +383,7 @@ contract TestK1Validator is NexusTest_Base { abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256("Nexus"), - keccak256("1.0.0"), + keccak256("1.0.1"), block.chainid, address(BOB_ACCOUNT) ) diff --git a/test/foundry/unit/concrete/modules/TestK1Validator.tree b/test/foundry/unit/concrete/modules/TestK1Validator.tree index 0c86110f..6d255298 100644 --- a/test/foundry/unit/concrete/modules/TestK1Validator.tree +++ b/test/foundry/unit/concrete/modules/TestK1Validator.tree @@ -11,11 +11,12 @@ TestK1Validator ├── when testing the validateUserOp function │ ├── it should succeed with a valid signature (toEthSignedMessageHash) │ └── it should fail with an invalid signature +│ └── signature malleability should be rejected because of nonce ├── when testing the isValidSignatureWithSender function │ ├── it should succeed with a valid signature │ └── it should fail with an invalid signature │ └── it should succeed with a valid signature for isValidSignatureWithSender -│ └── it should fail with an invalid 's' value for isValidSignatureWithSender +│ └── it should fail with an inverted 's' value for isValidSignatureWithSender ├── when testing the transferOwnership function │ ├── it should transfer ownership to a new address │ └── it should revert when transferring to the zero address @@ -27,3 +28,11 @@ TestK1Validator └── when testing the isModuleType function ├── it should return true for VALIDATOR module type └── it should return false for an invalid module type +├── when testing the addSafeSender function +│ └── it should add a safe sender to the safe senders list +├── when testing the removeSafeSender function +│ └── it should remove a safe sender from the safe senders list +├── when testing the fillSafeSenders function +│ └── it should fill the safe senders list +├── when testing the isSafeSender function +│ └── it should check if a sender is in the safe senders list diff --git a/test/foundry/utils/TestHelper.t.sol b/test/foundry/utils/TestHelper.t.sol index 5419eb08..e6154aa6 100644 --- a/test/foundry/utils/TestHelper.t.sol +++ b/test/foundry/utils/TestHelper.t.sol @@ -23,7 +23,7 @@ import { NexusBootstrap, BootstrapConfig } from "../../../contracts/utils/NexusB import { BiconomyMetaFactory } from "../../../contracts/factory/BiconomyMetaFactory.sol"; import { NexusAccountFactory } from "../../../contracts/factory/NexusAccountFactory.sol"; import { BootstrapLib } from "../../../contracts/lib/BootstrapLib.sol"; -import { MODE_VALIDATION } from "../../../contracts/types/Constants.sol"; +import { MODE_VALIDATION, SUPPORTS_ERC7739_V1 } from "../../../contracts/types/Constants.sol"; import { MockRegistry } from "../../../contracts/mocks/MockRegistry.sol"; import { HelperConfig } from "../../../scripts/foundry/HelperConfig.s.sol"; diff --git a/test/hardhat/smart-account/Nexus.Basics.specs.ts b/test/hardhat/smart-account/Nexus.Basics.specs.ts index 3735ea07..0ac6613c 100644 --- a/test/hardhat/smart-account/Nexus.Basics.specs.ts +++ b/test/hardhat/smart-account/Nexus.Basics.specs.ts @@ -133,9 +133,7 @@ describe("Nexus Basic Specs", function () { describe("Smart Account Basics", function () { it("Should correctly return the Nexus's ID", async function () { - expect(await smartAccount.accountId()).to.equal( - "biconomy.nexus.1.0.0", - ); + expect(await smartAccount.accountId()).to.equal("biconomy.nexus.1.0.0"); }); it("Should get implementation address of smart account", async () => { @@ -352,7 +350,7 @@ describe("Nexus Basic Specs", function () { it("Should check signature validity using smart account isValidSignature for EIP 712 signature", async function () { const PARENT_TYPEHASH = - "TypedDataSign(Contents contents,bytes1 fields,string name,string version,uint256 chainId,address verifyingContract,bytes32 salt,uint256[] extensions)Contents(bytes32 stuff)"; + "TypedDataSign(Contents contents,string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)Contents(bytes32 stuff)"; const APP_DOMAIN_SEPARATOR = "0xa1a044077d7677adbbfa892ded5390979b33993e0e2a457e3f974bbcda53821b"; const data = "0x1234"; @@ -965,22 +963,5 @@ describe("Nexus Basic Specs", function () { // Stop impersonating the smart account await stopImpersonateAccount(smartAccountAddress.toString()); }); - - it("Should return correct bytes4 value for supportsNestedTypedDataSign", async function () { - const expectedValue = ethers.zeroPadBytes("0xd620c85a", 32); - - // Impersonate the smart account - const impersonatedSmartAccount = await impersonateAccount( - smartAccountAddress.toString(), - ); - - const result = await smartAccount - .connect(impersonatedSmartAccount) - .supportsNestedTypedDataSign(); - expect(result).to.equal(expectedValue); - - // Stop impersonating the smart account - await stopImpersonateAccount(smartAccountAddress.toString()); - }); }); }); diff --git a/test/hardhat/smart-account/Nexus.Factory.specs.ts b/test/hardhat/smart-account/Nexus.Factory.specs.ts index 6774fab2..17eb9440 100644 --- a/test/hardhat/smart-account/Nexus.Factory.specs.ts +++ b/test/hardhat/smart-account/Nexus.Factory.specs.ts @@ -202,22 +202,23 @@ describe("Nexus Factory Tests", function () { ownerAddress = await owner.getAddress(); - const validator = await BootstrapLib.createSingleConfig( - await validatorModule.getAddress(), - solidityPacked(["address"], [ownerAddress]), - ); - const hook = await BootstrapLib.createSingleConfig( - await hookModule.getAddress(), - "0x", - ); + const validator = { + module: await validatorModule.getAddress(), + data: solidityPacked(["address"], [ownerAddress]), + } + + const hook = { + module: await hookModule.getAddress(), + data: "0x", + } parsedValidator = { - module: validator[0], - data: validator[1], + module: validator.module, + data: validator.data, }; parsedHook = { - module: hook[0], - data: hook[1], + module: hook.module, + data: hook.data, }; }); @@ -331,33 +332,32 @@ describe("Nexus Factory Tests", function () { ownerAddress = await owner.getAddress(); - const validator = await BootstrapLib.createSingleConfig( - await validatorModule.getAddress(), - solidityPacked(["address"], [ownerAddress]), - ); - - const executor = await BootstrapLib.createSingleConfig( - await executorModule.getAddress(), - "0x", - ); - const hook = await BootstrapLib.createSingleConfig( - await hookModule.getAddress(), - "0x", - ); + const validator = { + module: await validatorModule.getAddress(), + data: solidityPacked(["address"], [ownerAddress]), + } + const executor = { + module: await executorModule.getAddress(), + data: "0x", + } + const hook = { + module: await hookModule.getAddress(), + data: "0x", + } parsedValidator = { - module: validator[0], - data: validator[1], + module: validator.module, + data: validator.data, }; parsedExecutor = { - module: executor[0], - data: executor[1], + module: executor.module, + data: executor.data, }; parsedHook = { - module: hook[0], - data: hook[1], + module: hook.module, + data: hook.data, }; }); @@ -515,20 +515,21 @@ describe("Nexus Factory Tests", function () { registryFactory = registryFactory.connect(owner); ownerAddress = await owner.getAddress(); - - const validator = await BootstrapLib.createSingleConfig( - await validatorModule.getAddress(), - solidityPacked(["address"], [ownerAddress]), - ); - - const executor = await BootstrapLib.createSingleConfig( - await executorModule.getAddress(), - "0x", - ); - const hook = await BootstrapLib.createSingleConfig( - await hookModule.getAddress(), - "0x", - ); + + const validator = { + module: await validatorModule.getAddress(), + data: solidityPacked(["address"], [ownerAddress]), + } + + const executor = { + module: await executorModule.getAddress(), + data: "0x", + } + + const hook = { + module: await hookModule.getAddress(), + data: "0x", + } parsedValidator = { module: validator[0], diff --git a/test/hardhat/smart-account/Nexus.Module.K1Validator.specs.ts b/test/hardhat/smart-account/Nexus.Module.K1Validator.specs.ts index 993238e2..68b4d7fc 100644 --- a/test/hardhat/smart-account/Nexus.Module.K1Validator.specs.ts +++ b/test/hardhat/smart-account/Nexus.Module.K1Validator.specs.ts @@ -79,7 +79,7 @@ describe("K1Validator module tests", () => { it("should get module version", async () => { const version = await k1Validator.version(); - expect(version).to.equal("1.0.0"); + expect(version).to.equal("1.0.1"); }); it("should check module type", async () => { diff --git a/test/hardhat/utils/deployment.ts b/test/hardhat/utils/deployment.ts index 0c8f6167..cbe41592 100644 --- a/test/hardhat/utils/deployment.ts +++ b/test/hardhat/utils/deployment.ts @@ -88,12 +88,7 @@ export async function getDeployedAccountK1Factory( // Get the contract factory for K1ValidatorFactory with linked library const K1ValidatorFactory = await ethers.getContractFactory( - "K1ValidatorFactory", - { - libraries: { - BootstrapLib: await BootstrapLib.getAddress(), - }, - }, + "K1ValidatorFactory" ); const deterministicAccountFactory = await deployments.deploy( @@ -102,9 +97,6 @@ export async function getDeployedAccountK1Factory( from: addresses[0], deterministicDeployment: true, args: [implementationAddress, owner, k1Validator, bootstrapper, registry], - libraries: { - BootstrapLib: await BootstrapLib.getAddress(), - }, }, ); diff --git a/test/hardhat/utils/operationHelpers.ts b/test/hardhat/utils/operationHelpers.ts index 2b0b5e45..b12e0c02 100644 --- a/test/hardhat/utils/operationHelpers.ts +++ b/test/hardhat/utils/operationHelpers.ts @@ -225,12 +225,7 @@ export async function getInitCode( BootstrapLib.waitForDeployment(); const K1ValidatorFactory = await ethers.getContractFactory( - "K1ValidatorFactory", - { - libraries: { - BootstrapLib: await BootstrapLib.getAddress(), - }, - }, + "K1ValidatorFactory" ); // Encode the createAccount function call with the provided parameters @@ -472,23 +467,13 @@ export async function getAccountDomainStructFields( const [fields, name, version, chainId, verifyingContract, salt, extensions] = await account.eip712Domain(); return ethers.AbiCoder.defaultAbiCoder().encode( + ["bytes32", "bytes32", "uint256", "address", "bytes32"], [ - "bytes1", - "bytes32", - "bytes32", - "uint256", - "address", - "bytes32", - "bytes32", - ], - [ - fields, // matches Solidity ethers.keccak256(ethers.toUtf8Bytes(name)), // matches Solidity ethers.keccak256(ethers.toUtf8Bytes(version)), // matches Solidity chainId, verifyingContract, salt, - ethers.keccak256(ethers.solidityPacked(["uint256[]"], [extensions])), ], ); } diff --git a/yarn.lock b/yarn.lock index 69a234fd..9047bad3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -41,39 +41,25 @@ table "^6.8.0" typescript "^4.3.5" -"@adraffy/ens-normalize@1.10.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" - integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== - "@adraffy/ens-normalize@1.10.1": version "1.10.1" resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== "@babel/code-frame@^7.0.0": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" - integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== - dependencies: - "@babel/highlight" "^7.24.7" - picocolors "^1.0.0" - -"@babel/helper-validator-identifier@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" - integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== - -"@babel/highlight@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" - integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" + integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== dependencies: - "@babel/helper-validator-identifier" "^7.24.7" - chalk "^2.4.2" + "@babel/helper-validator-identifier" "^7.25.9" js-tokens "^4.0.0" picocolors "^1.0.0" +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -81,6 +67,10 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@erc7579/enumerablemap4337@https://github.com/erc7579/enumerablemap": + version "1.0.0" + resolved "https://github.com/erc7579/enumerablemap#36291c5aeccb82d25d95e44bec617470e171a1a6" + "@ethereumjs/rlp@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" @@ -476,7 +466,7 @@ tweetnacl "^1.0.3" tweetnacl-util "^0.15.1" -"@noble/curves@1.2.0", "@noble/curves@~1.2.0": +"@noble/curves@1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== @@ -510,11 +500,6 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0" integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA== -"@noble/hashes@~1.3.0", "@noble/hashes@~1.3.2": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" - integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== - "@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" @@ -541,53 +526,53 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nomicfoundation/edr-darwin-arm64@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.6.2.tgz#52c3da9dcdab72c0447b41faa63264de84c9b6c3" - integrity sha512-o4A9SaPlxJ1MS6u8Ozqq7Y0ri2XO0jASw+qkytQyBYowNFNReoGqVSs7SCwenYCDiN+1il8+M0VAUq7wOovnCQ== +"@nomicfoundation/edr-darwin-arm64@0.6.4": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.6.4.tgz#6eaa64a6ea5201e4c92b121f2b7fd197b26e450a" + integrity sha512-QNQErISLgssV9+qia8sIjRANqtbW8snSDvjspixT/kSQ5ZSGxxctTg7x72wPSrcu8+EBEveIe5uqENIp5GH8HQ== -"@nomicfoundation/edr-darwin-x64@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.6.2.tgz#327deb548f2ae62eb456ba183970b022eb98c509" - integrity sha512-WG8BeG2eR3rFC+2/9V1hoPGW7tmNRUcuztdHUijO1h2flRsf2YWv+kEHO+EEnhGkEbgBUiwOrwlwlSMxhe2cGA== +"@nomicfoundation/edr-darwin-x64@0.6.4": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.6.4.tgz#d15ca89e9deef7d0a710cf90e79f3cc270a5a999" + integrity sha512-cjVmREiwByyc9+oGfvAh49IAw+oVJHF9WWYRD+Tm/ZlSpnEVWxrGNBak2bd/JSYjn+mZE7gmWS4SMRi4nKaLUg== -"@nomicfoundation/edr-linux-arm64-gnu@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.6.2.tgz#83daecf1ced46bb4c70326e9358d0c2ae69b472a" - integrity sha512-wvHaTmOwuPjRIOqBB+paI3RBdNlG8f3e1F2zWj75EdeWwefimPzzFUs05JxOYuPO0JhDQIn2tbYUgdZbBQ+mqg== +"@nomicfoundation/edr-linux-arm64-gnu@0.6.4": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.6.4.tgz#e73c41ca015dfddb5f4cb6cd3d9b2cbe5cc28989" + integrity sha512-96o9kRIVD6W5VkgKvUOGpWyUGInVQ5BRlME2Fa36YoNsRQMaKtmYJEU0ACosYES6ZTpYC8U5sjMulvPtVoEfOA== -"@nomicfoundation/edr-linux-arm64-musl@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.6.2.tgz#b0666da450d68364975562ec5f7c2b6ee718e36b" - integrity sha512-UrOAxnsywUcEngQM2ZxIuucci0VX29hYxX7jcpwZU50HICCjxNsxnuXYPxv+IM+6gbhBY1FYvYJGW4PJcP1Nyw== +"@nomicfoundation/edr-linux-arm64-musl@0.6.4": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.6.4.tgz#90906f733e4ad26657baeb22d28855d934ab7541" + integrity sha512-+JVEW9e5plHrUfQlSgkEj/UONrIU6rADTEk+Yp9pbe+mzNkJdfJYhs5JYiLQRP4OjxH4QOrXI97bKU6FcEbt5Q== -"@nomicfoundation/edr-linux-x64-gnu@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.6.2.tgz#c61ae692ddf906e65078962e6d86daaa04f95d0d" - integrity sha512-gYxlPLi7fkNcmDmCwZWQa5eOfNcTDundE+TWjpyafxLAjodQuKBD4I0p4XbnuocHjoBEeNzLWdE5RShbZEXEJA== +"@nomicfoundation/edr-linux-x64-gnu@0.6.4": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.6.4.tgz#11b8bd73df145a192e5a08199e5e81995fcde502" + integrity sha512-nzYWW+fO3EZItOeP4CrdMgDXfaGBIBkKg0Y/7ySpUxLqzut40O4Mb0/+quqLAFkacUSWMlFp8nsmypJfOH5zoA== -"@nomicfoundation/edr-linux-x64-musl@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.6.2.tgz#a2714ee7a62faf55c7994c7eaddeb32d0622801d" - integrity sha512-ev5hy9wmiHZi1GKQ1l6PJ2+UpsUh+DvK9AwiCZVEdaicuhmTfO6fdL4szgE4An8RU+Ou9DeiI1tZcq6iw++Wuw== +"@nomicfoundation/edr-linux-x64-musl@0.6.4": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.6.4.tgz#a34b9a2c9e34853207824dc81622668a069ca642" + integrity sha512-QFRoE9qSQ2boRrVeQ1HdzU+XN7NUgwZ1SIy5DQt4d7jCP+5qTNsq8LBNcqhRBOATgO63nsweNUhxX/Suj5r1Sw== -"@nomicfoundation/edr-win32-x64-msvc@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.6.2.tgz#5507884a81d57f337363b7fbf9bf4ae93ff69c0c" - integrity sha512-2ZXVVcmdmEeX0Hb3IAurHUjgU3H1GIk9h7Okosdjgl3tl+BaNHxi84Us+DblynO1LRj8nL/ATeVtSfBuW3Z1vw== +"@nomicfoundation/edr-win32-x64-msvc@0.6.4": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.6.4.tgz#ca035c6f66ae9f88fa3ef123a1f3a2099cce7a5a" + integrity sha512-2yopjelNkkCvIjUgBGhrn153IBPLwnsDeNiq6oA0WkeM8tGmQi4td+PGi9jAriUDAkc59Yoi2q9hYA6efiY7Zw== -"@nomicfoundation/edr@^0.6.1": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.6.2.tgz#6911d9a0b36bc054747dcd1ae894ce447400be31" - integrity sha512-yPUegN3sTWiAkRatCmGRkuvMgD9HSSpivl2ebAqq0aU2xgC7qmIO+YQPxQ3Z46MUoi7MrTf4e6GpbT4S/8x0ew== +"@nomicfoundation/edr@^0.6.4": + version "0.6.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.6.4.tgz#1cd336c46a60f5af774e6cf0f1943f49f63dded6" + integrity sha512-YgrSuT3yo5ZQkbvBGqQ7hG+RDvz3YygSkddg4tb1Z0Y6pLXFzwrcEwWaJCFAVeeZxdxGfCgGMUYgRVneK+WXkw== dependencies: - "@nomicfoundation/edr-darwin-arm64" "0.6.2" - "@nomicfoundation/edr-darwin-x64" "0.6.2" - "@nomicfoundation/edr-linux-arm64-gnu" "0.6.2" - "@nomicfoundation/edr-linux-arm64-musl" "0.6.2" - "@nomicfoundation/edr-linux-x64-gnu" "0.6.2" - "@nomicfoundation/edr-linux-x64-musl" "0.6.2" - "@nomicfoundation/edr-win32-x64-msvc" "0.6.2" + "@nomicfoundation/edr-darwin-arm64" "0.6.4" + "@nomicfoundation/edr-darwin-x64" "0.6.4" + "@nomicfoundation/edr-linux-arm64-gnu" "0.6.4" + "@nomicfoundation/edr-linux-arm64-musl" "0.6.4" + "@nomicfoundation/edr-linux-x64-gnu" "0.6.4" + "@nomicfoundation/edr-linux-x64-musl" "0.6.4" + "@nomicfoundation/edr-win32-x64-msvc" "0.6.4" "@nomicfoundation/ethereumjs-common@4.0.4": version "4.0.4" @@ -748,13 +733,9 @@ integrity sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA== "@openzeppelin/contracts@^5.0.0": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.0.2.tgz#b1d03075e49290d06570b2fd42154d76c2a5d210" - integrity sha512-ytPc6eLGcHHnapAZ9S+5qsdomhjo6QBHTDRRBFfTxXIpsicMhVPouPgmUPebZZZGX7vt9USA+Z+0M0dSVtSUEA== - -"@openzeppelin@https://github.com/OpenZeppelin/openzeppelin-contracts": - version "5.0.2" - resolved "https://github.com/OpenZeppelin/openzeppelin-contracts#49cd64565aafa5b8f6863bf60a30ef015861614c" + version "5.1.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-5.1.0.tgz#4e61162f2a2bf414c4e10c45eca98ce5f1aadbd4" + integrity sha512-p1ULhl7BXzjjbha5aqst+QMLY+4/LCWADXOCsmLHRM77AqiPjnd9vvUN9sosUfhL9JGKpZ0TjEGxgvnizmWGSA== "@pnpm/config.env-replace@^1.1.0": version "1.1.0" @@ -778,62 +759,66 @@ config-chain "^1.1.11" "@prb/math@^4.0.2": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@prb/math/-/math-4.0.3.tgz#08b4cc6f7ea98d6228ba577be4b692bd39e17c40" - integrity sha512-/RSt3VU1k2m3ox6U6kUL1MrktnAHr8vhydXu4eDtqFAms1gm3XnGpoZIPaK1lm2zdJQmKBwJ4EXALPARsuOlaA== - -"@prb/test@^0.6.4": - version "0.6.4" - resolved "https://registry.yarnpkg.com/@prb/test/-/test-0.6.4.tgz#20faa4b06e8c6e8fd19adcb8eb88d29d9f755afc" - integrity sha512-P0tTMsB6XQ0Wp61EYdXJYFhsOVGyZvcOFub2y9yk0sF+GYDusctR7DzEI+vOP0SILm3knFkEJASjewHEBppdRQ== + version "4.1.0" + resolved "https://registry.yarnpkg.com/@prb/math/-/math-4.1.0.tgz#cb65ff415d5cb1539b7d1b0bc41ecc55c0c12b5f" + integrity sha512-ef5Xrlh3BeX4xT5/Wi810dpEPq2bYPndRxgFIaKSU1F/Op/s8af03kyom+mfU7gEpvfIZ46xu8W0duiHplbBMg== "@prettier/sync@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@prettier/sync/-/sync-0.3.0.tgz#91f2cfc23490a21586d1cf89c6f72157c000ca1e" integrity sha512-3dcmCyAxIcxy036h1I7MQU/uEEBq8oLwf1CE3xeze+MPlgkdlb/+w6rGR/1dhp6Hqi17fRS6nvwnOzkESxEkOw== -"@rhinestone/checknsignatures@github:rhinestonewtf/checknsignatures": - version "0.0.1" - resolved "https://codeload.github.com/rhinestonewtf/checknsignatures/tar.gz/7ff44ef46da1266374e6a98e6cf69d727d7c357d" - dependencies: - forge-std "github:foundry-rs/forge-std" - solady "github:vectorized/solady" - -"@rhinestone/erc4337-validation@0.0.1-alpha.2": - version "0.0.1-alpha.2" - resolved "https://registry.yarnpkg.com/@rhinestone/erc4337-validation/-/erc4337-validation-0.0.1-alpha.2.tgz#9278ca59972e12838e3a25230041cc21d1c8053f" - integrity sha512-sxBSHoR0hV0rN2bv5HfINHR3RyBChfd0OWH0TP8nlA9FolJ1EezLByxcyrvAgi2QLQ2Zf2zVcNky1qYdfF4NjQ== +"@rhinestone/erc4337-validation@^0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@rhinestone/erc4337-validation/-/erc4337-validation-0.0.4.tgz#85d29a8f624c66ae5cbf9eea86c3bbaccbce649f" + integrity sha512-9GPvOvmM9j5ZZRCFeujPacUyByRnrGL22/5177hRzXh5mLq/A22EyvVIVNcsWMvNiLcHAV4dkkKpXaljxNOT9A== dependencies: "@openzeppelin/contracts" "5.0.1" account-abstraction "github:kopy-kat/account-abstraction#develop" account-abstraction-v0.6 "github:eth-infinitism/account-abstraction#v0.6.0" ds-test "github:dapphub/ds-test" - forge-std "github:foundry-rs/forge-std" + forge-std "github:foundry-rs/forge-std#8a225d81aa8e2e013580564588c79abb65eacc9e" prettier "^2.8.8" solady "github:vectorized/solady" - solhint "^4.1.1" -"@rhinestone/erc4337-validation@^0.0.1-alpha.5": - version "0.0.1-alpha.5" - resolved "https://registry.yarnpkg.com/@rhinestone/erc4337-validation/-/erc4337-validation-0.0.1-alpha.5.tgz#ddcecdb0c43c68de7f542d0b3b48797cce7ba736" - integrity sha512-yOrYyQBrT0JfHb+rjvx4pqk8uItKxEtn7n8z3k0qbZTzkXaNS9pCUBsTxy0kp6T2SNUrbQ8I4DMSiyGqjdh2ng== +"@rhinestone/module-bases@github:rhinestonewtf/module-bases": + version "0.0.1" + resolved "https://codeload.github.com/rhinestonewtf/module-bases/tar.gz/92fe10438701c35af92cda56deda1fbccde1c67d" dependencies: - "@openzeppelin/contracts" "5.0.1" - account-abstraction "github:kopy-kat/account-abstraction#develop" - account-abstraction-v0.6 "github:eth-infinitism/account-abstraction#v0.6.0" - ds-test "github:dapphub/ds-test" + "@ERC4337/account-abstraction" "github:kopy-kat/account-abstraction#develop" + erc7579 "github:erc7579/erc7579-implementation" forge-std "github:foundry-rs/forge-std" - prettier "^2.8.8" - solady "github:vectorized/solady" -"@rhinestone/module-bases@github:rhinestonewtf/module-bases": +"@rhinestone/module-bases@github:rhinestonewtf/module-bases#d048ec28c8ea8b4155db3ce4f027bc64cd41f9a7": version "0.0.1" - resolved "https://codeload.github.com/rhinestonewtf/module-bases/tar.gz/2db71722f939ed7d76315fc94c1a85bcb09ce59b" + resolved "https://codeload.github.com/rhinestonewtf/module-bases/tar.gz/d048ec28c8ea8b4155db3ce4f027bc64cd41f9a7" dependencies: "@ERC4337/account-abstraction" "github:kopy-kat/account-abstraction#develop" erc7579 "github:erc7579/erc7579-implementation" forge-std "github:foundry-rs/forge-std" +"@rhinestone/modulekit@0.4.17": + version "0.4.17" + resolved "https://registry.yarnpkg.com/@rhinestone/modulekit/-/modulekit-0.4.17.tgz#ffa7cbbd0c2287de55d8390195096e0ee8d5cb76" + integrity sha512-kaApkGizXNdz23/dFz5vZyGXzRSJq8GwySRfMDORriC2+cyrYhmCVgXOxUHVy/iDG2kWnrCe1tLvwFSpWZG3Sw== + dependencies: + "@ERC4337/account-abstraction" "github:kopy-kat/account-abstraction#develop" + "@ERC4337/account-abstraction-v0.6" "github:eth-infinitism/account-abstraction#v0.6.0" + "@prb/math" "^4.0.2" + "@rhinestone/erc4337-validation" "^0.0.4" + "@rhinestone/module-bases" "github:rhinestonewtf/module-bases#d048ec28c8ea8b4155db3ce4f027bc64cd41f9a7" + "@rhinestone/registry" "github:rhinestonewtf/registry#v1.0" + "@rhinestone/safe7579" "github:rhinestonewtf/safe7579#v1.0.0" + "@rhinestone/sentinellist" "github:rhinestonewtf/sentinellist" + "@safe-global/safe-contracts" "^1.4.1" + "@zerodev/kernel" "github:kopy-kat/kernel#patch" + ds-test "github:dapphub/ds-test" + erc7579 "github:erc7579/erc7579-implementation" + excessively-safe-call "github:nomad-xyz/ExcessivelySafeCall" + forge-std "github:foundry-rs/forge-std" + solady "github:vectorized/solady" + solarray "github:sablier-labs/solarray" + "@rhinestone/registry@github:rhinestonewtf/registry#v1.0": version "1.0.0" resolved "https://codeload.github.com/rhinestonewtf/registry/tar.gz/1371979a97293e0c6188afcd923784f6a718ae7d" @@ -847,9 +832,6 @@ resolved "https://codeload.github.com/rhinestonewtf/safe7579/tar.gz/33f110f08ed5fcab75c29d7cfb93f7f3e4da76a7" dependencies: "@ERC4337/account-abstraction" "github:kopy-kat/account-abstraction#develop" - "@ERC4337/account-abstraction-v0.6" "github:eth-infinitism/account-abstraction#v0.6.0" - "@rhinestone/checknsignatures" "github:rhinestonewtf/checknsignatures" - "@rhinestone/erc4337-validation" "0.0.1-alpha.2" "@rhinestone/module-bases" "github:rhinestonewtf/module-bases" "@rhinestone/sentinellist" "github:rhinestonewtf/sentinellist" "@safe-global/safe-contracts" "^1.4.1" @@ -861,7 +843,7 @@ "@rhinestone/sentinellist@github:rhinestonewtf/sentinellist": version "1.0.1" - resolved "https://codeload.github.com/rhinestonewtf/sentinellist/tar.gz/67e42f0eb3cf355ddba5a017892f9cc28d924875" + resolved "https://codeload.github.com/rhinestonewtf/sentinellist/tar.gz/e722c5cc68c570d535bc3c9f85b3ce90cdc38807" dependencies: forge-std "github:foundry-rs/forge-std" @@ -870,7 +852,7 @@ resolved "https://registry.yarnpkg.com/@safe-global/safe-contracts/-/safe-contracts-1.4.1.tgz#82605342f3289dc6b99818f599a3409ec2cb3fdc" integrity sha512-fP1jewywSwsIniM04NsqPyVRFKPMAuirC3ftA/TA4X3Zc5EnwQp/UCJUU2PL/37/z/jMo8UUaJ+pnFNWmMU7dQ== -"@scure/base@~1.1.0", "@scure/base@~1.1.2", "@scure/base@~1.1.6": +"@scure/base@~1.1.0", "@scure/base@~1.1.6": version "1.1.9" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1" integrity sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg== @@ -884,15 +866,6 @@ "@noble/secp256k1" "~1.7.0" "@scure/base" "~1.1.0" -"@scure/bip32@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.2.tgz#90e78c027d5e30f0b22c1f8d50ff12f3fb7559f8" - integrity sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA== - dependencies: - "@noble/curves" "~1.2.0" - "@noble/hashes" "~1.3.2" - "@scure/base" "~1.1.2" - "@scure/bip32@1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.4.0.tgz#4e1f1e196abedcef395b33b9674a042524e20d67" @@ -910,14 +883,6 @@ "@noble/hashes" "~1.2.0" "@scure/base" "~1.1.0" -"@scure/bip39@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" - integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== - dependencies: - "@noble/hashes" "~1.3.0" - "@scure/base" "~1.1.0" - "@scure/bip39@1.3.0": version "1.3.0" resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.3.0.tgz#0f258c16823ddd00739461ac31398b4e7d6a18c3" @@ -1095,9 +1060,11 @@ "@types/chai" "*" "@types/chai@*": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-5.0.0.tgz#7f981e71e69c9b2d422f58f78de1c59179782133" - integrity sha512-+DwhEHAaFPPdJ2ral3kNHFQXnTfscEEFsUxzD+d7nlcLrFK23JtNjH71RGasTcHb88b4vVi4mTyfpf8u2L8bdA== + version "5.0.1" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-5.0.1.tgz#2c3705555cf11f5f59c836a84c44afcfe4e5689d" + integrity sha512-5T8ajsg3M/FOncpLYW7sdOcD6yf4+722sze/tc4KQV0P8Z2rAr3SAuHCIkYmYpt8VbcQlnz8SxlOlPQYefe4cA== + dependencies: + "@types/deep-eql" "*" "@types/chai@^4.3.16": version "4.3.20" @@ -1118,6 +1085,11 @@ dependencies: "@types/ms" "*" +"@types/deep-eql@*": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/deep-eql/-/deep-eql-4.0.2.tgz#334311971d3a07121e7eb91b684a605e7eea9cbd" + integrity sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw== + "@types/form-data@0.0.33": version "0.0.33" resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-0.0.33.tgz#c9ac85b2a5fd18435b8c85d9ecb50e6d6c893ff8" @@ -1149,9 +1121,9 @@ integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== "@types/mocha@>=10.0.6": - version "10.0.8" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.8.tgz#a7eff5816e070c3b4d803f1d3cd780c4e42934a1" - integrity sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw== + version "10.0.9" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.9.tgz#101e9da88d2c02e5ac8952982c23b224524d662a" + integrity sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q== "@types/mocha@^9.0.0": version "9.1.1" @@ -1164,16 +1136,18 @@ integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== "@types/node@*", "@types/node@>=20.12.12": - version "22.7.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.4.tgz#e35d6f48dca3255ce44256ddc05dee1c23353fcc" - integrity sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg== + version "22.9.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.9.0.tgz#b7f16e5c3384788542c72dc3d561a7ceae2c0365" + integrity sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ== dependencies: - undici-types "~6.19.2" + undici-types "~6.19.8" -"@types/node@18.15.13": - version "18.15.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" - integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== +"@types/node@22.7.5": + version "22.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" + integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ== + dependencies: + undici-types "~6.19.2" "@types/node@^10.0.3": version "10.17.60" @@ -1181,9 +1155,9 @@ integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== "@types/node@^20.2.5": - version "20.16.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.10.tgz#0cc3fdd3daf114a4776f54ba19726a01c907ef71" - integrity sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA== + version "20.17.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.17.6.tgz#6e4073230c180d3579e8c60141f99efdf5df0081" + integrity sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ== dependencies: undici-types "~6.19.2" @@ -1205,9 +1179,9 @@ integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/qs@^6.2.31", "@types/qs@^6.9.7": - version "6.9.16" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.16.tgz#52bba125a07c0482d26747d5d4947a64daf8f794" - integrity sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A== + version "6.9.17" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.17.tgz#fc560f60946d0aeff2f914eb41679659d3310e1a" + integrity sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ== "@types/secp256k1@^4.0.1": version "4.0.6" @@ -1230,11 +1204,6 @@ abbrev@1.0.x: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q== -abitype@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.0.tgz#237176dace81d90d018bebf3a45cb42f2a2d9e97" - integrity sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ== - "account-abstraction-v0.6@github:eth-infinitism/account-abstraction#v0.6.0": version "0.6.0" resolved "https://codeload.github.com/eth-infinitism/account-abstraction/tar.gz/abff2aca61a8f0934e533d0d352978055fddbd96" @@ -1294,6 +1263,26 @@ abitype@1.0.0: table "^6.8.0" typescript "^4.3.5" +"account-abstraction@https://github.com/eth-infinitism/account-abstraction#v0.7.0": + version "0.7.0" + resolved "https://github.com/eth-infinitism/account-abstraction#7af70c8993a6f42973f520ae0752386a5032abe7" + dependencies: + "@nomiclabs/hardhat-etherscan" "^2.1.6" + "@openzeppelin/contracts" "^5.0.0" + "@thehubbleproject/bls" "^0.5.1" + "@typechain/hardhat" "^2.3.0" + "@types/debug" "^4.1.12" + "@types/mocha" "^9.0.0" + debug "^4.3.4" + 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.4" + source-map-support "^0.5.19" + table "^6.8.0" + typescript "^4.3.5" + acorn-walk@^8.1.1: version "8.3.4" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" @@ -1302,9 +1291,9 @@ acorn-walk@^8.1.1: acorn "^8.11.0" acorn@^8.11.0, acorn@^8.4.1: - version "8.12.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" - integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== adm-zip@^0.4.16: version "0.4.16" @@ -2104,10 +2093,10 @@ elliptic@6.5.4: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" -elliptic@^6.5.2, elliptic@^6.5.4: - version "6.5.7" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b" - integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q== +elliptic@^6.5.2, elliptic@^6.5.7: + version "6.6.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.0.tgz#5919ec723286c1edf28685aa89261d4761afa210" + integrity sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA== dependencies: bn.js "^4.11.9" brorand "^1.1.0" @@ -2142,7 +2131,7 @@ env-paths@^2.2.0: "erc7579@github:erc7579/erc7579-implementation": version "0.3.1" - resolved "https://codeload.github.com/erc7579/erc7579-implementation/tar.gz/b3f8bcb2df3aae3217213ffa8b7a87c1eb42ec56" + resolved "https://codeload.github.com/erc7579/erc7579-implementation/tar.gz/2081c0f9dc31b2e054a91956968180ea3fccf307" dependencies: "@rhinestone/sentinellist" "github:rhinestonewtf/sentinellist" account-abstraction "github:eth-infinitism/account-abstraction#develop" @@ -2150,6 +2139,13 @@ env-paths@^2.2.0: forge-std "github:foundry-rs/forge-std" solady "github:vectorized/solady" +"erc7739-validator-base@https://github.com/erc7579/erc7739Validator#v1.0.0": + version "0.1.1" + resolved "https://github.com/erc7579/erc7739Validator#d1e38493f58f28e62e12e41773086a90e8f60840" + dependencies: + "@erc7579/enumerablemap4337" "https://github.com/erc7579/enumerablemap" + "@rhinestone/modulekit" "0.4.17" + error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -2366,16 +2362,16 @@ ethers@^5.5.3, ethers@^5.7.0, ethers@^5.7.2, ethers@~5.7.0: "@ethersproject/wordlists" "5.7.0" ethers@^6.12.1: - version "6.13.2" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.2.tgz#4b67d4b49e69b59893931a032560999e5e4419fe" - integrity sha512-9VkriTTed+/27BGuY1s0hf441kqwHJ1wtN2edksEtiRvXx+soxRX3iSXTfFqq2+YwrOqbDoTHjIhQnjJRlzKmg== + version "6.13.4" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.4.tgz#bd3e1c3dc1e7dc8ce10f9ffb4ee40967a651b53c" + integrity sha512-21YtnZVg4/zKkCQPjrDj38B1r4nQvTZLopUGMLQ1ePU2zV/joCfDC3t3iKQjWRzjjjbzR+mdAIoikeBRNkdllA== dependencies: "@adraffy/ens-normalize" "1.10.1" "@noble/curves" "1.2.0" "@noble/hashes" "1.3.2" - "@types/node" "18.15.13" + "@types/node" "22.7.5" aes-js "4.0.0-beta.5" - tslib "2.4.0" + tslib "2.7.0" ws "8.17.1" ethjs-unit@0.1.6: @@ -2438,9 +2434,9 @@ fast-levenshtein@~2.0.6: integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fast-uri@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.2.tgz#d78b298cf70fd3b752fd951175a3da6a7b48f024" - integrity sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row== + version "3.0.3" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.3.tgz#892a1c91802d5d7860de728f18608a0573142241" + integrity sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw== fast-url-parser@^1.1.3: version "1.1.3" @@ -2503,8 +2499,12 @@ follow-redirects@^1.12.1, follow-redirects@^1.14.0, follow-redirects@^1.15.6: integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== "forge-std@github:foundry-rs/forge-std": + version "1.9.4" + resolved "https://codeload.github.com/foundry-rs/forge-std/tar.gz/0e7097750918380d84dd3cfdef595bee74dabb70" + +"forge-std@github:foundry-rs/forge-std#8a225d81aa8e2e013580564588c79abb65eacc9e": version "1.9.3" - resolved "https://codeload.github.com/foundry-rs/forge-std/tar.gz/8f24d6b04c92975e0795b5868aa0d783251cdeaa" + resolved "https://codeload.github.com/foundry-rs/forge-std/tar.gz/8a225d81aa8e2e013580564588c79abb65eacc9e" "forge-std@github:foundry-rs/forge-std#v1.7.6": version "1.7.6" @@ -2520,18 +2520,19 @@ form-data-encoder@^2.1.2: integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== form-data@^2.2.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" - integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + version "2.5.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.2.tgz#dc653743d1de2fcc340ceea38079daf6e9069fd2" + integrity sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q== dependencies: asynckit "^0.4.0" combined-stream "^1.0.6" mime-types "^2.1.12" + safe-buffer "^5.2.1" form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + version "4.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48" + integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" @@ -2871,13 +2872,13 @@ hardhat-storage-layout@^0.1.7: console-table-printer "^2.9.0" hardhat@^2.22.4: - version "2.22.12" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.12.tgz#a6d0be011fc009c50c454da367ad28c29f58d446" - integrity sha512-yok65M+LsOeTBHQsjg//QreGCyrsaNmeLVzhTFqlOvZ4ZE5y69N0wRxH1b2BC9dGK8S8OPUJMNiL9X0RAvbm8w== + version "2.22.15" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.15.tgz#319b4948f875968fde3f0d09a7edfe74e16b1365" + integrity sha512-BpTGa9PE/sKAaHi4s/S1e9WGv63DR1m7Lzfd60C8gSEchDPfAJssVRSq0MZ2v2k76ig9m0kHAwVLf5teYwu/Mw== dependencies: "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/edr" "^0.6.1" + "@nomicfoundation/edr" "^0.6.4" "@nomicfoundation/ethereumjs-common" "4.0.4" "@nomicfoundation/ethereumjs-tx" "5.0.4" "@nomicfoundation/ethereumjs-util" "9.0.4" @@ -3201,11 +3202,6 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isows@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.3.tgz#93c1cf0575daf56e7120bab5c8c448b0809d0d74" - integrity sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg== - js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -3252,9 +3248,9 @@ json-schema-traverse@^1.0.0: integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== json-stream-stringify@^3.1.4: - version "3.1.5" - resolved "https://registry.yarnpkg.com/json-stream-stringify/-/json-stream-stringify-3.1.5.tgz#7184383b397a83ac5da33b62371217522e6ac2f6" - integrity sha512-wurRuTiw27mck9MWaUIGAunfwqhPDxnXQVN/+Rzi+IEQUUALU10AZs1nWkSdtjH7PAVuAUcqQjH11S/JHOWeaA== + version "3.1.6" + resolved "https://registry.yarnpkg.com/json-stream-stringify/-/json-stream-stringify-3.1.6.tgz#ebe32193876fb99d4ec9f612389a8d8e2b5d54d4" + integrity sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog== jsonfile@^4.0.0: version "4.0.0" @@ -3508,9 +3504,9 @@ mnemonist@^0.38.0: obliterator "^2.0.0" mocha@^10.0.0, mocha@^10.2.0: - version "10.7.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.7.3.tgz#ae32003cabbd52b59aece17846056a68eb4b0752" - integrity sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A== + version "10.8.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.8.2.tgz#8d8342d016ed411b12a429eb731b825f961afb96" + integrity sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg== dependencies: ansi-colors "^4.1.3" browser-stdout "^1.3.1" @@ -3533,27 +3529,6 @@ mocha@^10.0.0, mocha@^10.2.0: yargs-parser "^20.2.9" yargs-unparser "^2.0.0" -"modulekit@github:rhinestonewtf/modulekit": - version "0.4.13" - resolved "https://codeload.github.com/rhinestonewtf/modulekit/tar.gz/ff6bd8a8918a02d9dd76658323e6b50c6be953a5" - dependencies: - "@ERC4337/account-abstraction" "github:kopy-kat/account-abstraction#develop" - "@ERC4337/account-abstraction-v0.6" "github:eth-infinitism/account-abstraction#v0.6.0" - "@prb/math" "^4.0.2" - "@rhinestone/erc4337-validation" "^0.0.1-alpha.5" - "@rhinestone/module-bases" "github:rhinestonewtf/module-bases" - "@rhinestone/registry" "github:rhinestonewtf/registry#v1.0" - "@rhinestone/safe7579" "github:rhinestonewtf/safe7579#v1.0.0" - "@rhinestone/sentinellist" "github:rhinestonewtf/sentinellist" - "@safe-global/safe-contracts" "^1.4.1" - "@zerodev/kernel" "github:kopy-kat/kernel#patch" - ds-test "github:dapphub/ds-test" - erc7579 "github:erc7579/erc7579-implementation" - excessively-safe-call "github:nomad-xyz/ExcessivelySafeCall" - forge-std "github:foundry-rs/forge-std" - solady "github:vectorized/solady" - solarray "github:sablier-labs/solarray" - ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" @@ -3578,6 +3553,11 @@ node-addon-api@^2.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== +node-addon-api@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" + integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== + node-emoji@^1.10.0: version "1.11.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" @@ -3795,9 +3775,9 @@ pbkdf2@^3.0.17: sha.js "^2.4.8" picocolors@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" - integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" @@ -3943,9 +3923,9 @@ readable-stream@^3.6.0: util-deprecate "^1.0.1" readdirp@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.0.1.tgz#b2fe35f8dca63183cd3b86883ecc8f720ea96ae6" - integrity sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw== + version "4.0.2" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.0.2.tgz#388fccb8b75665da3abffe2d8f8ed59fe74c230a" + integrity sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA== readdirp@~3.6.0: version "3.6.0" @@ -4081,7 +4061,7 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -4122,12 +4102,12 @@ scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== secp256k1@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" - integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== + version "4.0.4" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.4.tgz#58f0bfe1830fe777d9ca1ffc7574962a8189f8ab" + integrity sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw== dependencies: - elliptic "^6.5.4" - node-addon-api "^2.0.0" + elliptic "^6.5.7" + node-addon-api "^5.0.0" node-gyp-build "^4.2.0" semver@^5.5.0: @@ -4145,9 +4125,9 @@ semver@^7.3.4, semver@^7.3.7, semver@^7.5.2, semver@^7.5.4: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== -"sentinellist@github:zeroknots/sentinellist": +"sentinellist@github:rhinestonewtf/sentinellist#v1.0.0": version "1.0.1" - resolved "https://codeload.github.com/zeroknots/sentinellist/tar.gz/67e42f0eb3cf355ddba5a017892f9cc28d924875" + resolved "https://codeload.github.com/rhinestonewtf/sentinellist/tar.gz/6dff696f39fb55bfdde9581544d788932f145e47" dependencies: forge-std "github:foundry-rs/forge-std" @@ -4235,13 +4215,17 @@ slice-ansi@^4.0.0: is-fullwidth-code-point "^3.0.0" "solady@github:vectorized/solady": - version "0.0.246" - resolved "https://codeload.github.com/vectorized/solady/tar.gz/d4173342599d84db83f6b6e6a70c3fd5428eb284" + version "0.0.265" + resolved "https://codeload.github.com/vectorized/solady/tar.gz/1c9927e9eb0c280c44c81c943976fe8995b382ed" "solady@github:vectorized/solady#9deb9ed36a27261a8745db5b7cd7f4cdc3b1cd4e": version "0.0.168" resolved "https://codeload.github.com/vectorized/solady/tar.gz/9deb9ed36a27261a8745db5b7cd7f4cdc3b1cd4e" +"solady@github:vectorized/solady#v0.0.271": + version "0.0.271" + resolved "https://codeload.github.com/vectorized/solady/tar.gz/b38e2c025f8cd1ecbfc1b92678fe05ac950a4bb1" + "solarray@github:sablier-labs/solarray": version "1.0.0" resolved "https://codeload.github.com/sablier-labs/solarray/tar.gz/6bf10cb34cdace52a3ba5fe437e78cc82df92684" @@ -4267,32 +4251,6 @@ solhint-plugin-prettier@^0.1.0: "@prettier/sync" "^0.3.0" prettier-linter-helpers "^1.0.0" -solhint@^4.1.1: - version "4.5.4" - resolved "https://registry.yarnpkg.com/solhint/-/solhint-4.5.4.tgz#171cf33f46c36b8499efe60c0e425f6883a54e50" - integrity sha512-Cu1XiJXub2q1eCr9kkJ9VPv1sGcmj3V7Zb76B0CoezDOB9bu3DxKIFFH7ggCl9fWpEPD6xBmRLfZrYijkVmujQ== - dependencies: - "@solidity-parser/parser" "^0.18.0" - ajv "^6.12.6" - antlr4 "^4.13.1-patch-1" - ast-parents "^0.0.1" - chalk "^4.1.2" - commander "^10.0.0" - cosmiconfig "^8.0.0" - fast-diff "^1.2.0" - glob "^8.0.3" - ignore "^5.2.4" - js-yaml "^4.1.0" - latest-version "^7.0.0" - lodash "^4.17.21" - pluralize "^8.0.0" - semver "^7.5.2" - strip-ansi "^6.0.1" - table "^6.8.1" - text-table "^0.2.0" - optionalDependencies: - prettier "^2.8.3" - solhint@^5.0.1: version "5.0.3" resolved "https://registry.yarnpkg.com/solhint/-/solhint-5.0.3.tgz#b57f6d2534fe09a60f9db1b92e834363edd1cbde" @@ -4621,10 +4579,10 @@ ts-node@>=10.9.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tslib@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== +tslib@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== tslib@^1.9.3: version "1.14.1" @@ -4695,9 +4653,9 @@ typedarray@^0.0.6: integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== typescript@>=5.4.5: - version "5.6.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" - integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== + version "5.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" + integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== typescript@^4.3.5: version "4.9.5" @@ -4719,7 +4677,7 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== -undici-types@~6.19.2: +undici-types@~6.19.2, undici-types@~6.19.8: version "6.19.8" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== @@ -4780,20 +4738,6 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -viem@2.7.13: - version "2.7.13" - resolved "https://registry.yarnpkg.com/viem/-/viem-2.7.13.tgz#bf3f8e973f532f9f9c86c97b645ac8add740e1bd" - integrity sha512-NGWLEocRp2UTqGidzI9bnL9u6WHlG2ik7IwqXNe6/QC2dL6jE3Z1mUnUUVcSx71h81nx74EflD9ahtleK3RQdA== - dependencies: - "@adraffy/ens-normalize" "1.10.0" - "@noble/curves" "1.2.0" - "@noble/hashes" "1.3.2" - "@scure/bip32" "1.3.2" - "@scure/bip39" "1.2.1" - abitype "1.0.0" - isows "1.0.3" - ws "8.13.0" - web3-utils@^1.3.6: version "1.10.4" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.4.tgz#0daee7d6841641655d8b3726baf33b08eda1cbec" @@ -4877,11 +4821,6 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== -ws@8.13.0: - version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== - ws@8.17.1: version "8.17.1" resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" @@ -4936,9 +4875,9 @@ yocto-queue@^0.1.0: integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== zksync-ethers@^5.0.0: - version "5.9.2" - resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.9.2.tgz#1c5f34cb25ac0b040fd1a6118f2ba1c2c3bda090" - integrity sha512-Y2Mx6ovvxO6UdC2dePLguVzvNToOY8iLWeq5ne+jgGSJxAi/f4He/NF6FNsf6x1aWX0o8dy4Df8RcOQXAkj5qw== + version "5.10.0" + resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.10.0.tgz#3caf25478539a3fd6e170c13555cec6a1dae32e2" + integrity sha512-OAjTGAHF9wbdkRGkj7XZuF/a1Sk/FVbwH4pmLjAKlR7mJ7sQtQhBhrPU2dCc67xLaNvEESPfwil19ES5wooYFg== dependencies: ethers "~5.7.0"