diff --git a/.changeset/kind-poems-pull.md b/.changeset/kind-poems-pull.md new file mode 100644 index 000000000..06518aac7 --- /dev/null +++ b/.changeset/kind-poems-pull.md @@ -0,0 +1,5 @@ +--- +'@openzeppelin/wizard-common': patch +--- + +Update Solidity Account prompt diff --git a/.changeset/odd-ants-hunt.md b/.changeset/odd-ants-hunt.md new file mode 100644 index 000000000..ee20e0e4c --- /dev/null +++ b/.changeset/odd-ants-hunt.md @@ -0,0 +1,6 @@ +--- +'@openzeppelin/wizard': minor +'@openzeppelin/contracts-mcp': minor +--- + +Add constructors for `SignerECDSA`, `SignerP256`, `SignerRSA`, `SignerERC7702`, `SignerERC7913`, `MultiSignerERC7913` and `MultiSignerERC7913Weighted` diff --git a/.changeset/sad-nails-smash.md b/.changeset/sad-nails-smash.md new file mode 100644 index 000000000..c0ff12783 --- /dev/null +++ b/.changeset/sad-nails-smash.md @@ -0,0 +1,6 @@ +--- +'@openzeppelin/wizard': minor +'@openzeppelin/contracts-mcp': minor +--- + +Enable upgradeability for `AccountERC7579`, `AccountERC7579Hooked`, `SignerECDSA`, `SignerP256`, `SignerRSA`, `SignerERC7702`, `SignerERC7913` and `MultiSignerERC7913` diff --git a/.changeset/sour-hats-grow.md b/.changeset/sour-hats-grow.md new file mode 100644 index 000000000..3d08edbde --- /dev/null +++ b/.changeset/sour-hats-grow.md @@ -0,0 +1,6 @@ +--- +'@openzeppelin/wizard': minor +'@openzeppelin/contracts-mcp': minor +--- + +**Breaking change**: Use `Account`, `AccountERC7579`, `AccountERC7579Hooked`, `ERC7812`, `ERC7739Utils`, `ERC7913Utils`, `AbstractSigner`, `SignerECDSA`, `SignerP256`, `SignerRSA`, `SignerERC7702`, `SignerERC7913`, `MultiSignerERC7913`, and `MultiSignerERC7913Weighted` from OpenZeppelin Contracts 5.4.0 instead of Community Contracts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8aa9a7e5b..cd7259d86 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -111,7 +111,7 @@ jobs: working-directory: packages/ui - name: Run tests if: matrix.variant == 'default' - run: yarn test '**/*.test.ts' '!**/*.compile.test.ts' + run: yarn test '**/*.test.ts' '**/test.ts' '!**/*.compile.test.ts' working-directory: packages/core/${{matrix.package}} - name: Get list of changed files diff --git a/packages/common/src/ai/descriptions/solidity.ts b/packages/common/src/ai/descriptions/solidity.ts index e5df01346..cd87ad1fd 100644 --- a/packages/common/src/ai/descriptions/solidity.ts +++ b/packages/common/src/ai/descriptions/solidity.ts @@ -8,8 +8,7 @@ export const solidityPrompts = { Stablecoin: 'Make a stablecoin token that uses the ERC-20 standard. Experimental, some features are not audited and are subject to change.', RWA: 'Make a real-world asset token that uses the ERC-20 standard. Experimental, some features are not audited and are subject to change.', - Account: - 'Make an account contract that follows the ERC-4337 standard. Experimental, some features are not audited and are subject to change.', + Account: 'Make an account contract that follows the ERC-4337 standard.', Governor: 'Make a contract to implement governance, such as for a DAO.', Custom: 'Make a custom smart contract.', }; diff --git a/packages/core/solidity/README.md b/packages/core/solidity/README.md index bb4177bbf..68f6bfe9a 100644 --- a/packages/core/solidity/README.md +++ b/packages/core/solidity/README.md @@ -22,7 +22,7 @@ The following contract types are supported: - `governor` - `custom` -Note that `stablecoin`, `realWorldAsset`, and `account` are experimental and may be subject to change. +Note that `stablecoin`, and `realWorldAsset` are experimental and may be subject to change. Each contract type has functions/constants as defined below. diff --git a/packages/core/solidity/package.json b/packages/core/solidity/package.json index c2a92e1da..8364f89ce 100644 --- a/packages/core/solidity/package.json +++ b/packages/core/solidity/package.json @@ -22,7 +22,7 @@ "update-env": "rm ./src/environments/hardhat/package-lock.json && npm install --package-lock-only --prefix ./src/environments/hardhat && rm ./src/environments/hardhat/upgradeable/package-lock.json && npm install --package-lock-only --prefix ./src/environments/hardhat/upgradeable" }, "devDependencies": { - "@openzeppelin/community-contracts": "git+https://github.com/OpenZeppelin/openzeppelin-community-contracts.git#de17c8e", + "@openzeppelin/community-contracts": "git+https://github.com/OpenZeppelin/openzeppelin-community-contracts.git#2d607bd", "@openzeppelin/contracts": "^5.4.0", "@openzeppelin/contracts-upgradeable": "^5.4.0", "@types/node": "^20.0.0", diff --git a/packages/core/solidity/src/account.test.ts b/packages/core/solidity/src/account.test.ts index fbf809721..97611cee9 100644 --- a/packages/core/solidity/src/account.test.ts +++ b/packages/core/solidity/src/account.test.ts @@ -50,72 +50,98 @@ test('account API assert defaults', async t => { t.is(account.print(account.defaults), account.print()); }); -for (const signer of [false, 'ERC7702', 'ECDSA', 'P256', 'RSA', 'Multisig', 'MultisigWeighted'] as const) { - let title = 'Account'; - if (signer) { - title += ` with Signer${signer}`; +function format(upgradeable: false | 'uups' | 'transparent') { + switch (upgradeable) { + case false: + return 'non-upgradeable'; + case 'uups': + return 'upgradeable uups'; + case 'transparent': + return 'upgradeable transparent'; } +} - testAccount(`${title} named`, { - name: `Custom${title}`, - signer, - }); - - testAccount(`${title} with ERC1271`, { - name: `Custom${title}ERC1271`, - signatureValidation: 'ERC1271', - signer, - }); - - testAccount(`${title} with ERC7739`, { - name: `Custom${title}ERC7739`, - signatureValidation: 'ERC7739', - signer, - }); - - testAccount(`${title} with ERC721Holder`, { - name: `Custom${title}ERC721Holder`, - ERC721Holder: true, - signer, - }); - - testAccount(`${title} with ERC1155Holder`, { - name: `Custom${title}ERC1155Holder`, - ERC1155Holder: true, - signer, - }); - - testAccount(`${title} with ERC721Holder and ERC1155Holder`, { - name: `Custom${title}ERC721HolderERC1155Holder`, - ERC721Holder: true, - ERC1155Holder: true, - signer, - }); - - testAccount(`${title} with ERC7821 Execution`, { - signer, - batchedExecution: true, - }); - - testAccount(`${title} with ERC7579`, { - signer, - ERC7579Modules: 'AccountERC7579', - }); - - testAccount(`${title} with ERC7579 with ERC1271`, { - signer, - ERC7579Modules: 'AccountERC7579', - signatureValidation: 'ERC1271', - }); - - testAccount(`${title} with ERC7579 with ERC7739`, { - signer, - ERC7579Modules: 'AccountERC7579', - signatureValidation: 'ERC7739', - }); - - testAccount(`${title} with ERC7579 hooks`, { - signer, - ERC7579Modules: 'AccountERC7579Hooked', - }); +for (const signer of [false, 'ERC7702', 'ECDSA', 'P256', 'RSA', 'Multisig', 'MultisigWeighted'] as const) { + for (const upgradeable of [false, 'uups', 'transparent'] as const) { + if (signer === 'ERC7702' && !!upgradeable) continue; + + let title = 'Account'; + if (signer) { + title += ` with Signer${signer}`; + } + + testAccount(`${title} named ${format(upgradeable)}`, { + name: `Custom${title}`, + signer, + upgradeable, + }); + + testAccount(`${title} with ERC1271 ${format(upgradeable)}`, { + name: `Custom${title}ERC1271`, + signatureValidation: 'ERC1271', + signer, + upgradeable, + }); + + testAccount(`${title} with ERC7739 ${format(upgradeable)}`, { + name: `Custom${title}ERC7739`, + signatureValidation: 'ERC7739', + signer, + upgradeable, + }); + + testAccount(`${title} with ERC721Holder ${format(upgradeable)}`, { + name: `Custom${title}ERC721Holder`, + ERC721Holder: true, + signer, + upgradeable, + }); + + testAccount(`${title} with ERC1155Holder ${format(upgradeable)}`, { + name: `Custom${title}ERC1155Holder`, + ERC1155Holder: true, + signer, + upgradeable, + }); + + testAccount(`${title} with ERC721Holder and ERC1155Holder ${format(upgradeable)}`, { + name: `Custom${title}ERC721HolderERC1155Holder`, + ERC721Holder: true, + ERC1155Holder: true, + signer, + upgradeable, + }); + + testAccount(`${title} with ERC7821 Execution ${format(upgradeable)}`, { + signer, + upgradeable, + batchedExecution: true, + }); + + testAccount(`${title} with ERC7579 ${format(upgradeable)}`, { + signer, + upgradeable, + ERC7579Modules: 'AccountERC7579', + }); + + testAccount(`${title} with ERC7579 with ERC1271 ${format(upgradeable)}`, { + signer, + upgradeable, + ERC7579Modules: 'AccountERC7579', + signatureValidation: 'ERC1271', + }); + + testAccount(`${title} with ERC7579 with ERC7739 ${format(upgradeable)}`, { + signer, + upgradeable, + ERC7579Modules: 'AccountERC7579', + signatureValidation: 'ERC7739', + }); + + testAccount(`${title} with ERC7579 hooks ${format(upgradeable)}`, { + signer, + upgradeable, + ERC7579Modules: 'AccountERC7579Hooked', + }); + } } diff --git a/packages/core/solidity/src/account.test.ts.md b/packages/core/solidity/src/account.test.ts.md index b3bec39c8..59f7f04d9 100644 --- a/packages/core/solidity/src/account.test.ts.md +++ b/packages/core/solidity/src/account.test.ts.md @@ -4,17 +4,17 @@ The actual snapshot is saved in `account.test.ts.snap`. Generated by [AVA](https://avajs.dev). -## Account named +## Account named non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ ␊ contract CustomAccount is Account, EIP712, ERC7739 {␊ constructor() EIP712("CustomAccount", "1") {}␊ @@ -31,15 +31,15 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with ERC1271 +## Account with ERC1271 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ ␊ contract CustomAccountERC1271 is Account, IERC1271 {␊ @@ -64,17 +64,17 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with ERC7739 +## Account with ERC7739 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ ␊ contract CustomAccountERC7739 is Account, EIP712, ERC7739 {␊ constructor() EIP712("CustomAccountERC7739", "1") {}␊ @@ -91,18 +91,18 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with ERC721Holder +## Account with ERC721Holder non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ ␊ contract CustomAccountERC721Holder is Account, EIP712, ERC7739, ERC721Holder {␊ constructor() EIP712("CustomAccountERC721Holder", "1") {}␊ @@ -119,18 +119,18 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with ERC1155Holder +## Account with ERC1155Holder non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ ␊ contract CustomAccountERC1155Holder is Account, EIP712, ERC7739, ERC1155Holder {␊ constructor() EIP712("CustomAccountERC1155Holder", "1") {}␊ @@ -147,19 +147,19 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with ERC721Holder and ERC1155Holder +## Account with ERC721Holder and ERC1155Holder non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ ␊ contract CustomAccountERC721HolderERC1155Holder is Account, EIP712, ERC7739, ERC721Holder, ERC1155Holder {␊ constructor() EIP712("CustomAccountERC721HolderERC1155Holder", "1") {}␊ @@ -176,18 +176,18 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with ERC7821 Execution +## Account with ERC7821 Execution non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {ERC7821} from "@openzeppelin/community-contracts/account/extensions/ERC7821.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ ␊ contract MyAccount is Account, EIP712, ERC7739, ERC7821 {␊ constructor() EIP712("MyAccount", "1") {}␊ @@ -213,22 +213,27 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with ERC7579 +## Account with ERC7579 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ ␊ contract MyAccount is Account, EIP712, ERC7739, AccountERC7579 {␊ - constructor() EIP712("MyAccount", "1") {}␊ + constructor(uint256 moduleTypeId, address module, bytes calldata initData)␊ + EIP712("MyAccount", "1")␊ + {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ + }␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ @@ -254,20 +259,25 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with ERC7579 with ERC1271 +## Account with ERC7579 with ERC1271 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ ␊ contract MyAccount is Account, IERC1271, AccountERC7579 {␊ + constructor(uint256 moduleTypeId, address module, bytes calldata initData) {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ + }␊ + ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ @@ -289,22 +299,27 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with ERC7579 with ERC7739 +## Account with ERC7579 with ERC7739 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ ␊ contract MyAccount is Account, EIP712, ERC7739, AccountERC7579 {␊ - constructor() EIP712("MyAccount", "1") {}␊ + constructor(uint256 moduleTypeId, address module, bytes calldata initData)␊ + EIP712("MyAccount", "1")␊ + {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ + }␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ @@ -330,23 +345,28 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with ERC7579 hooks +## Account with ERC7579 hooks non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ - import {AccountERC7579Hooked} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579Hooked.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {AccountERC7579Hooked} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579Hooked.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ ␊ contract MyAccount is Account, EIP712, ERC7739, AccountERC7579Hooked {␊ - constructor() EIP712("MyAccount", "1") {}␊ + constructor(uint256 moduleTypeId, address module, bytes calldata initData)␊ + EIP712("MyAccount", "1")␊ + {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ + }␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ @@ -372,37 +392,63 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerERC7702 named +## Account named upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {SignerERC7702} from "@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - contract CustomAccountWithSignerERC7702 is Account, EIP712, ERC7739, SignerERC7702 {␊ - constructor() EIP712("CustomAccount with SignerERC7702", "1") {}␊ + contract CustomAccount is Initializable, Account, EIP712, ERC7739, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerERC7702 with ERC1271 +## Account with ERC1271 upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ - import {SignerERC7702} from "@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountERC1271 is Initializable, Account, IERC1271, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ ␊ - contract CustomAccountWithSignerERC7702ERC1271 is Account, IERC1271, SignerERC7702 {␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ @@ -411,103 +457,201 @@ Generated by [AVA](https://avajs.dev). {␊ return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ }␊ + ␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerERC7702 with ERC7739 +## Account with ERC7739 upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {SignerERC7702} from "@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - contract CustomAccountWithSignerERC7702ERC7739 is Account, EIP712, ERC7739, SignerERC7702 {␊ - constructor() EIP712("CustomAccount with SignerERC7702ERC7739", "1") {}␊ + contract CustomAccountERC7739 is Initializable, Account, EIP712, ERC7739, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccountERC7739", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerERC7702 with ERC721Holder +## Account with ERC721Holder upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {SignerERC7702} from "@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - contract CustomAccountWithSignerERC7702ERC721Holder is Account, EIP712, ERC7739, SignerERC7702, ERC721Holder {␊ - constructor() EIP712("CustomAccount with SignerERC7702ERC721Holder", "1") {}␊ + contract CustomAccountERC721Holder is Initializable, Account, EIP712, ERC7739, ERC721Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccountERC721Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerERC7702 with ERC1155Holder +## Account with ERC1155Holder upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {SignerERC7702} from "@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - contract CustomAccountWithSignerERC7702ERC1155Holder is Account, EIP712, ERC7739, SignerERC7702, ERC1155Holder {␊ - constructor() EIP712("CustomAccount with SignerERC7702ERC1155Holder", "1") {}␊ + contract CustomAccountERC1155Holder is Initializable, Account, EIP712, ERC7739, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccountERC1155Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerERC7702 with ERC721Holder and ERC1155Holder +## Account with ERC721Holder and ERC1155Holder upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {SignerERC7702} from "@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - contract CustomAccountWithSignerERC7702ERC721HolderERC1155Holder is Account, EIP712, ERC7739, SignerERC7702, ERC721Holder, ERC1155Holder {␊ - constructor()␊ - EIP712("CustomAccount with SignerERC7702ERC721HolderERC1155Holder", "1")␊ + contract CustomAccountERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, ERC721Holder, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccountERC721HolderERC1155Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ {}␊ }␊ ` -## Account with SignerERC7702 with ERC7821 Execution +## Account with ERC7821 Execution upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {ERC7821} from "@openzeppelin/community-contracts/account/extensions/ERC7821.sol";␊ - import {SignerERC7702} from "@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - contract MyAccount is Account, EIP712, ERC7739, SignerERC7702, ERC7821 {␊ - constructor() EIP712("MyAccount", "1") {}␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, ERC7821, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ ␊ function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ internal␊ @@ -517,86 +661,125 @@ Generated by [AVA](https://avajs.dev). {␊ return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ }␊ + ␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerERC7702 with ERC7579 +## Account with ERC7579 upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerERC7702} from "@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - contract MyAccount is Account, EIP712, ERC7739, AccountERC7579, SignerERC7702 {␊ - constructor() EIP712("MyAccount", "1") {}␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(uint256 moduleTypeId, address module, bytes calldata initData)␊ + public␊ + initializer␊ + {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ + }␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ - ␊ - // IMPORTANT: Make sure SignerERC7702 is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerERC7702)␊ - // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ - function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ - internal␊ - view␊ - override(SignerERC7702, AbstractSigner, AccountERC7579)␊ - returns (bool)␊ - {␊ - return super._rawSignatureValidation(hash, signature);␊ - }␊ }␊ ` -## Account with SignerERC7702 with ERC7579 with ERC1271 +## Account with ERC7579 with ERC1271 upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerERC7702} from "@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(uint256 moduleTypeId, address module, bytes calldata initData)␊ + public␊ + initializer␊ + {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ ␊ - contract MyAccount is Account, IERC1271, AccountERC7579, SignerERC7702 {␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ @@ -605,181 +788,180 @@ Generated by [AVA](https://avajs.dev). function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(IERC1271, AccountERC7579)␊ + override(IERC1271, AccountERC7579Upgradeable)␊ returns (bytes4)␊ {␊ return super.isValidSignature(hash, signature);␊ }␊ - ␊ - // IMPORTANT: Make sure SignerERC7702 is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerERC7702)␊ - // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ - function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ - internal␊ - view␊ - override(SignerERC7702, AbstractSigner, AccountERC7579)␊ - returns (bool)␊ - {␊ - return super._rawSignatureValidation(hash, signature);␊ - }␊ }␊ ` -## Account with SignerERC7702 with ERC7579 with ERC7739 +## Account with ERC7579 with ERC7739 upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerERC7702} from "@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - contract MyAccount is Account, EIP712, ERC7739, AccountERC7579, SignerERC7702 {␊ - constructor() EIP712("MyAccount", "1") {}␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(uint256 moduleTypeId, address module, bytes calldata initData)␊ + public␊ + initializer␊ + {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ + }␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ - ␊ - // IMPORTANT: Make sure SignerERC7702 is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerERC7702)␊ - // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ - function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ - internal␊ - view␊ - override(SignerERC7702, AbstractSigner, AccountERC7579)␊ - returns (bool)␊ - {␊ - return super._rawSignatureValidation(hash, signature);␊ - }␊ }␊ ` -## Account with SignerERC7702 with ERC7579 hooks +## Account with ERC7579 hooks upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ - import {AccountERC7579Hooked} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579Hooked.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerERC7702} from "@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - contract MyAccount is Account, EIP712, ERC7739, AccountERC7579Hooked, SignerERC7702 {␊ - constructor() EIP712("MyAccount", "1") {}␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(uint256 moduleTypeId, address module, bytes calldata initData)␊ + public␊ + initializer␊ + {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ + }␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ - ␊ - // IMPORTANT: Make sure SignerERC7702 is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerERC7702)␊ - // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ - function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ - internal␊ - view␊ - override(SignerERC7702, AbstractSigner, AccountERC7579)␊ - returns (bool)␊ - {␊ - return super._rawSignatureValidation(hash, signature);␊ - }␊ }␊ ` -## Account with SignerECDSA named +## Account named upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerECDSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerECDSA is Initializable, Account, EIP712, ERC7739, SignerECDSA {␊ - constructor() EIP712("CustomAccount with SignerECDSA", "1") {␊ + contract CustomAccount is Initializable, Account, EIP712, ERC7739 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount", "1") {␊ _disableInitializers();␊ }␊ ␊ - function initializeECDSA(address signer) public initializer {␊ - _setSigner(signer);␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ }␊ }␊ ` -## Account with SignerECDSA with ERC1271 +## Account with ERC1271 upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerECDSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerECDSAERC1271 is Initializable, Account, IERC1271, SignerECDSA {␊ + contract CustomAccountERC1271 is Initializable, Account, IERC1271 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() {␊ _disableInitializers();␊ }␊ @@ -793,146 +975,165 @@ Generated by [AVA](https://avajs.dev). return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ }␊ ␊ - function initializeECDSA(address signer) public initializer {␊ - _setSigner(signer);␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ }␊ }␊ ` -## Account with SignerECDSA with ERC7739 +## Account with ERC7739 upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerECDSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerECDSAERC7739 is Initializable, Account, EIP712, ERC7739, SignerECDSA {␊ - constructor() EIP712("CustomAccount with SignerECDSAERC7739", "1") {␊ + contract CustomAccountERC7739 is Initializable, Account, EIP712, ERC7739 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccountERC7739", "1") {␊ _disableInitializers();␊ }␊ ␊ - function initializeECDSA(address signer) public initializer {␊ - _setSigner(signer);␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ }␊ }␊ ` -## Account with SignerECDSA with ERC721Holder +## Account with ERC721Holder upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerECDSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerECDSAERC721Holder is Initializable, Account, EIP712, ERC7739, SignerECDSA, ERC721Holder {␊ - constructor() EIP712("CustomAccount with SignerECDSAERC721Holder", "1") {␊ + contract CustomAccountERC721Holder is Initializable, Account, EIP712, ERC7739, ERC721Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccountERC721Holder", "1") {␊ _disableInitializers();␊ }␊ ␊ - function initializeECDSA(address signer) public initializer {␊ - _setSigner(signer);␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ }␊ }␊ ` -## Account with SignerECDSA with ERC1155Holder +## Account with ERC1155Holder upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerECDSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerECDSAERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerECDSA, ERC1155Holder {␊ - constructor() EIP712("CustomAccount with SignerECDSAERC1155Holder", "1") {␊ + contract CustomAccountERC1155Holder is Initializable, Account, EIP712, ERC7739, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccountERC1155Holder", "1") {␊ _disableInitializers();␊ }␊ ␊ - function initializeECDSA(address signer) public initializer {␊ - _setSigner(signer);␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ }␊ }␊ ` -## Account with SignerECDSA with ERC721Holder and ERC1155Holder +## Account with ERC721Holder and ERC1155Holder upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerECDSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerECDSAERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerECDSA, ERC721Holder, ERC1155Holder {␊ - constructor()␊ - EIP712("CustomAccount with SignerECDSAERC721HolderERC1155Holder", "1")␊ - {␊ + contract CustomAccountERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccountERC721HolderERC1155Holder", "1") {␊ _disableInitializers();␊ }␊ ␊ - function initializeECDSA(address signer) public initializer {␊ - _setSigner(signer);␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ }␊ }␊ ` -## Account with SignerECDSA with ERC7821 Execution +## Account with ERC7821 Execution upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {ERC7821} from "@openzeppelin/community-contracts/account/extensions/ERC7821.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerECDSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerECDSA, ERC7821 {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, ERC7821 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ - ␊ - function initializeECDSA(address signer) public initializer {␊ - _setSigner(signer);␊ - }␊ ␊ function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ internal␊ @@ -942,104 +1143,105 @@ Generated by [AVA](https://avajs.dev). {␊ return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ }␊ + ␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + // Custom validation logic␊ + return false;␊ + }␊ }␊ ` -## Account with SignerECDSA with ERC7579 +## Account with ERC7579 upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerECDSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerECDSA {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ + ␊ + function initialize(uint256 moduleTypeId, address module, bytes calldata initData)␊ + public␊ + initializer␊ + {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ + }␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ - }␊ - ␊ - function initializeECDSA(address signer) public initializer {␊ - _setSigner(signer);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ - ␊ - // IMPORTANT: Make sure SignerECDSA is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerECDSA)␊ - // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ - function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ - internal␊ - view␊ - override(SignerECDSA, AbstractSigner, AccountERC7579)␊ - returns (bool)␊ - {␊ - return super._rawSignatureValidation(hash, signature);␊ - }␊ }␊ ` -## Account with SignerECDSA with ERC7579 with ERC1271 +## Account with ERC7579 with ERC1271 upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerECDSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, IERC1271, AccountERC7579, SignerECDSA {␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() {␊ _disableInitializers();␊ }␊ ␊ - function initializeECDSA(address signer) public initializer {␊ - _setSigner(signer);␊ + function initialize(uint256 moduleTypeId, address module, bytes calldata initData)␊ + public␊ + initializer␊ + {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ }␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ @@ -1048,201 +1250,152 @@ Generated by [AVA](https://avajs.dev). function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(IERC1271, AccountERC7579)␊ + override(IERC1271, AccountERC7579Upgradeable)␊ returns (bytes4)␊ {␊ return super.isValidSignature(hash, signature);␊ }␊ - ␊ - // IMPORTANT: Make sure SignerECDSA is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerECDSA)␊ - // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ - function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ - internal␊ - view␊ - override(SignerECDSA, AbstractSigner, AccountERC7579)␊ - returns (bool)␊ - {␊ - return super._rawSignatureValidation(hash, signature);␊ - }␊ }␊ ` -## Account with SignerECDSA with ERC7579 with ERC7739 +## Account with ERC7579 with ERC7739 upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerECDSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerECDSA {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ + ␊ + function initialize(uint256 moduleTypeId, address module, bytes calldata initData)␊ + public␊ + initializer␊ + {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ + }␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ - }␊ - ␊ - function initializeECDSA(address signer) public initializer {␊ - _setSigner(signer);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ - ␊ - // IMPORTANT: Make sure SignerECDSA is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerECDSA)␊ - // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ - function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ - internal␊ - view␊ - override(SignerECDSA, AbstractSigner, AccountERC7579)␊ - returns (bool)␊ - {␊ - return super._rawSignatureValidation(hash, signature);␊ - }␊ }␊ ` -## Account with SignerECDSA with ERC7579 hooks +## Account with ERC7579 hooks upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ - import {AccountERC7579Hooked} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579Hooked.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerECDSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Hooked, SignerECDSA {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ + ␊ + function initialize(uint256 moduleTypeId, address module, bytes calldata initData)␊ + public␊ + initializer␊ + {␊ + require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);␊ + _installModule(moduleTypeId, module, initData);␊ + }␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ - }␊ - ␊ - function initializeECDSA(address signer) public initializer {␊ - _setSigner(signer);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ - ␊ - // IMPORTANT: Make sure SignerECDSA is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerECDSA)␊ - // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ - function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ - internal␊ - view␊ - override(SignerECDSA, AbstractSigner, AccountERC7579)␊ - returns (bool)␊ - {␊ - return super._rawSignatureValidation(hash, signature);␊ - }␊ }␊ ` -## Account with SignerP256 named +## Account with SignerERC7702 named non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerP256} from "@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol";␊ - ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerP256 is Initializable, Account, EIP712, ERC7739, SignerP256 {␊ - constructor() EIP712("CustomAccount with SignerP256", "1") {␊ - _disableInitializers();␊ - }␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {SignerERC7702} from "@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol";␊ ␊ - function initializeP256(bytes32 qx, bytes32 qy) public initializer {␊ - _setSigner(qx, qy);␊ - }␊ + contract CustomAccountWithSignerERC7702 is Account, EIP712, ERC7739, SignerERC7702 {␊ + constructor() EIP712("CustomAccount with SignerERC7702", "1") {}␊ }␊ ` -## Account with SignerP256 with ERC1271 +## Account with SignerERC7702 with ERC1271 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerP256} from "@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol";␊ - ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerP256ERC1271 is Initializable, Account, IERC1271, SignerP256 {␊ - constructor() {␊ - _disableInitializers();␊ - }␊ + import {SignerERC7702} from "@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol";␊ ␊ + contract CustomAccountWithSignerERC7702ERC1271 is Account, IERC1271, SignerERC7702 {␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ @@ -1251,147 +1404,103 @@ Generated by [AVA](https://avajs.dev). {␊ return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ }␊ - ␊ - function initializeP256(bytes32 qx, bytes32 qy) public initializer {␊ - _setSigner(qx, qy);␊ - }␊ }␊ ` -## Account with SignerP256 with ERC7739 +## Account with SignerERC7702 with ERC7739 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerP256} from "@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol";␊ - ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerP256ERC7739 is Initializable, Account, EIP712, ERC7739, SignerP256 {␊ - constructor() EIP712("CustomAccount with SignerP256ERC7739", "1") {␊ - _disableInitializers();␊ - }␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {SignerERC7702} from "@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol";␊ ␊ - function initializeP256(bytes32 qx, bytes32 qy) public initializer {␊ - _setSigner(qx, qy);␊ - }␊ + contract CustomAccountWithSignerERC7702ERC7739 is Account, EIP712, ERC7739, SignerERC7702 {␊ + constructor() EIP712("CustomAccount with SignerERC7702ERC7739", "1") {}␊ }␊ ` -## Account with SignerP256 with ERC721Holder +## Account with SignerERC7702 with ERC721Holder non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerP256} from "@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol";␊ - ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerP256ERC721Holder is Initializable, Account, EIP712, ERC7739, SignerP256, ERC721Holder {␊ - constructor() EIP712("CustomAccount with SignerP256ERC721Holder", "1") {␊ - _disableInitializers();␊ - }␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {SignerERC7702} from "@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol";␊ ␊ - function initializeP256(bytes32 qx, bytes32 qy) public initializer {␊ - _setSigner(qx, qy);␊ - }␊ + contract CustomAccountWithSignerERC7702ERC721Holder is Account, EIP712, ERC7739, SignerERC7702, ERC721Holder {␊ + constructor() EIP712("CustomAccount with SignerERC7702ERC721Holder", "1") {}␊ }␊ ` -## Account with SignerP256 with ERC1155Holder +## Account with SignerERC7702 with ERC1155Holder non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerP256} from "@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol";␊ - ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerP256ERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerP256, ERC1155Holder {␊ - constructor() EIP712("CustomAccount with SignerP256ERC1155Holder", "1") {␊ - _disableInitializers();␊ - }␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {SignerERC7702} from "@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol";␊ ␊ - function initializeP256(bytes32 qx, bytes32 qy) public initializer {␊ - _setSigner(qx, qy);␊ - }␊ + contract CustomAccountWithSignerERC7702ERC1155Holder is Account, EIP712, ERC7739, SignerERC7702, ERC1155Holder {␊ + constructor() EIP712("CustomAccount with SignerERC7702ERC1155Holder", "1") {}␊ }␊ ` -## Account with SignerP256 with ERC721Holder and ERC1155Holder +## Account with SignerERC7702 with ERC721Holder and ERC1155Holder non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerP256} from "@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {SignerERC7702} from "@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerP256ERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerP256, ERC721Holder, ERC1155Holder {␊ + contract CustomAccountWithSignerERC7702ERC721HolderERC1155Holder is Account, EIP712, ERC7739, SignerERC7702, ERC721Holder, ERC1155Holder {␊ constructor()␊ - EIP712("CustomAccount with SignerP256ERC721HolderERC1155Holder", "1")␊ - {␊ - _disableInitializers();␊ - }␊ - ␊ - function initializeP256(bytes32 qx, bytes32 qy) public initializer {␊ - _setSigner(qx, qy);␊ - }␊ + EIP712("CustomAccount with SignerERC7702ERC721HolderERC1155Holder", "1")␊ + {}␊ }␊ ` -## Account with SignerP256 with ERC7821 Execution +## Account with SignerERC7702 with ERC7821 Execution non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {ERC7821} from "@openzeppelin/community-contracts/account/extensions/ERC7821.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerP256} from "@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {SignerERC7702} from "@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerP256, ERC7821 {␊ - constructor() EIP712("MyAccount", "1") {␊ - _disableInitializers();␊ - }␊ - ␊ - function initializeP256(bytes32 qx, bytes32 qy) public initializer {␊ - _setSigner(qx, qy);␊ - }␊ + contract MyAccount is Account, EIP712, ERC7739, SignerERC7702, ERC7821 {␊ + constructor() EIP712("MyAccount", "1") {}␊ ␊ function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ internal␊ @@ -1404,28 +1513,24 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerP256 with ERC7579 +## Account with SignerERC7702 with ERC7579 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerP256} from "@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol";␊ + import {SignerERC7702} from "@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerP256 {␊ - constructor() EIP712("MyAccount", "1") {␊ - _disableInitializers();␊ - }␊ + contract MyAccount is Account, EIP712, ERC7739, AccountERC7579, SignerERC7702 {␊ + constructor() EIP712("MyAccount", "1") {}␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ @@ -1438,10 +1543,6 @@ Generated by [AVA](https://avajs.dev). bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ }␊ - ␊ - function initializeP256(bytes32 qx, bytes32 qy) public initializer {␊ - _setSigner(qx, qy);␊ - }␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ @@ -1453,14 +1554,14 @@ Generated by [AVA](https://avajs.dev). return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerP256 is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerP256)␊ + // IMPORTANT: Make sure SignerERC7702 is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerERC7702)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(SignerP256, AbstractSigner, AccountERC7579)␊ + override(SignerERC7702, AbstractSigner, AccountERC7579)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -1468,32 +1569,22 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerP256 with ERC7579 with ERC1271 +## Account with SignerERC7702 with ERC7579 with ERC1271 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerP256} from "@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol";␊ - ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, IERC1271, AccountERC7579, SignerP256 {␊ - constructor() {␊ - _disableInitializers();␊ - }␊ - ␊ - function initializeP256(bytes32 qx, bytes32 qy) public initializer {␊ - _setSigner(qx, qy);␊ - }␊ + import {SignerERC7702} from "@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol";␊ ␊ + contract MyAccount is Account, IERC1271, AccountERC7579, SignerERC7702 {␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ @@ -1513,14 +1604,14 @@ Generated by [AVA](https://avajs.dev). return super.isValidSignature(hash, signature);␊ }␊ ␊ - // IMPORTANT: Make sure SignerP256 is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerP256)␊ + // IMPORTANT: Make sure SignerERC7702 is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerERC7702)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(SignerP256, AbstractSigner, AccountERC7579)␊ + override(SignerERC7702, AbstractSigner, AccountERC7579)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -1528,28 +1619,24 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerP256 with ERC7579 with ERC7739 +## Account with SignerERC7702 with ERC7579 with ERC7739 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerP256} from "@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol";␊ + import {SignerERC7702} from "@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerP256 {␊ - constructor() EIP712("MyAccount", "1") {␊ - _disableInitializers();␊ - }␊ + contract MyAccount is Account, EIP712, ERC7739, AccountERC7579, SignerERC7702 {␊ + constructor() EIP712("MyAccount", "1") {}␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ @@ -1562,10 +1649,6 @@ Generated by [AVA](https://avajs.dev). bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ }␊ - ␊ - function initializeP256(bytes32 qx, bytes32 qy) public initializer {␊ - _setSigner(qx, qy);␊ - }␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ @@ -1577,14 +1660,14 @@ Generated by [AVA](https://avajs.dev). return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerP256 is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerP256)␊ + // IMPORTANT: Make sure SignerERC7702 is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerERC7702)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(SignerP256, AbstractSigner, AccountERC7579)␊ + override(SignerERC7702, AbstractSigner, AccountERC7579)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -1592,29 +1675,25 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerP256 with ERC7579 hooks +## Account with SignerERC7702 with ERC7579 hooks non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ - import {AccountERC7579Hooked} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579Hooked.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {AccountERC7579Hooked} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579Hooked.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerP256} from "@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol";␊ + import {SignerERC7702} from "@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Hooked, SignerP256 {␊ - constructor() EIP712("MyAccount", "1") {␊ - _disableInitializers();␊ - }␊ + contract MyAccount is Account, EIP712, ERC7739, AccountERC7579Hooked, SignerERC7702 {␊ + constructor() EIP712("MyAccount", "1") {}␊ ␊ function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ @@ -1627,10 +1706,6 @@ Generated by [AVA](https://avajs.dev). bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ }␊ - ␊ - function initializeP256(bytes32 qx, bytes32 qy) public initializer {␊ - _setSigner(qx, qy);␊ - }␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ @@ -1642,14 +1717,14 @@ Generated by [AVA](https://avajs.dev). return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerP256 is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerP256)␊ + // IMPORTANT: Make sure SignerERC7702 is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerERC7702)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(SignerP256, AbstractSigner, AccountERC7579)␊ + override(SignerERC7702, AbstractSigner, AccountERC7579)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -1657,48 +1732,55 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerRSA named +## Account with SignerECDSA named non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerRSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerRSA is Initializable, Account, EIP712, ERC7739, SignerRSA {␊ - constructor() EIP712("CustomAccount with SignerRSA", "1") {␊ + contract CustomAccountWithSignerECDSA is Initializable, Account, EIP712, ERC7739, SignerECDSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer)␊ + EIP712("CustomAccount with SignerECDSA", "1")␊ + SignerECDSA(signer)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ _disableInitializers();␊ }␊ ␊ - function initializeRSA(bytes memory e, bytes memory n) public initializer {␊ - _setSigner(e, n);␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ }␊ }␊ ` -## Account with SignerRSA with ERC1271 +## Account with SignerECDSA with ERC1271 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerRSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerRSAERC1271 is Initializable, Account, IERC1271, SignerRSA {␊ - constructor() {␊ + contract CustomAccountWithSignerECDSAERC1271 is Initializable, Account, IERC1271, SignerECDSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer) SignerECDSA(signer) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ _disableInitializers();␊ }␊ ␊ @@ -1711,145 +1793,165 @@ Generated by [AVA](https://avajs.dev). return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ }␊ ␊ - function initializeRSA(bytes memory e, bytes memory n) public initializer {␊ - _setSigner(e, n);␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ }␊ }␊ ` -## Account with SignerRSA with ERC7739 +## Account with SignerECDSA with ERC7739 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerRSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerRSAERC7739 is Initializable, Account, EIP712, ERC7739, SignerRSA {␊ - constructor() EIP712("CustomAccount with SignerRSAERC7739", "1") {␊ + contract CustomAccountWithSignerECDSAERC7739 is Initializable, Account, EIP712, ERC7739, SignerECDSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer)␊ + EIP712("CustomAccount with SignerECDSAERC7739", "1")␊ + SignerECDSA(signer)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ _disableInitializers();␊ }␊ ␊ - function initializeRSA(bytes memory e, bytes memory n) public initializer {␊ - _setSigner(e, n);␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ }␊ }␊ ` -## Account with SignerRSA with ERC721Holder +## Account with SignerECDSA with ERC721Holder non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerRSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerRSAERC721Holder is Initializable, Account, EIP712, ERC7739, SignerRSA, ERC721Holder {␊ - constructor() EIP712("CustomAccount with SignerRSAERC721Holder", "1") {␊ + contract CustomAccountWithSignerECDSAERC721Holder is Initializable, Account, EIP712, ERC7739, SignerECDSA, ERC721Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer)␊ + EIP712("CustomAccount with SignerECDSAERC721Holder", "1")␊ + SignerECDSA(signer)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ _disableInitializers();␊ }␊ ␊ - function initializeRSA(bytes memory e, bytes memory n) public initializer {␊ - _setSigner(e, n);␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ }␊ }␊ ` -## Account with SignerRSA with ERC1155Holder +## Account with SignerECDSA with ERC1155Holder non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerRSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerRSAERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerRSA, ERC1155Holder {␊ - constructor() EIP712("CustomAccount with SignerRSAERC1155Holder", "1") {␊ + contract CustomAccountWithSignerECDSAERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerECDSA, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer)␊ + EIP712("CustomAccount with SignerECDSAERC1155Holder", "1")␊ + SignerECDSA(signer)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ _disableInitializers();␊ }␊ ␊ - function initializeRSA(bytes memory e, bytes memory n) public initializer {␊ - _setSigner(e, n);␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ }␊ }␊ ` -## Account with SignerRSA with ERC721Holder and ERC1155Holder +## Account with SignerECDSA with ERC721Holder and ERC1155Holder non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerRSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerRSAERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerRSA, ERC721Holder, ERC1155Holder {␊ - constructor()␊ - EIP712("CustomAccount with SignerRSAERC721HolderERC1155Holder", "1")␊ + contract CustomAccountWithSignerECDSAERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerECDSA, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer)␊ + EIP712("CustomAccount with SignerECDSAERC721HolderERC1155Holder", "1")␊ + SignerECDSA(signer)␊ {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ _disableInitializers();␊ }␊ ␊ - function initializeRSA(bytes memory e, bytes memory n) public initializer {␊ - _setSigner(e, n);␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ }␊ }␊ ` -## Account with SignerRSA with ERC7821 Execution +## Account with SignerECDSA with ERC7821 Execution non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {ERC7821} from "@openzeppelin/community-contracts/account/extensions/ERC7821.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {SignerRSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerRSA, ERC7821 {␊ - constructor() EIP712("MyAccount", "1") {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerECDSA, ERC7821 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer) EIP712("MyAccount", "1") SignerECDSA(signer) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ _disableInitializers();␊ }␊ ␊ - function initializeRSA(bytes memory e, bytes memory n) public initializer {␊ - _setSigner(e, n);␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ }␊ ␊ function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ @@ -1863,26 +1965,28 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerRSA with ERC7579 +## Account with SignerECDSA with ERC7579 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerRSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerRSA {␊ - constructor() EIP712("MyAccount", "1") {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerECDSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer) EIP712("MyAccount", "1") SignerECDSA(signer) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ _disableInitializers();␊ }␊ ␊ @@ -1898,8 +2002,8 @@ Generated by [AVA](https://avajs.dev). return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ - function initializeRSA(bytes memory e, bytes memory n) public initializer {␊ - _setSigner(e, n);␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ }␊ ␊ // The following functions are overrides required by Solidity.␊ @@ -1912,14 +2016,14 @@ Generated by [AVA](https://avajs.dev). return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerRSA is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerRSA)␊ + // IMPORTANT: Make sure SignerECDSA is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerECDSA)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(SignerRSA, AbstractSigner, AccountERC7579)␊ + override(SignerECDSA, AbstractSigner, AccountERC7579)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -1927,30 +2031,32 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerRSA with ERC7579 with ERC1271 +## Account with SignerECDSA with ERC7579 with ERC1271 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerRSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, IERC1271, AccountERC7579, SignerRSA {␊ - constructor() {␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579, SignerECDSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer) SignerECDSA(signer) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ _disableInitializers();␊ }␊ ␊ - function initializeRSA(bytes memory e, bytes memory n) public initializer {␊ - _setSigner(e, n);␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ }␊ ␊ // The following functions are overrides required by Solidity.␊ @@ -1972,14 +2078,14 @@ Generated by [AVA](https://avajs.dev). return super.isValidSignature(hash, signature);␊ }␊ ␊ - // IMPORTANT: Make sure SignerRSA is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerRSA)␊ + // IMPORTANT: Make sure SignerECDSA is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerECDSA)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(SignerRSA, AbstractSigner, AccountERC7579)␊ + override(SignerECDSA, AbstractSigner, AccountERC7579)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -1987,26 +2093,28 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerRSA with ERC7579 with ERC7739 +## Account with SignerECDSA with ERC7579 with ERC7739 non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerRSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerRSA {␊ - constructor() EIP712("MyAccount", "1") {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerECDSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer) EIP712("MyAccount", "1") SignerECDSA(signer) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ _disableInitializers();␊ }␊ ␊ @@ -2022,8 +2130,8 @@ Generated by [AVA](https://avajs.dev). return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ - function initializeRSA(bytes memory e, bytes memory n) public initializer {␊ - _setSigner(e, n);␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ }␊ ␊ // The following functions are overrides required by Solidity.␊ @@ -2036,14 +2144,14 @@ Generated by [AVA](https://avajs.dev). return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerRSA is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerRSA)␊ + // IMPORTANT: Make sure SignerECDSA is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerECDSA)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(SignerRSA, AbstractSigner, AccountERC7579)␊ + override(SignerECDSA, AbstractSigner, AccountERC7579)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -2051,27 +2159,29 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerRSA with ERC7579 hooks +## Account with SignerECDSA with ERC7579 hooks non-upgradeable > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ - import {AccountERC7579Hooked} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579Hooked.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {AccountERC7579Hooked} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579Hooked.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ - import {SignerRSA} from "@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Hooked, SignerRSA {␊ - constructor() EIP712("MyAccount", "1") {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Hooked, SignerECDSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer) EIP712("MyAccount", "1") SignerECDSA(signer) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ _disableInitializers();␊ }␊ ␊ @@ -2087,8 +2197,8 @@ Generated by [AVA](https://avajs.dev). return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ - function initializeRSA(bytes memory e, bytes memory n) public initializer {␊ - _setSigner(e, n);␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ }␊ ␊ // The following functions are overrides required by Solidity.␊ @@ -2101,14 +2211,14 @@ Generated by [AVA](https://avajs.dev). return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerRSA is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerRSA)␊ + // IMPORTANT: Make sure SignerECDSA is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerECDSA)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(SignerRSA, AbstractSigner, AccountERC7579)␊ + override(SignerECDSA, AbstractSigner, AccountERC7579)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -2116,63 +2226,55 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerMultisig named +## Account with SignerECDSA named upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisig is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913 {␊ - constructor() EIP712("CustomAccount with SignerMultisig", "1") {␊ + contract CustomAccountWithSignerECDSA is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerECDSA", "1") {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisig(bytes[] memory signers, uint256 threshold)␊ - public␊ - initializer␊ - {␊ - _addSigners(signers);␊ - _setThreshold(threshold);␊ - }␊ - ␊ - function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ - _addSigners(signers);␊ - }␊ - ␊ - function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ - _removeSigners(signers);␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ - _setThreshold(threshold);␊ - }␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerMultisig with ERC1271 +## Account with SignerECDSA with ERC1271 upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisigERC1271 is Initializable, Account, IERC1271, MultiSignerERC7913 {␊ + contract CustomAccountWithSignerECDSAERC1271 is Initializable, Account, IERC1271, SignerECDSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() {␊ _disableInitializers();␊ }␊ @@ -2186,12 +2288,6826 @@ Generated by [AVA](https://avajs.dev). return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ }␊ ␊ - function initializeMultisig(bytes[] memory signers, uint256 threshold)␊ - public␊ - initializer␊ - {␊ - _addSigners(signers);␊ - _setThreshold(threshold);␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerECDSA with ERC7739 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerECDSAERC7739 is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerECDSAERC7739", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerECDSA with ERC721Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerECDSAERC721Holder is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, ERC721Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerECDSAERC721Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerECDSA with ERC1155Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerECDSAERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerECDSAERC1155Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerECDSA with ERC721Holder and ERC1155Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerECDSAERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, ERC721Holder, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor()␊ + EIP712("CustomAccount with SignerECDSAERC721HolderERC1155Holder", "1")␊ + {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerECDSA with ERC7821 Execution upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, ERC7821, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerECDSA with ERC7579 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerECDSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerECDSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerECDSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerECDSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC7579 with ERC1271 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable, SignerECDSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579Upgradeable)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerECDSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerECDSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerECDSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC7579 with ERC7739 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerECDSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerECDSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerECDSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerECDSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC7579 hooks upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable, SignerECDSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerECDSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerECDSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerECDSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA named upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerECDSA is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerECDSA", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC1271 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerECDSAERC1271 is Initializable, Account, IERC1271, SignerECDSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC7739 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerECDSAERC7739 is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerECDSAERC7739", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC721Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerECDSAERC721Holder is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, ERC721Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerECDSAERC721Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC1155Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerECDSAERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerECDSAERC1155Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC721Holder and ERC1155Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerECDSAERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor()␊ + EIP712("CustomAccount with SignerECDSAERC721HolderERC1155Holder", "1")␊ + {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC7821 Execution upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, ERC7821 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC7579 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerECDSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerECDSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerECDSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerECDSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC7579 with ERC1271 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable, SignerECDSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579Upgradeable)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerECDSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerECDSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerECDSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC7579 with ERC7739 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerECDSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerECDSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerECDSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerECDSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerECDSA with ERC7579 hooks upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable, SignerECDSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerECDSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerECDSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerECDSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 named non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerP256} from "@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol";␊ + ␊ + contract CustomAccountWithSignerP256 is Initializable, Account, EIP712, ERC7739, SignerP256 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes32 qx, bytes32 qy)␊ + EIP712("CustomAccount with SignerP256", "1")␊ + SignerP256(qx, qy)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + _setSigner(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC1271 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerP256} from "@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC1271 is Initializable, Account, IERC1271, SignerP256 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes32 qx, bytes32 qy) SignerP256(qx, qy) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + _setSigner(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7739 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerP256} from "@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC7739 is Initializable, Account, EIP712, ERC7739, SignerP256 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes32 qx, bytes32 qy)␊ + EIP712("CustomAccount with SignerP256ERC7739", "1")␊ + SignerP256(qx, qy)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + _setSigner(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC721Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerP256} from "@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC721Holder is Initializable, Account, EIP712, ERC7739, SignerP256, ERC721Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes32 qx, bytes32 qy)␊ + EIP712("CustomAccount with SignerP256ERC721Holder", "1")␊ + SignerP256(qx, qy)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + _setSigner(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC1155Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerP256} from "@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerP256, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes32 qx, bytes32 qy)␊ + EIP712("CustomAccount with SignerP256ERC1155Holder", "1")␊ + SignerP256(qx, qy)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + _setSigner(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC721Holder and ERC1155Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerP256} from "@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerP256, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes32 qx, bytes32 qy)␊ + EIP712("CustomAccount with SignerP256ERC721HolderERC1155Holder", "1")␊ + SignerP256(qx, qy)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + _setSigner(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7821 Execution non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerP256} from "@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerP256, ERC7821 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes32 qx, bytes32 qy)␊ + EIP712("MyAccount", "1")␊ + SignerP256(qx, qy)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + _setSigner(qx, qy);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256} from "@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerP256 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes32 qx, bytes32 qy)␊ + EIP712("MyAccount", "1")␊ + SignerP256(qx, qy)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + _setSigner(qx, qy);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256 is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerP256)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 with ERC1271 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256} from "@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579, SignerP256 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes32 qx, bytes32 qy) SignerP256(qx, qy) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + _setSigner(qx, qy);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256 is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerP256)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 with ERC7739 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256} from "@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerP256 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes32 qx, bytes32 qy)␊ + EIP712("MyAccount", "1")␊ + SignerP256(qx, qy)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + _setSigner(qx, qy);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256 is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerP256)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 hooks non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {AccountERC7579Hooked} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579Hooked.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256} from "@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Hooked, SignerP256 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes32 qx, bytes32 qy)␊ + EIP712("MyAccount", "1")␊ + SignerP256(qx, qy)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + _setSigner(qx, qy);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256 is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerP256)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 named upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256 is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerP256", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerP256 with ERC1271 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC1271 is Initializable, Account, IERC1271, SignerP256Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerP256 with ERC7739 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC7739 is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerP256ERC7739", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerP256 with ERC721Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC721Holder is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable, ERC721Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerP256ERC721Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerP256 with ERC1155Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerP256ERC1155Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerP256 with ERC721Holder and ERC1155Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable, ERC721Holder, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor()␊ + EIP712("CustomAccount with SignerP256ERC721HolderERC1155Holder", "1")␊ + {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerP256 with ERC7821 Execution upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable, ERC7821, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerP256Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256Upgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerP256Upgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 with ERC1271 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable, SignerP256Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579Upgradeable)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256Upgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerP256Upgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 with ERC7739 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerP256Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256Upgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerP256Upgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 hooks upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable, SignerP256Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256Upgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerP256Upgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 named upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256 is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerP256", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC1271 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC1271 is Initializable, Account, IERC1271, SignerP256Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7739 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC7739 is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerP256ERC7739", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC721Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC721Holder is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable, ERC721Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerP256ERC721Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC1155Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerP256ERC1155Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC721Holder and ERC1155Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerP256ERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor()␊ + EIP712("CustomAccount with SignerP256ERC721HolderERC1155Holder", "1")␊ + {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7821 Execution upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerP256Upgradeable, ERC7821 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerP256Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256Upgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerP256Upgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 with ERC1271 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable, SignerP256Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579Upgradeable)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256Upgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerP256Upgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 with ERC7739 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerP256Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256Upgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerP256Upgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerP256 with ERC7579 hooks upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerP256Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerP256Upgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable, SignerP256Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes32 qx, bytes32 qy) public initializer {␊ + __SignerP256_init(qx, qy);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerP256Upgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerP256Upgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerP256Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA named non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerRSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol";␊ + ␊ + contract CustomAccountWithSignerRSA is Initializable, Account, EIP712, ERC7739, SignerRSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes memory e, bytes memory n)␊ + EIP712("CustomAccount with SignerRSA", "1")␊ + SignerRSA(e, n)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + _setSigner(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC1271 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerRSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC1271 is Initializable, Account, IERC1271, SignerRSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes memory e, bytes memory n) SignerRSA(e, n) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + _setSigner(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7739 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerRSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC7739 is Initializable, Account, EIP712, ERC7739, SignerRSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes memory e, bytes memory n)␊ + EIP712("CustomAccount with SignerRSAERC7739", "1")␊ + SignerRSA(e, n)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + _setSigner(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC721Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerRSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC721Holder is Initializable, Account, EIP712, ERC7739, SignerRSA, ERC721Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes memory e, bytes memory n)␊ + EIP712("CustomAccount with SignerRSAERC721Holder", "1")␊ + SignerRSA(e, n)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + _setSigner(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC1155Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerRSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerRSA, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes memory e, bytes memory n)␊ + EIP712("CustomAccount with SignerRSAERC1155Holder", "1")␊ + SignerRSA(e, n)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + _setSigner(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC721Holder and ERC1155Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerRSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerRSA, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes memory e, bytes memory n)␊ + EIP712("CustomAccount with SignerRSAERC721HolderERC1155Holder", "1")␊ + SignerRSA(e, n)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + _setSigner(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7821 Execution non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerRSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerRSA, ERC7821 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes memory e, bytes memory n)␊ + EIP712("MyAccount", "1")␊ + SignerRSA(e, n)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + _setSigner(e, n);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerRSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes memory e, bytes memory n)␊ + EIP712("MyAccount", "1")␊ + SignerRSA(e, n)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + _setSigner(e, n);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSA is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerRSA)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSA, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 with ERC1271 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579, SignerRSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes memory e, bytes memory n) SignerRSA(e, n) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + _setSigner(e, n);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSA is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerRSA)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSA, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 with ERC7739 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, SignerRSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes memory e, bytes memory n)␊ + EIP712("MyAccount", "1")␊ + SignerRSA(e, n)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + _setSigner(e, n);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSA is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerRSA)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSA, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 hooks non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {AccountERC7579Hooked} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579Hooked.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Hooked, SignerRSA {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes memory e, bytes memory n)␊ + EIP712("MyAccount", "1")␊ + SignerRSA(e, n)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + _setSigner(e, n);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSA is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerRSA)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSA, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA named upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSA is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerRSA", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerRSA with ERC1271 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC1271 is Initializable, Account, IERC1271, SignerRSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerRSA with ERC7739 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC7739 is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerRSAERC7739", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerRSA with ERC721Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC721Holder is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable, ERC721Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerRSAERC721Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerRSA with ERC1155Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerRSAERC1155Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerRSA with ERC721Holder and ERC1155Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable, ERC721Holder, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor()␊ + EIP712("CustomAccount with SignerRSAERC721HolderERC1155Holder", "1")␊ + {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerRSA with ERC7821 Execution upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable, ERC7821, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerRSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerRSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 with ERC1271 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable, SignerRSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579Upgradeable)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerRSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 with ERC7739 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerRSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerRSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 hooks upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable, SignerRSAUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerRSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA named upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSA is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerRSA", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC1271 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC1271 is Initializable, Account, IERC1271, SignerRSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7739 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC7739 is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerRSAERC7739", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC721Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC721Holder is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable, ERC721Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerRSAERC721Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC1155Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerRSAERC1155Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC721Holder and ERC1155Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerRSAERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor()␊ + EIP712("CustomAccount with SignerRSAERC721HolderERC1155Holder", "1")␊ + {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7821 Execution upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerRSAUpgradeable, ERC7821 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerRSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerRSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 with ERC1271 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable, SignerRSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579Upgradeable)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerRSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 with ERC7739 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, SignerRSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerRSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerRSA with ERC7579 hooks upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {SignerRSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerRSAUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable, SignerRSAUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes memory e, bytes memory n) public initializer {␊ + __SignerRSA_init(e, n);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerRSAUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerRSAUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(SignerRSAUpgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig named non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + ␊ + contract CustomAccountWithSignerMultisig is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64 threshold)␊ + EIP712("CustomAccount with SignerMultisig", "1")␊ + MultiSignerERC7913(signers, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC1271 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC1271 is Initializable, Account, IERC1271, MultiSignerERC7913 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64 threshold)␊ + MultiSignerERC7913(signers, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7739 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC7739 is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64 threshold)␊ + EIP712("CustomAccount with SignerMultisigERC7739", "1")␊ + MultiSignerERC7913(signers, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC721Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC721Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913, ERC721Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64 threshold)␊ + EIP712("CustomAccount with SignerMultisigERC721Holder", "1")␊ + MultiSignerERC7913(signers, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC1155Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64 threshold)␊ + EIP712("CustomAccount with SignerMultisigERC1155Holder", "1")␊ + MultiSignerERC7913(signers, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC721Holder and ERC1155Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64 threshold)␊ + EIP712("CustomAccount with SignerMultisigERC721HolderERC1155Holder", "1")␊ + MultiSignerERC7913(signers, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7821 Execution non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913, ERC7821 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64 threshold)␊ + EIP712("MyAccount", "1")␊ + MultiSignerERC7913(signers, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, MultiSignerERC7913 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64 threshold)␊ + EIP712("MyAccount", "1")␊ + MultiSignerERC7913(signers, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisig is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisig)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 with ERC1271 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579, MultiSignerERC7913 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64 threshold)␊ + MultiSignerERC7913(signers, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisig is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisig)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 with ERC7739 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, MultiSignerERC7913 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64 threshold)␊ + EIP712("MyAccount", "1")␊ + MultiSignerERC7913(signers, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisig is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisig)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 hooks non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {AccountERC7579Hooked} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579Hooked.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Hooked, MultiSignerERC7913 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64 threshold)␊ + EIP712("MyAccount", "1")␊ + MultiSignerERC7913(signers, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisig is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisig)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig named upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisig is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerMultisig", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerMultisig with ERC1271 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC1271 is Initializable, Account, IERC1271, MultiSignerERC7913Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerMultisig with ERC7739 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC7739 is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerMultisigERC7739", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerMultisig with ERC721Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC721Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable, ERC721Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerMultisigERC721Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerMultisig with ERC1155Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerMultisigERC1155Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerMultisig with ERC721Holder and ERC1155Holder upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable, ERC721Holder, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor()␊ + EIP712("CustomAccount with SignerMultisigERC721HolderERC1155Holder", "1")␊ + {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerMultisig with ERC7821 Execution upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable, ERC7821, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, MultiSignerERC7913Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 with ERC1271 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable, MultiSignerERC7913Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579Upgradeable)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 with ERC7739 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, MultiSignerERC7913Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 hooks upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable, MultiSignerERC7913Upgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig named upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisig is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerMultisig", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC1271 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC1271 is Initializable, Account, IERC1271, MultiSignerERC7913Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7739 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC7739 is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerMultisigERC7739", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC721Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC721Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable, ERC721Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerMultisigERC721Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC1155Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerMultisigERC1155Holder", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC721Holder and ERC1155Holder upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor()␊ + EIP712("CustomAccount with SignerMultisigERC721HolderERC1155Holder", "1")␊ + {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7821 Execution upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Upgradeable, ERC7821 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, MultiSignerERC7913Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 with ERC1271 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable, MultiSignerERC7913Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579Upgradeable)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 with ERC7739 upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, MultiSignerERC7913Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisig with ERC7579 hooks upgradeable transparent + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable, MultiSignerERC7913Upgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("MyAccount", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579Upgradeable, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913_init(signers, threshold);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579Upgradeable)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigUpgradeable)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted named non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Weighted} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigWeighted is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + EIP712("CustomAccount with SignerMultisigWeighted", "1")␊ + MultiSignerERC7913Weighted(signers, weights, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setSignerWeights(signers, weights);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted with ERC1271 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Weighted} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigWeightedERC1271 is Initializable, Account, IERC1271, MultiSignerERC7913Weighted {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + MultiSignerERC7913Weighted(signers, weights, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setSignerWeights(signers, weights);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted with ERC7739 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Weighted} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigWeightedERC7739 is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + EIP712("CustomAccount with SignerMultisigWeightedERC7739", "1")␊ + MultiSignerERC7913Weighted(signers, weights, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setSignerWeights(signers, weights);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted with ERC721Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Weighted} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigWeightedERC721Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted, ERC721Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + EIP712("CustomAccount with SignerMultisigWeightedERC721Holder", "1")␊ + MultiSignerERC7913Weighted(signers, weights, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setSignerWeights(signers, weights);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted with ERC1155Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Weighted} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigWeightedERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + EIP712("CustomAccount with SignerMultisigWeightedERC1155Holder", "1")␊ + MultiSignerERC7913Weighted(signers, weights, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setSignerWeights(signers, weights);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted with ERC721Holder and ERC1155Holder non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Weighted} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigWeightedERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + EIP712("CustomAccount with SignerMultisigWeightedERC721HolderERC1155Holder", "1")␊ + MultiSignerERC7913Weighted(signers, weights, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setSignerWeights(signers, weights);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted with ERC7821 Execution non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Weighted} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted, ERC7821 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + EIP712("MyAccount", "1")␊ + MultiSignerERC7913Weighted(signers, weights, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setSignerWeights(signers, weights);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _erc7821AuthorizedExecutor(address caller, bytes32 mode, bytes calldata executionData)␊ + internal␊ + view␊ + override␊ + returns (bool)␊ + {␊ + return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted with ERC7579 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + import {MultiSignerERC7913Weighted} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, MultiSignerERC7913Weighted {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + EIP712("MyAccount", "1")␊ + MultiSignerERC7913Weighted(signers, weights, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setSignerWeights(signers, weights);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigWeighted is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisigWeighted)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted with ERC7579 with ERC1271 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + import {MultiSignerERC7913Weighted} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579, MultiSignerERC7913Weighted {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + MultiSignerERC7913Weighted(signers, weights, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setSignerWeights(signers, weights);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(IERC1271, AccountERC7579)␊ + returns (bytes4)␊ + {␊ + return super.isValidSignature(hash, signature);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigWeighted is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisigWeighted)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted with ERC7579 with ERC7739 non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + import {MultiSignerERC7913Weighted} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, MultiSignerERC7913Weighted {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + EIP712("MyAccount", "1")␊ + MultiSignerERC7913Weighted(signers, weights, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setSignerWeights(signers, weights);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigWeighted is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisigWeighted)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted with ERC7579 hooks non-upgradeable + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol";␊ + import {AccountERC7579Hooked} from "@openzeppelin/contracts/account/extensions/draft-AccountERC7579Hooked.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol";␊ + import {MultiSignerERC7913Weighted} from "@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol";␊ + import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Hooked, MultiSignerERC7913Weighted {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + EIP712("MyAccount", "1")␊ + MultiSignerERC7913Weighted(signers, weights, threshold)␊ + {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override(AccountERC7579, ERC7739)␊ + returns (bytes4)␊ + {␊ + // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ + // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ + bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + _addSigners(signers);␊ + _setSignerWeights(signers, weights);␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + // The following functions are overrides required by Solidity.␊ + ␊ + function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ + internal␊ + override(Account, AccountERC7579)␊ + returns (uint256)␊ + {␊ + return super._validateUserOp(userOp, userOpHash);␊ + }␊ + ␊ + // IMPORTANT: Make sure SignerMultisigWeighted is most derived than AccountERC7579␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisigWeighted)␊ + // to ensure the correct order of function resolution.␊ + // AccountERC7579 returns false for _rawSignatureValidation␊ + function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ + internal␊ + view␊ + override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + returns (bool)␊ + {␊ + return super._rawSignatureValidation(hash, signature);␊ + }␊ + }␊ + ` + +## Account with SignerMultisigWeighted named upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigWeighted is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("CustomAccount with SignerMultisigWeighted", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ + }␊ + ␊ + function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _addSigners(signers);␊ + }␊ + ␊ + function removeSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ + _removeSigners(signers);␊ + }␊ + ␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ + _setThreshold(threshold);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + ` + +## Account with SignerMultisigWeighted with ERC1271 upgradeable uups + +> Snapshot 1 + + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract CustomAccountWithSignerMultisigWeightedERC1271 is Initializable, Account, IERC1271, MultiSignerERC7913WeightedUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() {␊ + _disableInitializers();␊ + }␊ + ␊ + function isValidSignature(bytes32 hash, bytes calldata signature)␊ + public␊ + view␊ + override␊ + returns (bytes4)␊ + {␊ + return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ + }␊ + ␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ + public␊ + initializer␊ + {␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ }␊ ␊ function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ @@ -2202,38 +9118,53 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerMultisig with ERC7739 +## Account with SignerMultisigWeighted with ERC7739 upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisigERC7739 is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913 {␊ - constructor() EIP712("CustomAccount with SignerMultisigERC7739", "1") {␊ + contract CustomAccountWithSignerMultisigWeightedERC7739 is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor()␊ + EIP712("CustomAccount with SignerMultisigWeightedERC7739", "1")␊ + {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisig(bytes[] memory signers, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ }␊ ␊ function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ @@ -2244,39 +9175,54 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerMultisig with ERC721Holder +## Account with SignerMultisigWeighted with ERC721Holder upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisigERC721Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913, ERC721Holder {␊ - constructor() EIP712("CustomAccount with SignerMultisigERC721Holder", "1") {␊ + contract CustomAccountWithSignerMultisigWeightedERC721Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable, ERC721Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor()␊ + EIP712("CustomAccount with SignerMultisigWeightedERC721Holder", "1")␊ + {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisig(bytes[] memory signers, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ }␊ ␊ function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ @@ -2287,39 +9233,54 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerMultisig with ERC1155Holder +## Account with SignerMultisigWeighted with ERC1155Holder upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisigERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913, ERC1155Holder {␊ - constructor() EIP712("CustomAccount with SignerMultisigERC1155Holder", "1") {␊ + contract CustomAccountWithSignerMultisigWeightedERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor()␊ + EIP712("CustomAccount with SignerMultisigWeightedERC1155Holder", "1")␊ + {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisig(bytes[] memory signers, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ }␊ ␊ function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ @@ -2330,42 +9291,55 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerMultisig with ERC721Holder and ERC1155Holder +## Account with SignerMultisigWeighted with ERC721Holder and ERC1155Holder upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisigERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913, ERC721Holder, ERC1155Holder {␊ + contract CustomAccountWithSignerMultisigWeightedERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable, ERC721Holder, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor()␊ - EIP712("CustomAccount with SignerMultisigERC721HolderERC1155Holder", "1")␊ + EIP712("CustomAccount with SignerMultisigWeightedERC721HolderERC1155Holder", "1")␊ {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisig(bytes[] memory signers, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ }␊ ␊ function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ @@ -2376,39 +9350,52 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerMultisig with ERC7821 Execution +## Account with SignerMultisigWeighted with ERC7821 Execution upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {ERC7821} from "@openzeppelin/community-contracts/account/extensions/ERC7821.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ - ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913, ERC7821 {␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable, ERC7821, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisig(bytes[] memory signers, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ }␊ ␊ function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ @@ -2419,7 +9406,7 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ ␊ @@ -2431,28 +9418,36 @@ Generated by [AVA](https://avajs.dev). {␊ return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ }␊ ` -## Account with SignerMultisig with ERC7579 +## Account with SignerMultisigWeighted with ERC7579 upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, MultiSignerERC7913 {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, MultiSignerERC7913WeightedUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ @@ -2460,21 +9455,27 @@ Generated by [AVA](https://avajs.dev). function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ - function initializeMultisig(bytes[] memory signers, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ }␊ ␊ function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ @@ -2485,28 +9486,34 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerMultisig is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisig)␊ + // IMPORTANT: Make sure SignerMultisigWeightedUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigWeightedUpgradeable)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -2514,34 +9521,42 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerMultisig with ERC7579 with ERC1271 +## Account with SignerMultisigWeighted with ERC7579 with ERC1271 upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, IERC1271, AccountERC7579, MultiSignerERC7913 {␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable, MultiSignerERC7913WeightedUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisig(bytes[] memory signers, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ }␊ ␊ function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ @@ -2552,15 +9567,21 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ @@ -2569,20 +9590,20 @@ Generated by [AVA](https://avajs.dev). function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(IERC1271, AccountERC7579)␊ + override(IERC1271, AccountERC7579Upgradeable)␊ returns (bytes4)␊ {␊ return super.isValidSignature(hash, signature);␊ }␊ ␊ - // IMPORTANT: Make sure SignerMultisig is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisig)␊ + // IMPORTANT: Make sure SignerMultisigWeightedUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigWeightedUpgradeable)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -2590,25 +9611,27 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerMultisig with ERC7579 with ERC7739 +## Account with SignerMultisigWeighted with ERC7579 with ERC7739 upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, MultiSignerERC7913 {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, MultiSignerERC7913WeightedUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ @@ -2616,21 +9639,27 @@ Generated by [AVA](https://avajs.dev). function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ - function initializeMultisig(bytes[] memory signers, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ }␊ ␊ function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ @@ -2641,28 +9670,34 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerMultisig is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisig)␊ + // IMPORTANT: Make sure SignerMultisigWeightedUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigWeightedUpgradeable)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -2670,26 +9705,28 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerMultisig with ERC7579 hooks +## Account with SignerMultisigWeighted with ERC7579 hooks upgradeable uups > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ - import {AccountERC7579Hooked} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579Hooked.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Hooked, MultiSignerERC7913 {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable, MultiSignerERC7913WeightedUpgradeable, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ @@ -2697,21 +9734,27 @@ Generated by [AVA](https://avajs.dev). function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ - function initializeMultisig(bytes[] memory signers, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ + }␊ + ␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ + public␊ + onlyEntryPointOrSelf␊ + {␊ + _setSignerWeights(signers, weights);␊ }␊ ␊ function addSigners(bytes[] memory signers) public onlyEntryPointOrSelf {␊ @@ -2722,28 +9765,34 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ ␊ // The following functions are overrides required by Solidity.␊ ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerMultisig is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisig)␊ + // IMPORTANT: Make sure SignerMultisigWeightedUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigWeightedUpgradeable)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -2751,36 +9800,34 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerMultisigWeighted named +## Account with SignerMultisigWeighted named upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisigWeighted is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted {␊ + contract CustomAccountWithSignerMultisigWeighted is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("CustomAccount with SignerMultisigWeighted", "1") {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisigWeighted(bytes[] memory signers, uint256[] memory weights, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setSignerWeights(signers, weights);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ }␊ ␊ - function setSignerWeights(bytes[] memory signers, uint256[] memory weights)␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ public␊ onlyEntryPointOrSelf␊ {␊ @@ -2795,27 +9842,27 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ }␊ ` -## Account with SignerMultisigWeighted with ERC1271 +## Account with SignerMultisigWeighted with ERC1271 upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisigWeightedERC1271 is Initializable, Account, IERC1271, MultiSignerERC7913Weighted {␊ + contract CustomAccountWithSignerMultisigWeightedERC1271 is Initializable, Account, IERC1271, MultiSignerERC7913WeightedUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() {␊ _disableInitializers();␊ }␊ @@ -2829,16 +9876,14 @@ Generated by [AVA](https://avajs.dev). return _rawSignatureValidation(hash, signature) ? IERC1271.isValidSignature.selector : bytes4(0xffffffff);␊ }␊ ␊ - function initializeMultisigWeighted(bytes[] memory signers, uint256[] memory weights, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setSignerWeights(signers, weights);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ }␊ ␊ - function setSignerWeights(bytes[] memory signers, uint256[] memory weights)␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ public␊ onlyEntryPointOrSelf␊ {␊ @@ -2853,44 +9898,42 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ }␊ ` -## Account with SignerMultisigWeighted with ERC7739 +## Account with SignerMultisigWeighted with ERC7739 upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisigWeightedERC7739 is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted {␊ + contract CustomAccountWithSignerMultisigWeightedERC7739 is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor()␊ EIP712("CustomAccount with SignerMultisigWeightedERC7739", "1")␊ {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisigWeighted(bytes[] memory signers, uint256[] memory weights, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setSignerWeights(signers, weights);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ }␊ ␊ - function setSignerWeights(bytes[] memory signers, uint256[] memory weights)␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ public␊ onlyEntryPointOrSelf␊ {␊ @@ -2905,45 +9948,43 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ }␊ ` -## Account with SignerMultisigWeighted with ERC721Holder +## Account with SignerMultisigWeighted with ERC721Holder upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisigWeightedERC721Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted, ERC721Holder {␊ + contract CustomAccountWithSignerMultisigWeightedERC721Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable, ERC721Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor()␊ EIP712("CustomAccount with SignerMultisigWeightedERC721Holder", "1")␊ {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisigWeighted(bytes[] memory signers, uint256[] memory weights, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setSignerWeights(signers, weights);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ }␊ ␊ - function setSignerWeights(bytes[] memory signers, uint256[] memory weights)␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ public␊ onlyEntryPointOrSelf␊ {␊ @@ -2958,45 +9999,43 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ }␊ ` -## Account with SignerMultisigWeighted with ERC1155Holder +## Account with SignerMultisigWeighted with ERC1155Holder upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisigWeightedERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted, ERC1155Holder {␊ + contract CustomAccountWithSignerMultisigWeightedERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor()␊ EIP712("CustomAccount with SignerMultisigWeightedERC1155Holder", "1")␊ {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisigWeighted(bytes[] memory signers, uint256[] memory weights, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setSignerWeights(signers, weights);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ }␊ ␊ - function setSignerWeights(bytes[] memory signers, uint256[] memory weights)␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ public␊ onlyEntryPointOrSelf␊ {␊ @@ -3011,46 +10050,44 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ }␊ ` -## Account with SignerMultisigWeighted with ERC721Holder and ERC1155Holder +## Account with SignerMultisigWeighted with ERC721Holder and ERC1155Holder upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract CustomAccountWithSignerMultisigWeightedERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted, ERC721Holder, ERC1155Holder {␊ + contract CustomAccountWithSignerMultisigWeightedERC721HolderERC1155Holder is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor()␊ EIP712("CustomAccount with SignerMultisigWeightedERC721HolderERC1155Holder", "1")␊ {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisigWeighted(bytes[] memory signers, uint256[] memory weights, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setSignerWeights(signers, weights);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ }␊ ␊ - function setSignerWeights(bytes[] memory signers, uint256[] memory weights)␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ public␊ onlyEntryPointOrSelf␊ {␊ @@ -3065,43 +10102,41 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ }␊ ` -## Account with SignerMultisigWeighted with ERC7821 Execution +## Account with SignerMultisigWeighted with ERC7821 Execution upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {ERC7821} from "@openzeppelin/community-contracts/account/extensions/ERC7821.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913Weighted, ERC7821 {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, MultiSignerERC7913WeightedUpgradeable, ERC7821 {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisigWeighted(bytes[] memory signers, uint256[] memory weights, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setSignerWeights(signers, weights);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ }␊ ␊ - function setSignerWeights(bytes[] memory signers, uint256[] memory weights)␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ public␊ onlyEntryPointOrSelf␊ {␊ @@ -3116,7 +10151,7 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ ␊ @@ -3131,26 +10166,26 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerMultisigWeighted with ERC7579 +## Account with SignerMultisigWeighted with ERC7579 upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ - import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, MultiSignerERC7913Weighted {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, MultiSignerERC7913WeightedUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ @@ -3158,25 +10193,23 @@ Generated by [AVA](https://avajs.dev). function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ - function initializeMultisigWeighted(bytes[] memory signers, uint256[] memory weights, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setSignerWeights(signers, weights);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ }␊ ␊ - function setSignerWeights(bytes[] memory signers, uint256[] memory weights)␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ public␊ onlyEntryPointOrSelf␊ {␊ @@ -3191,7 +10224,7 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ ␊ @@ -3199,20 +10232,20 @@ Generated by [AVA](https://avajs.dev). ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerMultisigWeighted is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisigWeighted)␊ + // IMPORTANT: Make sure SignerMultisigWeightedUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigWeightedUpgradeable)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -3220,39 +10253,37 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerMultisigWeighted with ERC7579 with ERC1271 +## Account with SignerMultisigWeighted with ERC7579 with ERC1271 upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ - import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, IERC1271, AccountERC7579, MultiSignerERC7913Weighted {␊ + contract MyAccount is Initializable, Account, IERC1271, AccountERC7579Upgradeable, MultiSignerERC7913WeightedUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() {␊ _disableInitializers();␊ }␊ ␊ - function initializeMultisigWeighted(bytes[] memory signers, uint256[] memory weights, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setSignerWeights(signers, weights);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ }␊ ␊ - function setSignerWeights(bytes[] memory signers, uint256[] memory weights)␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ public␊ onlyEntryPointOrSelf␊ {␊ @@ -3267,7 +10298,7 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ ␊ @@ -3275,7 +10306,7 @@ Generated by [AVA](https://avajs.dev). ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ @@ -3284,20 +10315,20 @@ Generated by [AVA](https://avajs.dev). function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(IERC1271, AccountERC7579)␊ + override(IERC1271, AccountERC7579Upgradeable)␊ returns (bytes4)␊ {␊ return super.isValidSignature(hash, signature);␊ }␊ ␊ - // IMPORTANT: Make sure SignerMultisigWeighted is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisigWeighted)␊ + // IMPORTANT: Make sure SignerMultisigWeightedUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigWeightedUpgradeable)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -3305,26 +10336,26 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerMultisigWeighted with ERC7579 with ERC7739 +## Account with SignerMultisigWeighted with ERC7579 with ERC7739 upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ - import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579, MultiSignerERC7913Weighted {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Upgradeable, MultiSignerERC7913WeightedUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ @@ -3332,25 +10363,23 @@ Generated by [AVA](https://avajs.dev). function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ - function initializeMultisigWeighted(bytes[] memory signers, uint256[] memory weights, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setSignerWeights(signers, weights);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ }␊ ␊ - function setSignerWeights(bytes[] memory signers, uint256[] memory weights)␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ public␊ onlyEntryPointOrSelf␊ {␊ @@ -3365,7 +10394,7 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ ␊ @@ -3373,20 +10402,20 @@ Generated by [AVA](https://avajs.dev). ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerMultisigWeighted is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisigWeighted)␊ + // IMPORTANT: Make sure SignerMultisigWeightedUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigWeightedUpgradeable)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ @@ -3394,27 +10423,27 @@ Generated by [AVA](https://avajs.dev). }␊ ` -## Account with SignerMultisigWeighted with ERC7579 hooks +## Account with SignerMultisigWeighted with ERC7579 hooks upgradeable transparent > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ pragma solidity ^0.8.27;␊ ␊ - import {AbstractSigner} from "@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol";␊ - import {Account} from "@openzeppelin/community-contracts/account/Account.sol";␊ - import {AccountERC7579} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";␊ - import {AccountERC7579Hooked} from "@openzeppelin/community-contracts/account/extensions/AccountERC7579Hooked.sol";␊ + import {AbstractSigner} from "@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol";␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {AccountERC7579HookedUpgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579HookedUpgradeable.sol";␊ + import {AccountERC7579Upgradeable} from "@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol";␊ import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ - import {ERC7739} from "@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol";␊ - import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ - import {MultiSignerERC7913} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol";␊ - import {MultiSignerERC7913Weighted} from "@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {MultiSignerERC7913Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913Upgradeable.sol";␊ + import {MultiSignerERC7913WeightedUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/MultiSignerERC7913WeightedUpgradeable.sol";␊ import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol";␊ ␊ - /// @custom:oz-upgrades-unsafe-allow constructor␊ - contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579Hooked, MultiSignerERC7913Weighted {␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, AccountERC7579HookedUpgradeable, MultiSignerERC7913WeightedUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ constructor() EIP712("MyAccount", "1") {␊ _disableInitializers();␊ }␊ @@ -3422,25 +10451,23 @@ Generated by [AVA](https://avajs.dev). function isValidSignature(bytes32 hash, bytes calldata signature)␊ public␊ view␊ - override(AccountERC7579, ERC7739)␊ + override(AccountERC7579Upgradeable, ERC7739)␊ returns (bytes4)␊ {␊ // ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).␊ // If the returned value is 0xffffffff, fallback to ERC-7579 validation.␊ bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);␊ - return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;␊ + return erc7739magic == bytes4(0xffffffff) ? AccountERC7579Upgradeable.isValidSignature(hash, signature) : erc7739magic;␊ }␊ ␊ - function initializeMultisigWeighted(bytes[] memory signers, uint256[] memory weights, uint256 threshold)␊ + function initialize(bytes[] memory signers, uint64[] memory weights, uint64 threshold)␊ public␊ initializer␊ {␊ - _addSigners(signers);␊ - _setSignerWeights(signers, weights);␊ - _setThreshold(threshold);␊ + __MultiSignerERC7913Weighted_init(signers, weights, threshold);␊ }␊ ␊ - function setSignerWeights(bytes[] memory signers, uint256[] memory weights)␊ + function setSignerWeights(bytes[] memory signers, uint64[] memory weights)␊ public␊ onlyEntryPointOrSelf␊ {␊ @@ -3455,7 +10482,7 @@ Generated by [AVA](https://avajs.dev). _removeSigners(signers);␊ }␊ ␊ - function setThreshold(uint256 threshold) public onlyEntryPointOrSelf {␊ + function setThreshold(uint64 threshold) public onlyEntryPointOrSelf {␊ _setThreshold(threshold);␊ }␊ ␊ @@ -3463,20 +10490,20 @@ Generated by [AVA](https://avajs.dev). ␊ function _validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash)␊ internal␊ - override(Account, AccountERC7579)␊ + override(Account, AccountERC7579Upgradeable)␊ returns (uint256)␊ {␊ return super._validateUserOp(userOp, userOpHash);␊ }␊ ␊ - // IMPORTANT: Make sure SignerMultisigWeighted is most derived than AccountERC7579␊ - // in the inheritance chain (i.e. contract ... is AccountERC7579, ..., SignerMultisigWeighted)␊ + // IMPORTANT: Make sure SignerMultisigWeightedUpgradeable is most derived than AccountERC7579Upgradeable␊ + // in the inheritance chain (i.e. contract ... is AccountERC7579Upgradeable, ..., SignerMultisigWeightedUpgradeable)␊ // to ensure the correct order of function resolution.␊ - // AccountERC7579 returns false for \`_rawSignatureValidation\`␊ + // AccountERC7579Upgradeable returns false for _rawSignatureValidation␊ function _rawSignatureValidation(bytes32 hash, bytes calldata signature)␊ internal␊ view␊ - override(MultiSignerERC7913, AbstractSigner, AccountERC7579)␊ + override(MultiSignerERC7913Upgradeable, AbstractSigner, AccountERC7579Upgradeable)␊ returns (bool)␊ {␊ return super._rawSignatureValidation(hash, signature);␊ diff --git a/packages/core/solidity/src/account.test.ts.snap b/packages/core/solidity/src/account.test.ts.snap index 80eddb0a2..8539b23ac 100644 Binary files a/packages/core/solidity/src/account.test.ts.snap and b/packages/core/solidity/src/account.test.ts.snap differ diff --git a/packages/core/solidity/src/account.ts b/packages/core/solidity/src/account.ts index da79a0809..8d9efcb3a 100644 --- a/packages/core/solidity/src/account.ts +++ b/packages/core/solidity/src/account.ts @@ -2,9 +2,18 @@ import { ContractBuilder } from './contract'; import type { Contract } from './contract'; import { defineFunctions } from './utils/define-functions'; import { printContract } from './print'; +import { makeUpgradeable } from './helpers'; import { defaults as commonDefaults, withCommonDefaults, type CommonOptions } from './common-options'; import { setInfo } from './set-info'; -import { addSigner, signerFunctions, signers, type SignerOptions } from './signer'; +import { + addLockingConstructorAllowReachable, + addSigner, + signerArgs, + signerFunctions, + signers, + type SignerOptions, +} from './signer'; +import { setUpgradeableAccount } from './set-upgradeable'; export const defaults: Required = { ...commonDefaults, @@ -53,13 +62,13 @@ export function printAccount(opts: AccountOptions = defaults): string { export function buildAccount(opts: AccountOptions): Contract { const allOpts = withDefaults(opts); - allOpts.upgradeable = false; // Upgradeability is not yet available for the community contracts allOpts.access = false; // Access control options are not used for Account const c = new ContractBuilder(allOpts.name); addParents(c, allOpts); overrideRawSignatureValidation(c, allOpts); + setUpgradeableAccount(c, allOpts.upgradeable); setInfo(c, allOpts.info); if (opts.ERC7579Modules) { @@ -76,7 +85,7 @@ function addParents(c: ContractBuilder, opts: AccountOptions): void { // Base c.addParent({ name: 'Account', - path: `@openzeppelin/community-contracts/account/Account.sol`, + path: `@openzeppelin/contracts/account/Account.sol`, }); c.addOverride({ name: 'Account' }, functions._validateUserOp); @@ -85,7 +94,8 @@ function addParents(c: ContractBuilder, opts: AccountOptions): void { // Extensions addSignatureValidation(c, opts); addERC7579Modules(c, opts); - addSigner(c, opts.signer ?? false); + addSigner(c, opts.signer ?? false, opts.upgradeable ?? false); + addSignerInitializer(c, opts); addMultisigFunctions(c, opts); addBatchedExecution(c, opts); addERC721Holder(c, opts); @@ -97,7 +107,7 @@ function addSignatureValidation(c: ContractBuilder, opts: AccountOptions) { case 'ERC7739': c.addParent({ name: 'ERC7739', - path: '@openzeppelin/community-contracts/utils/cryptography/ERC7739.sol', + path: '@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol', }); break; case 'ERC1271': @@ -139,7 +149,7 @@ function addBatchedExecution(c: ContractBuilder, opts: AccountOptions): void { if (!opts.batchedExecution || !!opts.ERC7579Modules) return; c.addParent({ name: 'ERC7821', - path: '@openzeppelin/community-contracts/account/extensions/ERC7821.sol', + path: '@openzeppelin/contracts/account/extensions/draft-ERC7821.sol', }); c.addOverride({ name: 'ERC7821' }, functions._erc7821AuthorizedExecutor); c.setFunctionBody( @@ -150,30 +160,113 @@ function addBatchedExecution(c: ContractBuilder, opts: AccountOptions): void { function addERC7579Modules(c: ContractBuilder, opts: AccountOptions): void { if (!opts.ERC7579Modules) return; + + // Base AccountERC7579 account (upgradeable or not) + const name = makeUpgradeable('AccountERC7579', opts.upgradeable); + c.addParent({ - name: opts.ERC7579Modules, - path: `@openzeppelin/community-contracts/account/extensions/${opts.ERC7579Modules}.sol`, + name: makeUpgradeable(opts.ERC7579Modules, opts.upgradeable), + path: makeUpgradeable( + `@openzeppelin/contracts/account/extensions/draft-${opts.ERC7579Modules}.sol`, + opts.upgradeable, + ), }); if (opts.ERC7579Modules !== 'AccountERC7579') { c.addImportOnly({ - name: 'AccountERC7579', - path: `@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol`, + name: makeUpgradeable('AccountERC7579', opts.upgradeable), + path: makeUpgradeable('@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol', opts.upgradeable), }); } - c.addOverride({ name: 'AccountERC7579' }, functions.isValidSignature); - c.addOverride({ name: 'AccountERC7579' }, functions._validateUserOp); - if (opts.signatureValidation !== 'ERC7739') return; - c.addOverride({ name: 'ERC7739' }, functions.isValidSignature); - c.setFunctionBody( - [ - '// ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).', - '// If the returned value is 0xffffffff, fallback to ERC-7579 validation.', - 'bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);', - 'return erc7739magic == bytes4(0xffffffff) ? AccountERC7579.isValidSignature(hash, signature) : erc7739magic;', - ], - functions.isValidSignature, - ); + // Accounts that use ERC7579 without a signer must be constructed with at least one module (executor of validation) + if (!opts.signer) { + const args = [ + { type: 'uint256', name: 'moduleTypeId' }, + { type: 'address', name: 'module' }, + { type: 'bytes calldata', name: 'initData' }, + ]; + const body = [ + 'require(moduleTypeId == MODULE_TYPE_VALIDATOR || moduleTypeId == MODULE_TYPE_EXECUTOR);', + '_installModule(moduleTypeId, module, initData);', + ]; + if (opts.upgradeable) { + c.addParent({ + name: 'Initializable', + path: '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol', + }); + addLockingConstructorAllowReachable(c); + + const fn = { name: 'initialize', kind: 'public' as const, args }; + c.addModifier('initializer', fn); + c.setFunctionBody(body, fn); + } else { + for (const arg of args) c.addConstructorArgument(arg); + for (const line of body) c.addConstructorCode(line); + } + } + + // isValidSignature override + c.addOverride({ name }, functions.isValidSignature); + if (opts.signatureValidation === 'ERC7739') { + c.addOverride({ name: 'ERC7739' }, functions.isValidSignature); + c.setFunctionBody( + [ + '// ERC-7739 can return the ERC-1271 magic value, 0xffffffff (invalid) or 0x77390001 (detection).', + '// If the returned value is 0xffffffff, fallback to ERC-7579 validation.', + 'bytes4 erc7739magic = ERC7739.isValidSignature(hash, signature);', + `return erc7739magic == bytes4(0xffffffff) ? ${name}.isValidSignature(hash, signature) : erc7739magic;`, + ], + functions.isValidSignature, + ); + } + + // _validateUserOp override + c.addOverride({ name }, functions._validateUserOp); +} + +function addSignerInitializer(c: ContractBuilder, opts: AccountOptions): void { + if (opts.upgradeable) { + if (!opts.signer) { + addLockingConstructorAllowReachable(c); + } + return; // Initializer added in signer.ts + } + if (!opts.signer || opts.signer === 'ERC7702') return; // No initialization required + + c.addParent({ + name: 'Initializable', + path: opts.upgradeable + ? '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol' + : '@openzeppelin/contracts/proxy/utils/Initializable.sol', + }); + + addLockingConstructorAllowReachable(c, [ + '// Accounts are typically deployed and initialized as clones during their first user op,', + '// therefore, initializers are disabled for the implementation contract', + ]); + + const fn = { name: 'initialize', kind: 'public' as const, args: signerArgs[opts.signer] }; + c.addModifier('initializer', fn); + + switch (opts.signer) { + case 'Multisig': + c.addFunctionCode(`_addSigners(${signerArgs[opts.signer][0]!.name});`, fn); + c.addFunctionCode(`_setThreshold(${signerArgs[opts.signer][1]!.name});`, fn); + break; + case 'MultisigWeighted': + c.addFunctionCode(`_addSigners(${signerArgs[opts.signer][0]!.name});`, fn); + c.addFunctionCode( + `_setSignerWeights(${signerArgs[opts.signer][0]!.name}, ${signerArgs[opts.signer][1]!.name});`, + fn, + ); + c.addFunctionCode(`_setThreshold(${signerArgs[opts.signer][2]!.name});`, fn); + break; + case 'ECDSA': + case 'P256': + case 'RSA': + c.addFunctionCode(`_setSigner(${signerArgs[opts.signer].map(({ name }) => name).join(', ')});`, fn); + break; + } } function addMultisigFunctions(c: ContractBuilder, opts: AccountOptions): void { @@ -222,24 +315,31 @@ function overrideRawSignatureValidation(c: ContractBuilder, opts: AccountOptions // Disambiguate between Signer and AccountERC7579 if (opts.signer && opts.ERC7579Modules) { + const accountName = makeUpgradeable('AccountERC7579', opts.upgradeable); + const signerName = makeUpgradeable(`Signer${opts.signer}`, opts.upgradeable); + c.addImportOnly({ name: 'AbstractSigner', - path: '@openzeppelin/community-contracts/utils/cryptography/AbstractSigner.sol', + path: '@openzeppelin/contracts/utils/cryptography/signers/AbstractSigner.sol', }); c.addOverride({ name: 'AbstractSigner' }, signerFunctions._rawSignatureValidation); - c.addOverride({ name: 'AccountERC7579' }, signerFunctions._rawSignatureValidation); + c.addOverride({ name: accountName }, signerFunctions._rawSignatureValidation); c.setFunctionComments( [ - `// IMPORTANT: Make sure Signer${opts.signer} is most derived than AccountERC7579`, - `// in the inheritance chain (i.e. contract ... is AccountERC7579, ..., Signer${opts.signer})`, + `// IMPORTANT: Make sure ${signerName} is most derived than ${accountName}`, + `// in the inheritance chain (i.e. contract ... is ${accountName}, ..., ${signerName})`, '// to ensure the correct order of function resolution.', - '// AccountERC7579 returns false for `_rawSignatureValidation`', + `// ${accountName} returns false for _rawSignatureValidation`, ], signerFunctions._rawSignatureValidation, ); + // Base override for `_rawSignatureValidation` given MultiSignerERC7913Weighted is MultiSignerERC7913 if (opts.signer === 'MultisigWeighted') { - c.addImportOnly(signers.Multisig); + c.addImportOnly({ + name: makeUpgradeable(signers.Multisig.name, opts.upgradeable), + path: makeUpgradeable(signers.Multisig.path, opts.upgradeable), + }); } } } @@ -283,13 +383,13 @@ const functions = { }, setThreshold: { kind: 'public' as const, - args: [{ name: 'threshold', type: 'uint256' }], + args: [{ name: 'threshold', type: 'uint64' }], }, setSignerWeights: { kind: 'public' as const, args: [ { name: 'signers', type: 'bytes[] memory' }, - { name: 'weights', type: 'uint256[] memory' }, + { name: 'weights', type: 'uint64[] memory' }, ], }, }), diff --git a/packages/core/solidity/src/contract.ts b/packages/core/solidity/src/contract.ts index 6ed276124..d3a89333c 100644 --- a/packages/core/solidity/src/contract.ts +++ b/packages/core/solidity/src/contract.ts @@ -9,8 +9,11 @@ export interface Contract { functions: ContractFunction[]; constructorCode: string[]; constructorArgs: FunctionArgument[]; + constructorComments: string[]; variables: string[]; - upgradeable: boolean; + shouldAutoTranspileImports: boolean; + shouldInstallContractsUpgradeable: boolean; + shouldUseUpgradesPluginsForProxyDeployment: boolean; } export type Value = string | number | { lit: string } | { note: string; value: Value }; @@ -75,13 +78,17 @@ export interface NatspecTag { export class ContractBuilder implements Contract { readonly name: string; license: string = 'MIT'; - upgradeable = false; + + shouldAutoTranspileImports: boolean = false; + shouldInstallContractsUpgradeable: boolean = false; + shouldUseUpgradesPluginsForProxyDeployment: boolean = false; readonly using: Using[] = []; readonly natspecTags: NatspecTag[] = []; readonly constructorArgs: FunctionArgument[] = []; readonly constructorCode: string[] = []; + readonly constructorComments: string[] = []; readonly variableSet: Set = new Set(); private parentMap: Map = new Map(); @@ -180,6 +187,15 @@ export class ContractBuilder implements Contract { this.constructorCode.push(code); } + addConstructorComment(comment: string) { + if (this.shouldAutoTranspileImports) { + throw new Error( + 'Constructor comments are not supported when `shouldAutoTranspileImports` is true, since constructor will be transformed into an initializer', + ); + } + this.constructorComments.push(comment); + } + addFunctionCode(code: string, baseFn: BaseFunction, mutability?: FunctionMutability) { const fn = this.addFunction(baseFn); if (fn.final) { diff --git a/packages/core/solidity/src/generate/account.ts b/packages/core/solidity/src/generate/account.ts index 27c4adda3..685e23bb8 100644 --- a/packages/core/solidity/src/generate/account.ts +++ b/packages/core/solidity/src/generate/account.ts @@ -1,5 +1,6 @@ import type { AccountOptions } from '../account'; import { infoOptions } from '../set-info'; +import { upgradeableOptions } from '../set-upgradeable'; import { generateAlternatives } from './alternatives'; const account = { @@ -11,7 +12,7 @@ const account = { batchedExecution: [false, true] as const, ERC7579Modules: [false, 'AccountERC7579', 'AccountERC7579Hooked'] as const, access: [false] as const, - upgradeable: [false] as const, + upgradeable: upgradeableOptions, info: infoOptions, }; diff --git a/packages/core/solidity/src/helpers.ts b/packages/core/solidity/src/helpers.ts new file mode 100644 index 000000000..fe1d92bfe --- /dev/null +++ b/packages/core/solidity/src/helpers.ts @@ -0,0 +1,31 @@ +// Use posix to ensure forward slashes on all platforms +import { posix as path } from 'path'; +import type { CommonOptions } from './common-options'; + +// If upgradeable is true-ish, translate a contract name or contract path into its corresponding upgradeable variant. +// Otherwise, return the input unmodified. +// +// Example: +// - makeUpgradeable('AccountERC7579', false) == 'AccountERC7579' +// - makeUpgradeable('AccountERC7579', 'uups') == 'AccountERC7579Upgradeable' +// - makeUpgradeable('@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol', false) == '@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol' +// - makeUpgradeable('@openzeppelin/contracts/account/extensions/draft-AccountERC7579.sol', 'uups') == '@openzeppelin/contracts-upgradeable/account/extensions/draft-AccountERC7579Upgradeable.sol' +export function makeUpgradeable(input: string, upgradeable: CommonOptions['upgradeable'] = false): string { + switch (upgradeable) { + case false: + return input; + case 'uups': + case 'transparent': { + const { dir, name, ext } = path.parse(input); + return path.format({ + dir: dir.replace('/contracts/', '/contracts-upgradeable/'), + name: name + 'Upgradeable', + ext, + }); + } + default: { + const _: never = upgradeable; + throw new Error('Unknown upgradeable option'); + } + } +} diff --git a/packages/core/solidity/src/options.ts b/packages/core/solidity/src/options.ts index 6e800715f..d2fbeba18 100644 --- a/packages/core/solidity/src/options.ts +++ b/packages/core/solidity/src/options.ts @@ -30,19 +30,19 @@ export interface Options { } export interface Helpers extends Required { - upgradeable: boolean; + shouldUseInitializers: boolean; transformName: (name: ReferencedContract) => string; } export function withHelpers(contract: Contract, opts: Options = {}): Helpers { - const contractUpgradeable = contract.upgradeable; + const shouldAutoTranspileImports = contract.shouldAutoTranspileImports; const transformName = (n: ReferencedContract) => - contractUpgradeable && inferTranspiled(n) ? upgradeableName(n.name) : n.name; + shouldAutoTranspileImports && inferTranspiled(n) ? upgradeableName(n.name) : n.name; return { - upgradeable: contractUpgradeable, + shouldUseInitializers: shouldAutoTranspileImports, transformName, transformImport: p1 => { - const p2 = contractUpgradeable && inferTranspiled(p1) ? upgradeableImport(p1) : p1; + const p2 = shouldAutoTranspileImports && inferTranspiled(p1) ? upgradeableImport(p1) : p1; return opts.transformImport?.(p2) ?? p2; }, }; diff --git a/packages/core/solidity/src/print.ts b/packages/core/solidity/src/print.ts index 7585baac7..fbf484151 100644 --- a/packages/core/solidity/src/print.ts +++ b/packages/core/solidity/src/print.ts @@ -81,24 +81,24 @@ function printConstructor(contract: Contract, helpers: Helpers): Lines[] { const hasParentParams = contract.parents.some(p => p.params.length > 0); const hasConstructorCode = contract.constructorCode.length > 0; const parentsWithInitializers = contract.parents.filter(hasInitializer); - if (hasParentParams || hasConstructorCode || (helpers.upgradeable && parentsWithInitializers.length > 0)) { + if (hasParentParams || hasConstructorCode || (helpers.shouldUseInitializers && parentsWithInitializers.length > 0)) { const parents = parentsWithInitializers.flatMap(p => printParentConstructor(p, helpers)); - const modifiers = helpers.upgradeable ? ['public initializer'] : parents; + const modifiers = helpers.shouldUseInitializers ? ['public initializer'] : parents; const args = contract.constructorArgs.map(a => printArgument(a, helpers)); - const body = helpers.upgradeable + const body = helpers.shouldUseInitializers ? spaceBetween( parents.map(p => p + ';'), contract.constructorCode, ) : contract.constructorCode; - const head = helpers.upgradeable ? 'function initialize' : 'constructor'; - const constructor = printFunction2([], head, args, modifiers, body); - if (!helpers.upgradeable) { - return constructor; + const head = helpers.shouldUseInitializers ? 'function initialize' : 'constructor'; + const ctor = printFunction2(contract.constructorComments, head, args, modifiers, body); + if (!helpers.shouldUseInitializers) { + return ctor; } else { - return spaceBetween(DISABLE_INITIALIZERS, constructor); + return spaceBetween(DISABLE_INITIALIZERS, ctor); } - } else if (!helpers.upgradeable) { + } else if (!helpers.shouldUseInitializers) { return []; } else { return DISABLE_INITIALIZERS; @@ -139,7 +139,7 @@ function sortedFunctions(contract: Contract): SortedFunctions { } function printParentConstructor({ contract, params }: Parent, helpers: Helpers): [] | [string] { - const useTranspiled = helpers.upgradeable && inferTranspiled(contract); + const useTranspiled = helpers.shouldUseInitializers && inferTranspiled(contract); const fn = useTranspiled ? `__${contract.name}_init` : contract.name; if (useTranspiled || params.length > 0) { return [fn + '(' + params.map(printValue).join(', ') + ')']; diff --git a/packages/core/solidity/src/set-upgradeable.ts b/packages/core/solidity/src/set-upgradeable.ts index bdd72198d..361184145 100644 --- a/packages/core/solidity/src/set-upgradeable.ts +++ b/packages/core/solidity/src/set-upgradeable.ts @@ -11,16 +11,19 @@ function setUpgradeableBase( c: ContractBuilder, upgradeable: Upgradeable, restrictAuthorizeUpgradeWhenUUPS: () => void, + onlyUseUpgradeableInitializableAndUUPS: boolean = false, ) { if (upgradeable === false) { return; } - c.upgradeable = true; + c.shouldAutoTranspileImports = !onlyUseUpgradeableInitializableAndUUPS; + c.shouldInstallContractsUpgradeable = true; + c.shouldUseUpgradesPluginsForProxyDeployment = true; c.addParent({ name: 'Initializable', - path: '@openzeppelin/contracts/proxy/utils/Initializable.sol', + path: `@openzeppelin/${onlyUseUpgradeableInitializableAndUUPS ? 'contracts-upgradeable' : 'contracts'}/proxy/utils/Initializable.sol`, }); switch (upgradeable) { @@ -31,7 +34,7 @@ function setUpgradeableBase( restrictAuthorizeUpgradeWhenUUPS(); const UUPSUpgradeable = { name: 'UUPSUpgradeable', - path: '@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol', + path: `@openzeppelin/${onlyUseUpgradeableInitializableAndUUPS ? 'contracts-upgradeable' : 'contracts'}/proxy/utils/UUPSUpgradeable.sol`, }; c.addParent(UUPSUpgradeable); c.addOverride(UUPSUpgradeable, functions._authorizeUpgrade); @@ -58,6 +61,22 @@ export function setUpgradeableGovernor(c: ContractBuilder, upgradeable: Upgradea }); } +export function setUpgradeableAccount(c: ContractBuilder, upgradeable: Upgradeable) { + if (upgradeable === false) { + return; + } + setUpgradeableBase( + c, + upgradeable, + () => { + c.addModifier('onlyEntryPointOrSelf', functions._authorizeUpgrade); + }, + true, // account.ts handles usage of transpiled imports (when needed) rather than using helpers. + ); + c.shouldInstallContractsUpgradeable = true; + c.shouldUseUpgradesPluginsForProxyDeployment = false; // this will eventually use a factory to deploy proxies +} + const functions = defineFunctions({ _authorizeUpgrade: { args: [{ name: 'newImplementation', type: 'address' }], diff --git a/packages/core/solidity/src/signer.ts b/packages/core/solidity/src/signer.ts index 09e2cd111..42e209a35 100644 --- a/packages/core/solidity/src/signer.ts +++ b/packages/core/solidity/src/signer.ts @@ -1,112 +1,128 @@ import type { ContractBuilder } from './contract'; +import { OptionsError } from './error'; +import type { Upgradeable } from './set-upgradeable'; +import { makeUpgradeable } from './helpers'; import { defineFunctions } from './utils/define-functions'; export const SignerOptions = [false, 'ERC7702', 'ECDSA', 'P256', 'RSA', 'Multisig', 'MultisigWeighted'] as const; export type SignerOptions = (typeof SignerOptions)[number]; -export function addSigner(c: ContractBuilder, signer: SignerOptions): void { +export function addSigner(c: ContractBuilder, signer: SignerOptions, upgradeable: Upgradeable): void { if (!signer) return; - c.addParent(signers[signer]); - c.addOverride( - { name: signer === 'MultisigWeighted' ? signers.Multisig.name : signers[signer].name }, - signerFunctions._rawSignatureValidation, - ); - - // ERC-7702 doesn't require initialization - if (signer === 'ERC7702') return; - - c.addParent({ - name: 'Initializable', - path: '@openzeppelin/contracts/proxy/utils/Initializable.sol', - }); - - // Add locking constructor - c.addNatspecTag('@custom:oz-upgrades-unsafe-allow', 'constructor'); - c.addConstructorCode(`_disableInitializers();`); - - // Add initializer - const fn = signerFunctions[`initialize${signer}`]; - c.addModifier('initializer', fn); + const signerName = signer === 'MultisigWeighted' ? signers.Multisig.name : signers[signer].name; + c.addOverride({ name: makeUpgradeable(signerName, upgradeable) }, signerFunctions._rawSignatureValidation); switch (signer) { - case 'Multisig': - c.addFunctionCode(`_addSigners(${fn.args[0]!.name});`, fn); - c.addFunctionCode(`_setThreshold(${fn.args[1]!.name});`, fn); - break; - case 'MultisigWeighted': - c.addFunctionCode(`_addSigners(${fn.args[0]!.name});`, fn); - c.addFunctionCode(`_setSignerWeights(${fn.args[0]!.name}, ${fn.args[1]!.name});`, fn); - c.addFunctionCode(`_setThreshold(${fn.args[2]!.name});`, fn); + case 'ERC7702': + c.addParent(signers[signer]); + if (upgradeable) { + throw new OptionsError({ + erc7702: 'EOAs can upgrade by redelegating to a new account', + upgradeable: 'EOAs can upgrade by redelegating to a new account', + }); + } break; case 'ECDSA': case 'P256': case 'RSA': - c.addFunctionCode(`_setSigner(${fn.args.map(({ name }) => name).join(', ')});`, fn); + case 'Multisig': + case 'MultisigWeighted': { + if (upgradeable) { + c.addParent({ + name: 'Initializable', + path: '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol', + }); + addLockingConstructorAllowReachable(c); + + const fn = { name: 'initialize', kind: 'public' as const, args: signerArgs[signer] }; + c.addModifier('initializer', fn); + c.addFunctionCode(`__${signers[signer].name}_init(${signerArgs[signer].map(arg => arg.name).join(', ')});`, fn); + c.addParent({ + name: `${signers[signer].name}Upgradeable`, + path: makeUpgradeable(signers[signer].path, upgradeable), + }); + } else { + signerArgs[signer].forEach(arg => c.addConstructorArgument(arg)); + c.addParent( + signers[signer], + signerArgs[signer].map(arg => ({ lit: arg.name })), + ); + } + + break; + } + } +} + +/** + * Adds a locking constructor that disables initializers and annotates it to allow reachable constructors during Upgrades Plugins validations, + * which includes constructors in parent contracts. + * + * IMPORTANT: If a locking constructor is already present, it will not be added again, even if the body comments are different. + * + * @param c The contract builder. + * @param bodyComments Optional comments to add to the constructor body, before disabling initializers. + */ +export function addLockingConstructorAllowReachable(c: ContractBuilder, bodyComments?: string[]): void { + const disableInitializers = '_disableInitializers();'; + + if (!c.constructorCode.includes(disableInitializers)) { + c.addConstructorComment('/// @custom:oz-upgrades-unsafe-allow-reachable constructor'); + bodyComments?.forEach(comment => c.addConstructorCode(comment)); + c.addConstructorCode(disableInitializers); } } export const signers = { ERC7702: { name: 'SignerERC7702', - path: '@openzeppelin/community-contracts/utils/cryptography/SignerERC7702.sol', + path: '@openzeppelin/contracts/utils/cryptography/signers/SignerERC7702.sol', }, ECDSA: { name: 'SignerECDSA', - path: '@openzeppelin/community-contracts/utils/cryptography/SignerECDSA.sol', + path: '@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol', }, P256: { name: 'SignerP256', - path: '@openzeppelin/community-contracts/utils/cryptography/SignerP256.sol', + path: '@openzeppelin/contracts/utils/cryptography/signers/SignerP256.sol', }, RSA: { name: 'SignerRSA', - path: '@openzeppelin/community-contracts/utils/cryptography/SignerRSA.sol', + path: '@openzeppelin/contracts/utils/cryptography/signers/SignerRSA.sol', }, Multisig: { name: 'MultiSignerERC7913', - path: '@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913.sol', + path: '@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913.sol', }, MultisigWeighted: { name: 'MultiSignerERC7913Weighted', - path: '@openzeppelin/community-contracts/utils/cryptography/MultiSignerERC7913Weighted.sol', + path: '@openzeppelin/contracts/utils/cryptography/signers/MultiSignerERC7913Weighted.sol', }, }; +export const signerArgs: Record, { name: string; type: string }[]> = { + ECDSA: [{ name: 'signer', type: 'address' }], + P256: [ + { name: 'qx', type: 'bytes32' }, + { name: 'qy', type: 'bytes32' }, + ], + RSA: [ + { name: 'e', type: 'bytes memory' }, + { name: 'n', type: 'bytes memory' }, + ], + Multisig: [ + { name: 'signers', type: 'bytes[] memory' }, + { name: 'threshold', type: 'uint64' }, + ], + MultisigWeighted: [ + { name: 'signers', type: 'bytes[] memory' }, + { name: 'weights', type: 'uint64[] memory' }, + { name: 'threshold', type: 'uint64' }, + ], +}; + export const signerFunctions = defineFunctions({ - initializeECDSA: { - kind: 'public' as const, - args: [{ name: 'signer', type: 'address' }], - }, - initializeP256: { - kind: 'public' as const, - args: [ - { name: 'qx', type: 'bytes32' }, - { name: 'qy', type: 'bytes32' }, - ], - }, - initializeRSA: { - kind: 'public' as const, - args: [ - { name: 'e', type: 'bytes memory' }, - { name: 'n', type: 'bytes memory' }, - ], - }, - initializeMultisig: { - kind: 'public' as const, - args: [ - { name: 'signers', type: 'bytes[] memory' }, - { name: 'threshold', type: 'uint256' }, - ], - }, - initializeMultisigWeighted: { - kind: 'public' as const, - args: [ - { name: 'signers', type: 'bytes[] memory' }, - { name: 'weights', type: 'uint256[] memory' }, - { name: 'threshold', type: 'uint256' }, - ], - }, _rawSignatureValidation: { kind: 'internal' as const, args: [ diff --git a/packages/core/solidity/src/stablecoin.test.ts.md b/packages/core/solidity/src/stablecoin.test.ts.md index 9e9522d18..8aaaeb841 100644 --- a/packages/core/solidity/src/stablecoin.test.ts.md +++ b/packages/core/solidity/src/stablecoin.test.ts.md @@ -327,7 +327,7 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit 2d607bd␊ pragma solidity ^0.8.27;␊ ␊ import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊ @@ -362,7 +362,7 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit 2d607bd␊ pragma solidity ^0.8.27;␊ ␊ import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊ @@ -408,7 +408,7 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit 2d607bd␊ pragma solidity ^0.8.27;␊ ␊ import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊ @@ -588,7 +588,7 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 `// SPDX-License-Identifier: MIT␊ - // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit de17c8e␊ + // Compatible with OpenZeppelin Contracts ^5.4.0 and Community Contracts commit 2d607bd␊ pragma solidity ^0.8.27;␊ ␊ import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";␊ diff --git a/packages/core/solidity/src/stablecoin.test.ts.snap b/packages/core/solidity/src/stablecoin.test.ts.snap index af29ad69c..ab2244c77 100644 Binary files a/packages/core/solidity/src/stablecoin.test.ts.snap and b/packages/core/solidity/src/stablecoin.test.ts.snap differ diff --git a/packages/core/solidity/src/zip-foundry.test.ts b/packages/core/solidity/src/zip-foundry.test.ts index f35bf200b..527147d2f 100644 --- a/packages/core/solidity/src/zip-foundry.test.ts +++ b/packages/core/solidity/src/zip-foundry.test.ts @@ -6,6 +6,7 @@ import { zipFoundry } from './zip-foundry'; import { buildERC20 } from './erc20'; import { buildERC721 } from './erc721'; import { buildERC1155 } from './erc1155'; +import { buildAccount } from './account'; import { buildCustom } from './custom'; import { promises as fs } from 'fs'; import path from 'path'; @@ -117,6 +118,18 @@ test.serial('erc1155 transparent, ownable', async t => { await runTest(c, t, opts); }); +test.serial('account ecdsa', async t => { + const opts: GenericOptions = { kind: 'Account', name: 'My Account', signer: 'ECDSA' }; + const c = buildAccount(opts); + await runTest(c, t, opts); +}); + +test.serial('account ecdsa uups', async t => { + const opts: GenericOptions = { kind: 'Account', name: 'My Account', signer: 'ECDSA', upgradeable: 'uups' }; + const c = buildAccount(opts); + await runTest(c, t, opts); +}); + test.serial('custom basic', async t => { const opts: GenericOptions = { kind: 'Custom', name: 'My Contract' }; const c = buildCustom(opts); @@ -174,8 +187,9 @@ async function extractAndRunPackage(zip: JSZip, c: Contract, t: ExecutionContext const setGitUser = 'git init && git config user.email "test@test.test" && git config user.name "Test"'; const setup = 'bash setup.sh'; - const test = 'forge test' + (c.upgradeable ? ' --force' : ''); - const script = `forge script script/${c.name}.s.sol` + (c.upgradeable ? ' --force' : ''); + const test = 'forge test' + (c.shouldUseUpgradesPluginsForProxyDeployment ? ' --force' : ''); + const script = + `forge script script/${c.name}.s.sol` + (c.shouldUseUpgradesPluginsForProxyDeployment ? ' --force' : ''); const exec = (cmd: string) => util.promisify(child.exec)(cmd, { env: { ...process.env, NO_COLOR: '' } }); diff --git a/packages/core/solidity/src/zip-foundry.test.ts.md b/packages/core/solidity/src/zip-foundry.test.ts.md index 94009d407..dcccd0261 100644 --- a/packages/core/solidity/src/zip-foundry.test.ts.md +++ b/packages/core/solidity/src/zip-foundry.test.ts.md @@ -38,6 +38,7 @@ Generated by [AVA](https://avajs.dev). ␊ # Install OpenZeppelin Contracts␊ forge install OpenZeppelin/openzeppelin-contracts@vX.Y.Z --quiet␊ + ␊ ␊ # Remove unneeded Foundry template files␊ rm src/Counter.sol␊ @@ -54,6 +55,7 @@ Generated by [AVA](https://avajs.dev). echo "" >> remappings.txt␊ fi␊ echo "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/" >> remappings.txt␊ + ␊ ␊ # Perform initial git commit␊ git add .␊ @@ -233,8 +235,9 @@ Generated by [AVA](https://avajs.dev). # Initialize sample Foundry project␊ forge init --force --quiet␊ ␊ - # Install OpenZeppelin Contracts and Upgrades␊ + # Install OpenZeppelin Contracts␊ forge install OpenZeppelin/openzeppelin-contracts-upgradeable@vX.Y.Z --quiet␊ + # Install OpenZeppelin Foundry Upgrades␊ forge install OpenZeppelin/openzeppelin-foundry-upgrades --quiet␊ ␊ # Remove unneeded Foundry template files␊ @@ -253,7 +256,6 @@ Generated by [AVA](https://avajs.dev). fi␊ echo "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/" >> remappings.txt␊ echo "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/" >> remappings.txt␊ - ␊ # Add settings in foundry.toml␊ echo "" >> foundry.toml␊ echo "ffi = true" >> foundry.toml␊ @@ -475,8 +477,9 @@ Generated by [AVA](https://avajs.dev). # Initialize sample Foundry project␊ forge init --force --quiet␊ ␊ - # Install OpenZeppelin Contracts and Upgrades␊ + # Install OpenZeppelin Contracts␊ forge install OpenZeppelin/openzeppelin-contracts-upgradeable@vX.Y.Z --quiet␊ + # Install OpenZeppelin Foundry Upgrades␊ forge install OpenZeppelin/openzeppelin-foundry-upgrades --quiet␊ ␊ # Remove unneeded Foundry template files␊ @@ -495,7 +498,6 @@ Generated by [AVA](https://avajs.dev). fi␊ echo "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/" >> remappings.txt␊ echo "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/" >> remappings.txt␊ - ␊ # Add settings in foundry.toml␊ echo "" >> foundry.toml␊ echo "ffi = true" >> foundry.toml␊ @@ -666,8 +668,9 @@ Generated by [AVA](https://avajs.dev). # Initialize sample Foundry project␊ forge init --force --quiet␊ ␊ - # Install OpenZeppelin Contracts and Upgrades␊ + # Install OpenZeppelin Contracts␊ forge install OpenZeppelin/openzeppelin-contracts-upgradeable@vX.Y.Z --quiet␊ + # Install OpenZeppelin Foundry Upgrades␊ forge install OpenZeppelin/openzeppelin-foundry-upgrades --quiet␊ ␊ # Remove unneeded Foundry template files␊ @@ -686,7 +689,6 @@ Generated by [AVA](https://avajs.dev). fi␊ echo "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/" >> remappings.txt␊ echo "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/" >> remappings.txt␊ - ␊ # Add settings in foundry.toml␊ echo "" >> foundry.toml␊ echo "ffi = true" >> foundry.toml␊ @@ -848,6 +850,7 @@ Generated by [AVA](https://avajs.dev). ␊ # Install OpenZeppelin Contracts␊ forge install OpenZeppelin/openzeppelin-contracts@vX.Y.Z --quiet␊ + ␊ ␊ # Remove unneeded Foundry template files␊ rm src/Counter.sol␊ @@ -864,6 +867,7 @@ Generated by [AVA](https://avajs.dev). echo "" >> remappings.txt␊ fi␊ echo "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/" >> remappings.txt␊ + ␊ ␊ # Perform initial git commit␊ git add .␊ @@ -997,8 +1001,9 @@ Generated by [AVA](https://avajs.dev). # Initialize sample Foundry project␊ forge init --force --quiet␊ ␊ - # Install OpenZeppelin Contracts and Upgrades␊ + # Install OpenZeppelin Contracts␊ forge install OpenZeppelin/openzeppelin-contracts-upgradeable@vX.Y.Z --quiet␊ + # Install OpenZeppelin Foundry Upgrades␊ forge install OpenZeppelin/openzeppelin-foundry-upgrades --quiet␊ ␊ # Remove unneeded Foundry template files␊ @@ -1017,7 +1022,6 @@ Generated by [AVA](https://avajs.dev). fi␊ echo "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/" >> remappings.txt␊ echo "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/" >> remappings.txt␊ - ␊ # Add settings in foundry.toml␊ echo "" >> foundry.toml␊ echo "ffi = true" >> foundry.toml␊ @@ -1143,6 +1147,327 @@ Generated by [AVA](https://avajs.dev). `, ] +## account ecdsa + +> Snapshot 1 + + [ + `#!/usr/bin/env bash␊ + ␊ + # Check if git is installed␊ + if ! which git &> /dev/null␊ + then␊ + echo "git command not found. Install git and try again."␊ + exit 1␊ + fi␊ + ␊ + # Check if Foundry is installed␊ + if ! which forge &> /dev/null␊ + then␊ + echo "forge command not found. Install Foundry and try again. See https://book.getfoundry.sh/getting-started/installation"␊ + exit 1␊ + fi␊ + ␊ + # Setup Foundry project␊ + if ! [ -f "foundry.toml" ]␊ + then␊ + echo "Initializing Foundry project..."␊ + ␊ + # Backup Wizard template readme to avoid it being overwritten␊ + mv README.md README-oz.md␊ + ␊ + # Initialize sample Foundry project␊ + forge init --force --quiet␊ + ␊ + # Install OpenZeppelin Contracts␊ + forge install OpenZeppelin/openzeppelin-contracts@vX.Y.Z --quiet␊ + ␊ + ␊ + # Remove unneeded Foundry template files␊ + rm src/Counter.sol␊ + rm script/Counter.s.sol␊ + rm test/Counter.t.sol␊ + rm README.md␊ + ␊ + # Restore Wizard template readme␊ + mv README-oz.md README.md␊ + ␊ + # Add remappings␊ + if [ -f "remappings.txt" ]␊ + then␊ + echo "" >> remappings.txt␊ + fi␊ + echo "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/" >> remappings.txt␊ + ␊ + ␊ + # Perform initial git commit␊ + git add .␊ + git commit -m "openzeppelin: add wizard output" --quiet␊ + ␊ + echo "Done."␊ + else␊ + echo "Foundry project already initialized."␊ + fi␊ + `, + `# Sample Foundry Project␊ + ␊ + This project demonstrates a basic Foundry use case. It comes with a contract generated by [OpenZeppelin Wizard](https://wizard.openzeppelin.com/), a test for that contract, and a script that deploys that contract.␊ + ␊ + ## Installing Foundry␊ + ␊ + See [Foundry installation guide](https://book.getfoundry.sh/getting-started/installation).␊ + ␊ + ## Initializing the project␊ + ␊ + \`\`\`␊ + bash setup.sh␊ + \`\`\`␊ + ␊ + ## Testing the contract␊ + ␊ + \`\`\`␊ + forge test␊ + \`\`\`␊ + ␊ + ## Deploying the contract␊ + ␊ + You can simulate a deployment by running the script:␊ + ␊ + \`\`\`␊ + forge script script/MyAccount.s.sol␊ + \`\`\`␊ + ␊ + See [Solidity scripting guide](https://book.getfoundry.sh/guides/scripting-with-solidity) for more information.␊ + `, + `// SPDX-License-Identifier: MIT␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Script} from "forge-std/Script.sol";␊ + import {console} from "forge-std/console.sol";␊ + import {MyAccount} from "src/MyAccount.sol";␊ + ␊ + contract MyAccountScript is Script {␊ + function setUp() public {}␊ + ␊ + function run() public {␊ + // TODO: Set addresses for the variables below, then uncomment the following section:␊ + /*␊ + vm.startBroadcast();␊ + address signer = ;␊ + MyAccount instance = new MyAccount(signer);␊ + console.log("Contract deployed to %s", address(instance));␊ + vm.stopBroadcast();␊ + */␊ + }␊ + }␊ + `, + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerECDSA, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer) EIP712("My Account", "1") SignerECDSA(signer) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ + }␊ + }␊ + `, + `// SPDX-License-Identifier: MIT␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Test} from "forge-std/Test.sol";␊ + import {MyAccount} from "src/MyAccount.sol";␊ + ␊ + contract MyAccountTest is Test {␊ + MyAccount public instance;␊ + ␊ + function setUp() public {␊ + address signer = vm.addr(1);␊ + instance = new MyAccount(signer);␊ + }␊ + ␊ + function testSomething() public {␊ + // Add your test here␊ + }␊ + }␊ + `, + ] + +## account ecdsa uups + +> Snapshot 1 + + [ + `#!/usr/bin/env bash␊ + ␊ + # Check if git is installed␊ + if ! which git &> /dev/null␊ + then␊ + echo "git command not found. Install git and try again."␊ + exit 1␊ + fi␊ + ␊ + # Check if Foundry is installed␊ + if ! which forge &> /dev/null␊ + then␊ + echo "forge command not found. Install Foundry and try again. See https://book.getfoundry.sh/getting-started/installation"␊ + exit 1␊ + fi␊ + ␊ + # Setup Foundry project␊ + if ! [ -f "foundry.toml" ]␊ + then␊ + echo "Initializing Foundry project..."␊ + ␊ + # Backup Wizard template readme to avoid it being overwritten␊ + mv README.md README-oz.md␊ + ␊ + # Initialize sample Foundry project␊ + forge init --force --quiet␊ + ␊ + # Install OpenZeppelin Contracts␊ + forge install OpenZeppelin/openzeppelin-contracts-upgradeable@vX.Y.Z --quiet␊ + ␊ + ␊ + # Remove unneeded Foundry template files␊ + rm src/Counter.sol␊ + rm script/Counter.s.sol␊ + rm test/Counter.t.sol␊ + rm README.md␊ + ␊ + # Restore Wizard template readme␊ + mv README-oz.md README.md␊ + ␊ + # Add remappings␊ + if [ -f "remappings.txt" ]␊ + then␊ + echo "" >> remappings.txt␊ + fi␊ + echo "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/" >> remappings.txt␊ + echo "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/" >> remappings.txt␊ + ␊ + ␊ + # Perform initial git commit␊ + git add .␊ + git commit -m "openzeppelin: add wizard output" --quiet␊ + ␊ + echo "Done."␊ + else␊ + echo "Foundry project already initialized."␊ + fi␊ + `, + `# Sample Foundry Project␊ + ␊ + This project demonstrates a basic Foundry use case. It comes with a contract generated by [OpenZeppelin Wizard](https://wizard.openzeppelin.com/), a test for that contract, and a script that deploys that contract.␊ + ␊ + ## Installing Foundry␊ + ␊ + See [Foundry installation guide](https://book.getfoundry.sh/getting-started/installation).␊ + ␊ + ## Initializing the project␊ + ␊ + \`\`\`␊ + bash setup.sh␊ + \`\`\`␊ + ␊ + ## Testing the contract␊ + ␊ + \`\`\`␊ + forge test␊ + \`\`\`␊ + ␊ + ## Deploying the contract␊ + ␊ + You can simulate a deployment by running the script:␊ + ␊ + \`\`\`␊ + forge script script/MyAccount.s.sol␊ + \`\`\`␊ + ␊ + See [Solidity scripting guide](https://book.getfoundry.sh/guides/scripting-with-solidity) for more information.␊ + `, + `// SPDX-License-Identifier: MIT␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Script} from "forge-std/Script.sol";␊ + import {console} from "forge-std/console.sol";␊ + import {MyAccount} from "src/MyAccount.sol";␊ + ␊ + contract MyAccountScript is Script {␊ + function setUp() public {}␊ + ␊ + function run() public {␊ + vm.startBroadcast();␊ + MyAccount instance = new MyAccount();␊ + console.log("Contract deployed to %s", address(instance));␊ + vm.stopBroadcast();␊ + }␊ + }␊ + `, + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, ERC721Holder, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("My Account", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + `, + `// SPDX-License-Identifier: MIT␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Test} from "forge-std/Test.sol";␊ + import {MyAccount} from "src/MyAccount.sol";␊ + ␊ + contract MyAccountTest is Test {␊ + MyAccount public instance;␊ + ␊ + function setUp() public {␊ + instance = new MyAccount();␊ + }␊ + ␊ + function testSomething() public {␊ + // Add your test here␊ + }␊ + }␊ + `, + ] + ## custom basic > Snapshot 1 @@ -1177,6 +1502,7 @@ Generated by [AVA](https://avajs.dev). ␊ # Install OpenZeppelin Contracts␊ forge install OpenZeppelin/openzeppelin-contracts@vX.Y.Z --quiet␊ + ␊ ␊ # Remove unneeded Foundry template files␊ rm src/Counter.sol␊ @@ -1193,6 +1519,7 @@ Generated by [AVA](https://avajs.dev). echo "" >> remappings.txt␊ fi␊ echo "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/" >> remappings.txt␊ + ␊ ␊ # Perform initial git commit␊ git add .␊ @@ -1310,8 +1637,9 @@ Generated by [AVA](https://avajs.dev). # Initialize sample Foundry project␊ forge init --force --quiet␊ ␊ - # Install OpenZeppelin Contracts and Upgrades␊ + # Install OpenZeppelin Contracts␊ forge install OpenZeppelin/openzeppelin-contracts-upgradeable@vX.Y.Z --quiet␊ + # Install OpenZeppelin Foundry Upgrades␊ forge install OpenZeppelin/openzeppelin-foundry-upgrades --quiet␊ ␊ # Remove unneeded Foundry template files␊ @@ -1330,7 +1658,6 @@ Generated by [AVA](https://avajs.dev). fi␊ echo "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/" >> remappings.txt␊ echo "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/" >> remappings.txt␊ - ␊ # Add settings in foundry.toml␊ echo "" >> foundry.toml␊ echo "ffi = true" >> foundry.toml␊ diff --git a/packages/core/solidity/src/zip-foundry.test.ts.snap b/packages/core/solidity/src/zip-foundry.test.ts.snap index c21d46207..065cc8289 100644 Binary files a/packages/core/solidity/src/zip-foundry.test.ts.snap and b/packages/core/solidity/src/zip-foundry.test.ts.snap differ diff --git a/packages/core/solidity/src/zip-foundry.ts b/packages/core/solidity/src/zip-foundry.ts index 586711c22..52a437d0c 100644 --- a/packages/core/solidity/src/zip-foundry.ts +++ b/packages/core/solidity/src/zip-foundry.ts @@ -16,7 +16,7 @@ const test = (c: Contract, opts?: GenericOptions) => { function getImports(c: Contract) { const result = ['import {Test} from "forge-std/Test.sol";']; - if (c.upgradeable) { + if (c.shouldUseUpgradesPluginsForProxyDeployment) { result.push('import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";'); } result.push(`import {${c.name}} from "src/${c.name}.sol";`); @@ -37,7 +37,7 @@ const test = (c: Contract, opts?: GenericOptions) => { } function getDeploymentCode(c: Contract, args: string[]): Lines[] { - if (c.upgradeable) { + if (c.shouldUseUpgradesPluginsForProxyDeployment) { if (opts?.upgradeable === 'transparent') { return [ `address proxy = Upgrades.deployTransparentProxy(`, @@ -61,7 +61,11 @@ const test = (c: Contract, opts?: GenericOptions) => { function getAddressVariables(c: Contract, args: string[]): Lines[] { const vars = []; let i = 1; // private key index starts from 1 since it must be non-zero - if (c.upgradeable && opts?.upgradeable === 'transparent' && !args.includes('initialOwner')) { + if ( + c.shouldUseUpgradesPluginsForProxyDeployment && + opts?.upgradeable === 'transparent' && + !args.includes('initialOwner') + ) { vars.push(`address initialOwner = vm.addr(${i++});`); } for (const arg of args) { @@ -80,6 +84,7 @@ const test = (c: Contract, opts?: GenericOptions) => { case 'ERC1155': return ['function testUri() public view {', [`assertEq(instance.uri(0), "${opts.uri}");`], '}']; + case 'Account': case 'Governor': case 'Custom': return ['function testSomething() public {', ['// Add your test here'], '}']; @@ -107,7 +112,7 @@ const script = (c: Contract, opts?: GenericOptions) => { function getImports(c: Contract) { const result = ['import {Script} from "forge-std/Script.sol";', 'import {console} from "forge-std/console.sol";']; - if (c.upgradeable) { + if (c.shouldUseUpgradesPluginsForProxyDeployment) { result.push('import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";'); } result.push(`import {${c.name}} from "src/${c.name}.sol";`); @@ -120,7 +125,7 @@ const script = (c: Contract, opts?: GenericOptions) => { 'vm.startBroadcast();', ...getAddressVariables(c, args), ...getDeploymentCode(c, args), - `console.log("${c.upgradeable ? 'Proxy' : 'Contract'} deployed to %s", address(instance));`, + `console.log("${c.shouldUseUpgradesPluginsForProxyDeployment ? 'Proxy' : 'Contract'} deployed to %s", address(instance));`, 'vm.stopBroadcast();', ]; return [ @@ -134,7 +139,7 @@ const script = (c: Contract, opts?: GenericOptions) => { } function getDeploymentCode(c: Contract, args: string[]): Lines[] { - if (c.upgradeable) { + if (c.shouldUseUpgradesPluginsForProxyDeployment) { if (opts?.upgradeable === 'transparent') { return [ `address proxy = Upgrades.deployTransparentProxy(`, @@ -157,7 +162,11 @@ const script = (c: Contract, opts?: GenericOptions) => { function getAddressVariables(c: Contract, args: string[]): Lines[] { const vars = []; - if (c.upgradeable && opts?.upgradeable === 'transparent' && !args.includes('initialOwner')) { + if ( + c.shouldUseUpgradesPluginsForProxyDeployment && + opts?.upgradeable === 'transparent' && + !args.includes('initialOwner') + ) { vars.push('address initialOwner = ;'); } for (const arg of args) { @@ -205,16 +214,23 @@ then forge init --force --quiet ${ - c.upgradeable + c.shouldInstallContractsUpgradeable ? `\ - # Install OpenZeppelin Contracts and Upgrades - forge install OpenZeppelin/openzeppelin-contracts-upgradeable@v${contracts.version} --quiet - forge install OpenZeppelin/openzeppelin-foundry-upgrades --quiet\ + # Install OpenZeppelin Contracts + forge install OpenZeppelin/openzeppelin-contracts-upgradeable@v${contracts.version} --quiet\ ` : `\ # Install OpenZeppelin Contracts forge install OpenZeppelin/openzeppelin-contracts@v${contracts.version} --quiet\ ` +} +${ + c.shouldUseUpgradesPluginsForProxyDeployment + ? `\ + # Install OpenZeppelin Foundry Upgrades + forge install OpenZeppelin/openzeppelin-foundry-upgrades --quiet\ +` + : '' } # Remove unneeded Foundry template files @@ -232,11 +248,18 @@ ${ echo "" >> remappings.txt fi ${ - c.upgradeable + c.shouldInstallContractsUpgradeable ? `\ echo "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/" >> remappings.txt - echo "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/" >> remappings.txt - + echo "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/" >> remappings.txt\ +` + : `\ + echo "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/" >> remappings.txt\ +` +} +${ + c.shouldUseUpgradesPluginsForProxyDeployment + ? `\ # Add settings in foundry.toml echo "" >> foundry.toml echo "ffi = true" >> foundry.toml @@ -244,9 +267,7 @@ ${ echo "build_info = true" >> foundry.toml echo "extra_output = [\\"storageLayout\\"]" >> foundry.toml\ ` - : `\ - echo "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/" >> remappings.txt\ -` + : '' } # Perform initial git commit @@ -277,7 +298,7 @@ bash setup.sh ## Testing the contract \`\`\` -forge test${c.upgradeable ? ' --force' : ''} +forge test${c.shouldUseUpgradesPluginsForProxyDeployment ? ' --force' : ''} \`\`\` ## Deploying the contract @@ -285,7 +306,7 @@ forge test${c.upgradeable ? ' --force' : ''} You can simulate a deployment by running the script: \`\`\` -forge script script/${c.name}.s.sol${c.upgradeable ? ' --force' : ''} +forge script script/${c.name}.s.sol${c.shouldUseUpgradesPluginsForProxyDeployment ? ' --force' : ''} \`\`\` See [Solidity scripting guide](https://book.getfoundry.sh/guides/scripting-with-solidity) for more information. diff --git a/packages/core/solidity/src/zip-hardhat.test.ts b/packages/core/solidity/src/zip-hardhat.test.ts index 097e231ea..4daa63619 100644 --- a/packages/core/solidity/src/zip-hardhat.test.ts +++ b/packages/core/solidity/src/zip-hardhat.test.ts @@ -17,6 +17,7 @@ import { rimraf } from 'rimraf'; import type { JSZipObject } from 'jszip'; import type JSZip from 'jszip'; import type { GenericOptions } from './build-generic'; +import { buildAccount } from './account'; interface Context { tempFolder: string; @@ -92,6 +93,18 @@ test.serial('erc1155 basic', async t => { await runIgnitionTest(c, t, opts); }); +test.serial('account ecdsa', async t => { + const opts: GenericOptions = { kind: 'Account', name: 'My Account', signer: 'ECDSA' }; + const c = buildAccount(opts); + await runIgnitionTest(c, t, opts); +}); + +test.serial('account ecdsa uups', async t => { + const opts: GenericOptions = { kind: 'Account', name: 'My Account', signer: 'ECDSA', upgradeable: 'uups' }; + const c = buildAccount(opts); + await runIgnitionTest(c, t, opts); // Account does not use proxies for deployment, until factories are added +}); + test.serial('custom basic', async t => { const opts: GenericOptions = { kind: 'Custom', name: 'My Contract' }; const c = buildCustom(opts); diff --git a/packages/core/solidity/src/zip-hardhat.test.ts.md b/packages/core/solidity/src/zip-hardhat.test.ts.md index faf4023f1..c0068444e 100644 --- a/packages/core/solidity/src/zip-hardhat.test.ts.md +++ b/packages/core/solidity/src/zip-hardhat.test.ts.md @@ -485,6 +485,189 @@ Generated by [AVA](https://avajs.dev). `, ] +## account ecdsa + +> Snapshot 1 + + [ + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";␊ + import {SignerECDSA} from "@openzeppelin/contracts/utils/cryptography/signers/SignerECDSA.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerECDSA, ERC721Holder, ERC1155Holder {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor(address signer) EIP712("My Account", "1") SignerECDSA(signer) {␊ + // Accounts are typically deployed and initialized as clones during their first user op,␊ + // therefore, initializers are disabled for the implementation contract␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + _setSigner(signer);␊ + }␊ + }␊ + `, + `import { HardhatUserConfig } from "hardhat/config";␊ + import "@nomicfoundation/hardhat-toolbox";␊ + ␊ + ␊ + const config: HardhatUserConfig = {␊ + solidity: {␊ + version: "0.8.27",␊ + settings: {␊ + optimizer: {␊ + enabled: true,␊ + },␊ + },␊ + },␊ + };␊ + ␊ + export default config;␊ + `, + `{␊ + "name": "hardhat-sample",␊ + "version": "0.0.1",␊ + "description": "",␊ + "main": "index.js",␊ + "scripts": {␊ + "test": "hardhat test"␊ + },␊ + "author": "",␊ + "license": "MIT",␊ + "devDependencies": {␊ + "@openzeppelin/contracts": "^5.4.0",␊ + "@nomicfoundation/hardhat-toolbox": "^6.1.0",␊ + "hardhat": "^2.16.1"␊ + }␊ + }`, + `import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";␊ + ␊ + export default buildModule("MyAccountModule", (m) => {␊ + ␊ + // TODO: Set addresses for the contract arguments below␊ + const myAccount = m.contract("MyAccount", [signer]);␊ + ␊ + return { myAccount };␊ + });␊ + `, + `import { expect } from "chai";␊ + import { ethers } from "hardhat";␊ + ␊ + describe("MyAccount", function () {␊ + it("Test contract", async function () {␊ + const ContractFactory = await ethers.getContractFactory("MyAccount");␊ + ␊ + const signer = (await ethers.getSigners())[0].address;␊ + ␊ + const instance = await ContractFactory.deploy(signer);␊ + await instance.waitForDeployment();␊ + });␊ + });␊ + `, + ] + +## account ecdsa uups + +> Snapshot 1 + + [ + `// SPDX-License-Identifier: MIT␊ + // Compatible with OpenZeppelin Contracts ^5.4.0␊ + pragma solidity ^0.8.27;␊ + ␊ + import {Account} from "@openzeppelin/contracts/account/Account.sol";␊ + import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol";␊ + import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";␊ + import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";␊ + import {ERC7739} from "@openzeppelin/contracts/utils/cryptography/signers/draft-ERC7739.sol";␊ + import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊ + import {SignerECDSAUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/signers/SignerECDSAUpgradeable.sol";␊ + import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊ + ␊ + contract MyAccount is Initializable, Account, EIP712, ERC7739, SignerECDSAUpgradeable, ERC721Holder, ERC1155Holder, UUPSUpgradeable {␊ + /// @custom:oz-upgrades-unsafe-allow-reachable constructor␊ + constructor() EIP712("My Account", "1") {␊ + _disableInitializers();␊ + }␊ + ␊ + function initialize(address signer) public initializer {␊ + __SignerECDSA_init(signer);␊ + }␊ + ␊ + function _authorizeUpgrade(address newImplementation)␊ + internal␊ + override␊ + onlyEntryPointOrSelf␊ + {}␊ + }␊ + `, + `import { HardhatUserConfig } from "hardhat/config";␊ + import "@nomicfoundation/hardhat-toolbox";␊ + ␊ + ␊ + const config: HardhatUserConfig = {␊ + solidity: {␊ + version: "0.8.27",␊ + settings: {␊ + optimizer: {␊ + enabled: true,␊ + },␊ + },␊ + },␊ + };␊ + ␊ + export default config;␊ + `, + `{␊ + "name": "hardhat-sample",␊ + "version": "0.0.1",␊ + "description": "",␊ + "main": "index.js",␊ + "scripts": {␊ + "test": "hardhat test"␊ + },␊ + "author": "",␊ + "license": "MIT",␊ + "devDependencies": {␊ + "@openzeppelin/contracts": "^5.4.0",␊ + "@openzeppelin/contracts-upgradeable": "^5.4.0",␊ + "@openzeppelin/hardhat-upgrades": "^3.0.0",␊ + "@nomicfoundation/hardhat-toolbox": "^6.1.0",␊ + "hardhat": "^2.16.1"␊ + }␊ + }`, + `import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";␊ + ␊ + export default buildModule("MyAccountModule", (m) => {␊ + ␊ + ␊ + const myAccount = m.contract("MyAccount", []);␊ + ␊ + return { myAccount };␊ + });␊ + `, + `import { expect } from "chai";␊ + import { ethers } from "hardhat";␊ + ␊ + describe("MyAccount", function () {␊ + it("Test contract", async function () {␊ + const ContractFactory = await ethers.getContractFactory("MyAccount");␊ + ␊ + const instance = await ContractFactory.deploy();␊ + await instance.waitForDeployment();␊ + });␊ + });␊ + `, + ] + ## custom basic > Snapshot 1 diff --git a/packages/core/solidity/src/zip-hardhat.test.ts.snap b/packages/core/solidity/src/zip-hardhat.test.ts.snap index 024a4cbe3..ed7a6bb80 100644 Binary files a/packages/core/solidity/src/zip-hardhat.test.ts.snap and b/packages/core/solidity/src/zip-hardhat.test.ts.snap differ diff --git a/packages/core/solidity/src/zip-hardhat.ts b/packages/core/solidity/src/zip-hardhat.ts index 490a693b9..2531d4c57 100644 --- a/packages/core/solidity/src/zip-hardhat.ts +++ b/packages/core/solidity/src/zip-hardhat.ts @@ -6,10 +6,10 @@ import SOLIDITY_VERSION from './solidity-version.json'; import type { Lines } from './utils/format-lines'; import { formatLinesWithSpaces, spaceBetween } from './utils/format-lines'; -const hardhatConfig = (upgradeable: boolean) => `\ +const hardhatConfig = (useHardhatUpgrades: boolean) => `\ import { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; -${upgradeable ? `import "@openzeppelin/hardhat-upgrades";` : ''} +${useHardhatUpgrades ? `import "@openzeppelin/hardhat-upgrades";` : ''} const config: HardhatUserConfig = { solidity: { @@ -87,6 +87,7 @@ const test = (c: Contract, opts?: GenericOptions) => { case 'ERC1155': return [`expect(await instance.uri(0)).to.equal("${opts.uri}");`]; + case 'Account': case 'Governor': case 'Custom': break; @@ -118,7 +119,7 @@ function getAddressArgs(c: Contract): string[] { } function getDeploymentCall(c: Contract, args: string[]): string { - return c.upgradeable + return c.shouldUseUpgradesPluginsForProxyDeployment ? `upgrades.deployProxy(ContractFactory, [${args.join(', ')}])` : `ContractFactory.deploy(${args.join(', ')})`; } @@ -135,7 +136,7 @@ async function main() { const instance = await ${getDeploymentCall(c, args)}; await instance.waitForDeployment(); - console.log(\`${c.upgradeable ? 'Proxy' : 'Contract'} deployed to \${await instance.getAddress()}\`); + console.log(\`${c.shouldUseUpgradesPluginsForProxyDeployment ? 'Proxy' : 'Contract'} deployed to \${await instance.getAddress()}\`); } // We recommend this pattern to be able to use async/await everywhere @@ -168,7 +169,7 @@ export default buildModule("${c.name}Module", (m) => { const readme = (c: Contract) => `\ # Sample Hardhat Project -This project demonstrates a basic Hardhat use case. It comes with a contract generated by [OpenZeppelin Wizard](https://wizard.openzeppelin.com/), a test for that contract, ${c.upgradeable ? 'and a script that deploys that contract' : 'and a Hardhat Ignition module that deploys that contract'}. +This project demonstrates a basic Hardhat use case. It comes with a contract generated by [OpenZeppelin Wizard](https://wizard.openzeppelin.com/), a test for that contract, ${c.shouldUseUpgradesPluginsForProxyDeployment ? 'and a script that deploys that contract' : 'and a Hardhat Ignition module that deploys that contract'}. ## Installing dependencies @@ -187,13 +188,13 @@ npm test You can target any network from your Hardhat config using: \`\`\` -${c.upgradeable ? 'npx hardhat run --network scripts/deploy.ts' : `npx hardhat ignition deploy ignition/modules/${c.name}.ts --network `} +${c.shouldUseUpgradesPluginsForProxyDeployment ? 'npx hardhat run --network scripts/deploy.ts' : `npx hardhat ignition deploy ignition/modules/${c.name}.ts --network `} \`\`\` `; function getHardhatPlugins(c: Contract) { const plugins = ['ethers']; - if (c.upgradeable) { + if (c.shouldUseUpgradesPluginsForProxyDeployment) { plugins.push('upgrades'); } return plugins; @@ -202,27 +203,29 @@ function getHardhatPlugins(c: Contract) { export async function zipHardhat(c: Contract, opts?: GenericOptions) { const zip = new JSZip(); - const { default: packageJson } = c.upgradeable - ? await import('./environments/hardhat/upgradeable/package.json') - : await import('./environments/hardhat/package.json'); + const { default: packageJson } = + c.shouldInstallContractsUpgradeable || c.shouldUseUpgradesPluginsForProxyDeployment + ? await import('./environments/hardhat/upgradeable/package.json') + : await import('./environments/hardhat/package.json'); packageJson.license = c.license; - const { default: packageLock } = c.upgradeable - ? await import('./environments/hardhat/upgradeable/package-lock.json') - : await import('./environments/hardhat/package-lock.json'); + const { default: packageLock } = + c.shouldInstallContractsUpgradeable || c.shouldUseUpgradesPluginsForProxyDeployment + ? await import('./environments/hardhat/upgradeable/package-lock.json') + : await import('./environments/hardhat/package-lock.json'); packageLock.packages[''].license = c.license; zip.file(`contracts/${c.name}.sol`, printContract(c)); zip.file('test/test.ts', test(c, opts)); - if (c.upgradeable) { + if (c.shouldUseUpgradesPluginsForProxyDeployment) { zip.file('scripts/deploy.ts', script(c)); } else { zip.file(`ignition/modules/${c.name}.ts`, ignitionModule(c)); } zip.file('.gitignore', gitIgnore); - zip.file('hardhat.config.ts', hardhatConfig(c.upgradeable)); + zip.file('hardhat.config.ts', hardhatConfig(c.shouldUseUpgradesPluginsForProxyDeployment)); zip.file('package.json', JSON.stringify(packageJson, null, 2)); zip.file(`package-lock.json`, JSON.stringify(packageLock, null, 2)); zip.file('README.md', readme(c)); diff --git a/packages/mcp/src/solidity/schemas.ts b/packages/mcp/src/solidity/schemas.ts index 617f2fb25..9bdebed84 100644 --- a/packages/mcp/src/solidity/schemas.ts +++ b/packages/mcp/src/solidity/schemas.ts @@ -139,6 +139,7 @@ export const accountSchema = { .optional() .describe(solidityAccountDescriptions.ERC7579Modules), info: commonSchema.info, + upgradeable: commonSchema.upgradeable, } as const satisfies z.ZodRawShape; export const governorSchema = { diff --git a/packages/mcp/src/solidity/tools/account.test.ts b/packages/mcp/src/solidity/tools/account.test.ts index cbab1dde2..1bb676e5c 100644 --- a/packages/mcp/src/solidity/tools/account.test.ts +++ b/packages/mcp/src/solidity/tools/account.test.ts @@ -51,6 +51,7 @@ test('all', async t => { license: 'MIT', securityContact: 'security@example.com', }, + upgradeable: 'transparent', }; assertHasAllSupportedFields(t, params); await assertAPIEquivalence(t, params, account.print); diff --git a/packages/mcp/src/solidity/tools/account.ts b/packages/mcp/src/solidity/tools/account.ts index b62eb5af8..2fbfd68a9 100644 --- a/packages/mcp/src/solidity/tools/account.ts +++ b/packages/mcp/src/solidity/tools/account.ts @@ -19,6 +19,7 @@ export function registerSolidityAccount(server: McpServer): RegisteredTool { batchedExecution, ERC7579Modules, info, + upgradeable, }) => { const opts: AccountOptions = { name, @@ -29,6 +30,7 @@ export function registerSolidityAccount(server: McpServer): RegisteredTool { batchedExecution, ERC7579Modules, info, + upgradeable, }; return { content: [ diff --git a/packages/ui/api/ai-assistant/function-definitions/solidity.ts b/packages/ui/api/ai-assistant/function-definitions/solidity.ts index 00df94474..81cc84a4f 100644 --- a/packages/ui/api/ai-assistant/function-definitions/solidity.ts +++ b/packages/ui/api/ai-assistant/function-definitions/solidity.ts @@ -183,7 +183,7 @@ export const solidityAccountAIFunctionDefinition = { parameters: { type: 'object', properties: { - ...addFunctionPropertiesFrom(commonFunctionDescription, ['name', 'info']), + ...addFunctionPropertiesFrom(commonFunctionDescription, ['name', 'upgradeable', 'info']), signatureValidation: { anyOf: [ { type: 'boolean', enum: [false] }, @@ -217,11 +217,6 @@ export const solidityAccountAIFunctionDefinition = { ], description: solidityAccountDescriptions.ERC7579Modules, }, - upgradeable: { - type: 'boolean', - enum: [false], - description: 'Upgradeability is not yet available for features that use @openzeppelin/community-contracts', - }, access: { type: 'boolean', enum: [false], diff --git a/packages/ui/src/solidity/AccountControls.svelte b/packages/ui/src/solidity/AccountControls.svelte index 8a490a66f..628cc0f54 100644 --- a/packages/ui/src/solidity/AccountControls.svelte +++ b/packages/ui/src/solidity/AccountControls.svelte @@ -4,8 +4,10 @@ import type { KindedOptions, OptionsErrorMessages } from '@openzeppelin/wizard'; import ExpandableToggleRadio from '../common/ExpandableToggleRadio.svelte'; import { account } from '@openzeppelin/wizard'; + import { error } from '../common/error-tooltip'; import InfoSection from './InfoSection.svelte'; + import UpgradeabilitySection from './UpgradeabilitySection.svelte'; export let opts: Required = { kind: 'Account', @@ -20,16 +22,21 @@ wasERC7579Modules = !!opts.ERC7579Modules; } + let upgradeNotSupported = false; + let upgradeNotSupportedReason = ''; + $: { + if (opts.signer === 'ERC7702') { + upgradeNotSupported = true; + upgradeNotSupportedReason = 'EOAs can upgrade by redelegating to a new account'; + } else { + upgradeNotSupported = false; + upgradeNotSupportedReason = ''; + } + } + export let errors: undefined | OptionsErrorMessages; -
-
- * Experimental: - Some of the following features are not audited and are subject to change -
-
-

Settings

@@ -54,7 +61,7 @@ }} /> Signature Validation - + Enables smart contracts to validate signatures through a standard isValidSignature method. Unlike EOAs (regular accounts) that use private keys, this allows contracts to implement custom signature validation logic, making them capable of acting as signing entities for operations like approvals, swaps, or any signed messages. @@ -70,7 +77,7 @@ }} /> Account Bound - + Enhances signature security by using a defensive rehashing scheme that prevents signature replay attacks across multiple smart accounts owned by the same private key. This preserves the readability of signed contents while ensuring each signature is uniquely bound to a specific account and chain. @@ -112,7 +119,7 @@ }} /> Batched Execution - + Enables atomic execution of multiple transactions in a single operation, reducing total transaction costs and latency. @@ -157,29 +164,29 @@ bind:value={opts.signer} defaultValue="ECDSA" helpContent="Defines the base signature validation mechanism for the account. This implementation will be used to validate user operations following ERC-4337 or by ERC-1271's isValidSignature to verify signatures on behalf of the account." - helpLink="https://docs.openzeppelin.com/community-contracts/accounts#selecting_a_signer" + helpLink="https://docs.openzeppelin.com/contracts/accounts#selecting_a_signer" >
+ + diff --git a/packages/ui/src/solidity/App.svelte b/packages/ui/src/solidity/App.svelte index 94525b674..68382e944 100644 --- a/packages/ui/src/solidity/App.svelte +++ b/packages/ui/src/solidity/App.svelte @@ -118,7 +118,7 @@ downloadHardhat: false, downloadFoundry: false, }; - } else if (opts?.kind === 'Stablecoin' || opts?.kind === 'RealWorldAsset' || opts?.kind === 'Account') { + } else if (opts?.kind === 'Stablecoin' || opts?.kind === 'RealWorldAsset') { return { openInRemix: false, downloadHardhat: false, @@ -210,7 +210,7 @@ bind:currentOpts={opts} bind:currentCode={code} on:function-call-response={applyFunctionCall} - experimentalContracts={['Stablecoin', 'RealWorldAsset', 'Account']} + experimentalContracts={['Stablecoin', 'RealWorldAsset']} sampleMessages={['Make a token with supply of 10 million', 'What does mintable do?', 'Make a contract for a DAO']} /> @@ -224,7 +224,7 @@ - + diff --git a/packages/ui/src/solidity/UpgradeabilitySection.svelte b/packages/ui/src/solidity/UpgradeabilitySection.svelte index 518a6e676..08a57fe38 100644 --- a/packages/ui/src/solidity/UpgradeabilitySection.svelte +++ b/packages/ui/src/solidity/UpgradeabilitySection.svelte @@ -5,18 +5,40 @@ import HelpTooltip from '../common/HelpTooltip.svelte'; export let upgradeable: Upgradeable; + export let disabled: boolean = false; + export let disabledReason: string | undefined = undefined; + + let defaultValueWhenEnabled: 'transparent' | 'uups' = 'transparent'; + let wasDisabled = disabled; + let wasUpgradeable = upgradeable; + $: { + if (wasDisabled && !disabled) { + upgradeable = wasUpgradeable; + } else { + wasUpgradeable = upgradeable; + if (upgradeable !== false && disabled) { + upgradeable = false; + } + } + wasDisabled = disabled; + if (upgradeable !== false) { + defaultValueWhenEnabled = upgradeable; + } + }