Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
d666f50
feat: Remove hook group (#39)
adam-alchemy Mar 5, 2024
f6e335c
feat: [v0.8-develop, experimental] Merge validation function assignme…
adam-alchemy Apr 15, 2024
cf5355a
refactor: [v0.8-develop] 6900 iteration setup (#43)
adam-alchemy Apr 16, 2024
a66dcd8
refactor: [v0.8-develop] account test base (#44)
adam-alchemy Apr 17, 2024
8b58330
feat: [v0.8-develop] Bump solidity version and remove optimizations (…
adam-alchemy Apr 18, 2024
d9bcff3
feat: [v0.8-develop] merge pre validation types (#46)
adam-alchemy Apr 26, 2024
3b1e32e
chore: update to 4337 v0.7 (1/n) (#48)
howydev May 1, 2024
f00dba4
feat: [v0.8-develop] remove hook overlap support (#47)
adam-alchemy May 3, 2024
0f28a13
feat: [v0.8-develop] Simplify hook declaration and storage (#51)
adam-alchemy May 8, 2024
443b87b
fix: Add owner view function to manifest validation list (#55)
adamegyed May 14, 2024
59e8564
refactor: cleanup migrated content (#56)
adamegyed May 16, 2024
ed804c3
feat: [v0.8-develop, experimental] split up interfaces by type [1/N] …
adamegyed May 31, 2024
765a34f
feat: [v0.8-develop]: sig validation in interface (#59)
adamegyed May 31, 2024
7ac0f6b
feat: [v0.8-develop, experimental]: remove plugin call restriction [3…
adamegyed May 31, 2024
0923c21
feat: [v0.8-develop]: move runtime validation always allow to executi…
adamegyed May 31, 2024
3d54094
feat: [v0.8-develop] multi validation in user op signature (#62)
adamegyed Jun 10, 2024
81bef34
feat: Add various native function checks for plugin installation (#75)
fangting-alchemy Jun 18, 2024
c0a1e9d
feat: [v0.8-develop, experimental] default validation (#63)
adamegyed Jun 19, 2024
18261cb
feat: [v0.8-develop] associate pre-validation hooks with validation f…
adamegyed Jun 20, 2024
400e833
feat: [v0.8-develop] remove execute from plugin (#65)
adamegyed Jun 20, 2024
6e97d84
[1/n permissions] chore: remove existing permissions system (#67)
howydev Jun 28, 2024
f22a521
[2/n permissions] feat: add permission hooks (#76)
howydev Jul 9, 2024
f63137b
[3/n permissions] feat: add execute user operation (#77)
howydev Jul 9, 2024
de28c60
feat: [v0.8-develop] per validation hook data (#66)
adamegyed Jul 9, 2024
d8c726c
feat: [v0.8-develop] Add allowlist sample hook, refactor test base (#70)
adamegyed Jul 10, 2024
f376bf0
feat: [v0.8-develop] account self call restrictions (#78)
adamegyed Jul 10, 2024
072fa15
refactor: [v0.8-develop] invert validation mapping (#85)
adamegyed Jul 10, 2024
cfa31b1
feat: [v0.8-develop] remove plugin dependencies (#86)
adamegyed Jul 10, 2024
30596f8
style: [v0.8-develop] propose renaming default to global (#83)
adamegyed Jul 10, 2024
d50ae10
feat: [v0.8-develop] update SingleOwnerPlugin to use installValidatio…
adamegyed Jul 11, 2024
42d3db8
feat: [v0.8-develop] remove duplicate test factory [2/2] (#92)
adamegyed Jul 11, 2024
4279a97
fix: [v0.8-develop] cleanup requireUOHookCount (#95)
adamegyed Jul 16, 2024
c74d1ff
feat: add native token spend limit plugin
howydev Jun 12, 2024
8e7e33d
chore: update
howydev Jun 27, 2024
953bc11
fix: tests
howydev Jun 27, 2024
75d245e
chore: remove permission hooks, add new internal helper function for …
howydev Jun 28, 2024
c2d0910
fix: move to associated storage
howydev Jul 8, 2024
2743097
feat: add special paymaster list to still count towards limits
howydev Jul 8, 2024
a19fcda
c
howydev Jul 10, 2024
162131c
fix: lint
howydev Jul 10, 2024
1d38111
fix: lint, test
howydev Jul 10, 2024
3faa350
fix: test
howydev Jul 16, 2024
1685e91
[5/n permissions] feat: add erc20 token spend limit plugin (#80)
howydev Jul 16, 2024
d2e3c3a
feat: Validation revamp - Introduce validation composability and allo…
fangting-alchemy Jul 17, 2024
a598069
Allow direct plugin calls with validation & permission hooks (#90)
Zer0dot Jul 17, 2024
70ccd3e
style: [v0.8-develop] linter and fmt update (#98)
adamegyed Jul 17, 2024
5d0c3bb
Zer0dot/remove redundancy (#99)
Zer0dot Jul 17, 2024
a257ded
fix: Add back pluginEntityLib test and update old references and docs…
fangting-alchemy Jul 17, 2024
51e64d0
forge install: solady
Zer0dot Jul 18, 2024
cca4572
fix: Rename plugin to module and update readme and docs (#106)
fangting-alchemy Jul 19, 2024
6abe02c
fix: organize all modules under modules folder (#107)
fangting-alchemy Jul 19, 2024
6ca5b96
feat: appended initial validation and data to proxy bytecode
Zer0dot Jul 22, 2024
b5c593b
feat: pack appended bytecode into validation-specific configurations
Zer0dot Jul 22, 2024
ce001a8
feat: [v0.8-develop] User controlled install 1/N (#101)
adamegyed Jul 23, 2024
c41cc7c
feat: [v0.8-develop] merge plugin manager contracts 2/N (#102)
adamegyed Jul 23, 2024
13a36fa
feat: add factory
howydev Jul 18, 2024
3b100c5
update: add ownable, access control
howydev Jul 18, 2024
f2ef9d0
chore: comments
howydev Jul 18, 2024
a99f86d
fix: lint
howydev Jul 19, 2024
01db0f2
test: add tests, cleanup
howydev Jul 19, 2024
268b487
chore: use immutable single signer validation
howydev Jul 19, 2024
4278acf
fix: pr review fixes
howydev Jul 22, 2024
4f8947d
feat: [v0.8-develop] Remove validation installation from the manifest…
adamegyed Jul 23, 2024
e36feac
feat: [v0.8-develop] HookConfig install parameter & internal structur…
adamegyed Jul 24, 2024
ebabd8c
test: [v0.8-develop] Add test for ValidationConfigLib 5/N (#110)
adamegyed Jul 24, 2024
b71d6c9
fix: Handle fallback hooks & entrypoint/self-call/public selector run…
Zer0dot Jul 25, 2024
d8b0207
Merge branch 'v0.8-develop' into zer0dot/semi-modular-experiments
Zer0dot Jul 25, 2024
7efb881
fix: address renaming leftover issues
Zer0dot Jul 25, 2024
cc66201
chore: fix comment naming
Zer0dot Jul 25, 2024
f743d2a
feat: add native token spend limit plugin
howydev Jun 12, 2024
3476930
chore: update
howydev Jun 27, 2024
4a1302d
fix: tests
howydev Jun 27, 2024
797c4ef
chore: remove permission hooks, add new internal helper function for …
howydev Jun 28, 2024
29853e2
fix: move to associated storage
howydev Jul 8, 2024
834e2a4
feat: add special paymaster list to still count towards limits
howydev Jul 8, 2024
b859519
c
howydev Jul 10, 2024
8862e91
fix: lint
howydev Jul 10, 2024
28ed73b
fix: lint, test
howydev Jul 10, 2024
6b2edbb
fix: test
howydev Jul 16, 2024
edeb0fa
[5/n permissions] feat: add erc20 token spend limit plugin (#80)
howydev Jul 16, 2024
24cc733
feat: Validation revamp - Introduce validation composability and allo…
fangting-alchemy Jul 17, 2024
39d327e
Allow direct plugin calls with validation & permission hooks (#90)
Zer0dot Jul 17, 2024
1f43a23
style: [v0.8-develop] linter and fmt update (#98)
adamegyed Jul 17, 2024
acfb938
Zer0dot/remove redundancy (#99)
Zer0dot Jul 17, 2024
151b056
fix: Add back pluginEntityLib test and update old references and docs…
fangting-alchemy Jul 17, 2024
90540d6
fix: Rename plugin to module and update readme and docs (#106)
fangting-alchemy Jul 19, 2024
ee292ad
fix: organize all modules under modules folder (#107)
fangting-alchemy Jul 19, 2024
5cb215f
feat: [v0.8-develop] User controlled install 1/N (#101)
adamegyed Jul 23, 2024
9ebbe95
feat: [v0.8-develop] merge plugin manager contracts 2/N (#102)
adamegyed Jul 23, 2024
547c8b4
feat: add factory
howydev Jul 18, 2024
0fa034a
update: add ownable, access control
howydev Jul 18, 2024
182d024
chore: comments
howydev Jul 18, 2024
2a14f7b
fix: lint
howydev Jul 19, 2024
ce0484e
test: add tests, cleanup
howydev Jul 19, 2024
d5667b5
chore: use immutable single signer validation
howydev Jul 19, 2024
125920f
fix: pr review fixes
howydev Jul 22, 2024
16b6e97
feat: [v0.8-develop] Remove validation installation from the manifest…
adamegyed Jul 23, 2024
6d928b6
feat: [v0.8-develop] HookConfig install parameter & internal structur…
adamegyed Jul 24, 2024
193e156
test: [v0.8-develop] Add test for ValidationConfigLib 5/N (#110)
adamegyed Jul 24, 2024
7f75b1e
fix: Handle fallback hooks & entrypoint/self-call/public selector run…
Zer0dot Jul 25, 2024
bfeffa3
chore: [v0.8-develop] alpha.0 deploy prep (#111)
adamegyed Jul 26, 2024
1dc64e5
fix: remove unnecessary foundry.toml config (#114)
adamegyed Jul 26, 2024
2bc08b0
fix: start broadcast in script (#115)
adamegyed Jul 26, 2024
750f5c5
Merge branch 'develop' into zer0dot/semi-modular-experiments
Zer0dot Jul 26, 2024
4daa25a
chore: formatting
Zer0dot Jul 26, 2024
3f562f5
Refactor: split IExecution out from IModule and rename vars to refle…
fangting-alchemy Jul 26, 2024
e26f0d5
fix: adapt new factory to bytecode-appended SMA
Zer0dot Jul 26, 2024
2e9878f
feat: add alpha.0 deployments (#116)
adamegyed Jul 26, 2024
f70afc0
Merge branch 'develop' into zer0dot/semi-modular-experiments
Zer0dot Jul 26, 2024
99e8ded
chore: formatting
Zer0dot Jul 26, 2024
71cf394
chore: update foundry toml to match develop
Zer0dot Jul 26, 2024
0e5479b
chore: formatting with new foundry toml
Zer0dot Jul 26, 2024
bf65c85
feat: slight optimizations to factory
Zer0dot Jul 29, 2024
58287b3
chore: linting
Zer0dot Jul 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

# Factory owner capable only of managing stake
OWNER=
# EP 0.7 address
ENTRYPOINT=

# Create2 expected addresses of the contracts.
# When running for the first time, the error message will contain the expected addresses.
ACCOUNT_IMPL=
FACTORY=
SINGLE_SIGNER_VALIDATION=

# Optional, defaults to bytes32(0)
ACCOUNT_IMPL_SALT=
FACTORY_SALT=
SINGLE_SIGNER_VALIDATION_SALT=

# Optional, defaults to 0.1 ether and 1 day, respectively
STAKE_AMOUNT=
UNSTAKE_DELAY=
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,14 @@ node_modules/
# Coverage
report/
lcov.info

# env vars
.env

# deployments
broadcast/**/run-latest.json
broadcast/**/dry-run/**/*

# misc
.DS_Store
**/.DS_Store
18 changes: 12 additions & 6 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
[submodule "lib/account-abstraction"]
path = lib/account-abstraction
url = https://github.com/eth-infinitism/account-abstraction
path = lib/account-abstraction
url = https://github.com/eth-infinitism/account-abstraction
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/modular-account-libs"]
path = lib/modular-account-libs
url = https://github.com/erc6900/modular-account-libs
[submodule "lib/solady"]
path = lib/solady
url = https://github.com/vectorized/solady
36 changes: 18 additions & 18 deletions .solhint-test.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
{
"extends": "solhint:recommended",
"rules": {
"func-name-mixedcase": "off",
"immutable-vars-naming": ["error"],
"no-unused-import": ["error"],
"compiler-version": ["error", ">=0.8.19"],
"custom-errors": "off",
"func-visibility": ["error", { "ignoreConstructors": true }],
"max-line-length": ["error", 120],
"max-states-count": ["warn", 30],
"modifier-name-mixedcase": ["error"],
"private-vars-leading-underscore": ["error"],
"no-inline-assembly": "off",
"avoid-low-level-calls": "off",
"one-contract-per-file": "off",
"no-empty-blocks": "off"
}
"extends": "solhint:recommended",
"rules": {
"func-name-mixedcase": "off",
"immutable-vars-naming": ["error"],
"no-unused-import": ["error"],
"compiler-version": ["error", ">=0.8.19"],
"custom-errors": "off",
"func-visibility": ["error", { "ignoreConstructors": true }],
"max-line-length": ["error", 120],
"max-states-count": ["warn", 30],
"modifier-name-mixedcase": ["error"],
"private-vars-leading-underscore": ["error"],
"no-inline-assembly": "off",
"avoid-low-level-calls": "off",
"one-contract-per-file": "off",
"no-empty-blocks": "off",
"reason-string": ["warn", { "maxLength": 64 }]
}
}
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Reference implementation for [ERC-6900](https://eips.ethereum.org/EIPS/eip-6900). It is an early draft implementation.

The implementation includes an upgradable modular account with two plugins (`SingleOwnerPlugin` and `TokenReceiverPlugin`). It is compliant with ERC-6900 with the latest updates.
The implementation includes an upgradable modular account with three modules (`SingleSignerValidation`, `TokenReceiverModule`, and `AllowlistModule`). It is compliant with ERC-6900 with the latest updates.

## Important Callouts

Expand All @@ -11,7 +11,7 @@ The implementation includes an upgradable modular account with two plugins (`Sin

## Development

Anyone is welcome to submit feedback and/or PRs to improve code or add Plugins.
Anyone is welcome to submit feedback and/or PRs to improve code.

### Testing

Expand All @@ -28,3 +28,14 @@ Since IR compilation generates different bytecode, it's useful to test against t
FOUNDRY_PROFILE=optimized-build forge build
FOUNDRY_PROFILE=optimized-test forge test -vvv
```

## Integration testing

The reference implementation provides a sample factory and deploy script for the factory, account implementation, and the demo validation module `SingleSignerValidation`. This is not auditted, nor intended for production use. Limitations set by the GPL-V3 license apply.

To run this script, provide appropriate values in a `.env` file based on the `.env.example` template, then run:
```bash
forge script script/Deploy.s.sol <wallet options> -r <rpc_url> --broadcast
```

Where `<wallet_options>` specifies a way to sign the deployment transaction (see [here](https://book.getfoundry.sh/reference/forge/forge-script#wallet-options---raw)) and `<rpc_url>` specifies an RPC for the network you are deploying on.
214 changes: 214 additions & 0 deletions broadcast/Deploy.s.sol/421614/run-1722008916.json

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions deployments/arb-sepolia.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Arbitrum Sepolia

Chain ID: 421614

## AccountFactory

| Version | Address | Explorer | Salt |
| -------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------ | ---- |
| v0.8.0-alpha.0 | `0x1c7EF41AA9896b74223a3956c7dDE28F206E8b24` | [explorer](https://sepolia.arbiscan.io/address/0x1c7EF41AA9896b74223a3956c7dDE28F206E8b24) | `0` |

## UpgradeableModularAccount Implementation

| Version | Address | Explorer | Salt |
| -------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------ | ---- |
| v0.8.0-alpha.0 | `0x0809BF385117a43A322A4E31d459c0EcaA3B1A08` | [explorer](https://sepolia.arbiscan.io/address/0x0809BF385117a43A322A4E31d459c0EcaA3B1A08) | `0` |

## SingleSignerValidation

| Version | Address | Explorer | Salt |
| -------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------ | ---- |
| v0.8.0-alpha.0 | `0x9DA8c098A483E257dd96022831DF308cB24fCBE6` | [explorer](https://sepolia.arbiscan.io/address/0x9DA8c098A483E257dd96022831DF308cB24fCBE6) | `0` |
23 changes: 10 additions & 13 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@ libs = ['lib']
out = 'out'
optimizer = true
optimizer_runs = 200
fs_permissions = [
{ access = "read", path = "./out-optimized" }
]
auto_detect_solc = false
bytecode_hash = "none"
auto_detect_remappings = false
fs_permissions = [{ access = "read", path = "./out-optimized" }]

[fuzz]
runs = 500

[invariant]
runs=500
runs = 500
fail_on_revert = true
depth = 10

[profile.optimized-build]
via_ir = true
test = 'src'
optimizer_runs = 20000
out = 'out-optimized'

[profile.optimized-test]
Expand All @@ -38,7 +40,7 @@ runs = 5000
depth = 32

[profile.deep.fuzz]
runs = 10000
runs = 100000

[profile.deep.invariant]
runs = 5000
Expand All @@ -47,13 +49,8 @@ depth = 32
[fmt]
line_length = 115
wrap_comments = true

[rpc_endpoints]
mainnet = "${RPC_URL_MAINNET}"
goerli = "${RPC_URL_GOERLI}"

[etherscan]
mainnet = { key = "${ETHERSCAN_API_KEY}" }
goerli = { key = "${ETHERSCAN_API_KEY}" }
sort_imports = true
number_underscore = "thousands"
int_types = "long"

# See more config options https://github.com/foundry-rs/foundry/tree/master/config
1 change: 1 addition & 0 deletions lib/modular-account-libs
Submodule modular-account-libs added at 5d9d0e
1 change: 1 addition & 0 deletions lib/solady
Submodule solady added at 753c57
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
},
"scripts": {
"lint": "pnpm lint:src && pnpm lint:test",
"lint:src": "solhint -c .solhint-src.json './src/**/*.sol'",
"lint:test": "solhint -c .solhint-test.json './test/**/*.sol'"
"lint:src": "solhint --max-warnings 0 -c .solhint-src.json './src/**/*.sol'",
"lint:test": "solhint --max-warnings 0 -c .solhint-test.json './test/**/*.sol'"
}
}
2 changes: 2 additions & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ ds-test/=lib/forge-std/lib/ds-test/src/
forge-std/=lib/forge-std/src/
@eth-infinitism/account-abstraction/=lib/account-abstraction/contracts/
@openzeppelin/=lib/openzeppelin-contracts/
@modular-account-libs/=lib/modular-account-libs/src/
solady=lib/solady/src/
162 changes: 162 additions & 0 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.25;

import {IEntryPoint} from "@eth-infinitism/account-abstraction/interfaces/IEntryPoint.sol";
import {Script} from "forge-std/Script.sol";
import {console2} from "forge-std/Test.sol";

import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";

import {AccountFactory} from "../src/account/AccountFactory.sol";
import {UpgradeableModularAccount} from "../src/account/UpgradeableModularAccount.sol";
import {SingleSignerValidation} from "../src/modules/validation/SingleSignerValidation.sol";

contract DeployScript is Script {
IEntryPoint public entryPoint = IEntryPoint(payable(vm.envAddress("ENTRYPOINT")));

address public owner = vm.envAddress("OWNER");

address public accountImpl = vm.envOr("ACCOUNT_IMPL", address(0));
address public factory = vm.envOr("FACTORY", address(0));
address public singleSignerValidation = vm.envOr("SINGLE_SIGNER_VALIDATION", address(0));

bytes32 public accountImplSalt = bytes32(vm.envOr("ACCOUNT_IMPL_SALT", uint256(0)));
bytes32 public factorySalt = bytes32(vm.envOr("FACTORY_SALT", uint256(0)));
bytes32 public singleSignerValidationSalt = bytes32(vm.envOr("SINGLE_SIGNER_VALIDATION_SALT", uint256(0)));

uint256 public requiredStakeAmount = vm.envOr("STAKE_AMOUNT", uint256(0.1 ether));
uint256 public requiredUnstakeDelay = vm.envOr("UNSTAKE_DELAY", uint256(1 days));

function run() public {
console2.log("******** Deploying ERC-6900 Reference Implementation ********");
console2.log("Chain: ", block.chainid);
console2.log("EP: ", address(entryPoint));
console2.log("Factory owner: ", owner);

vm.startBroadcast();
_deployAccountImpl(accountImplSalt, accountImpl);
_deploySingleSignerValidation(singleSignerValidationSalt, singleSignerValidation);
_deployAccountFactory(factorySalt, factory);
_addStakeForFactory(uint32(requiredUnstakeDelay), requiredStakeAmount);
vm.stopBroadcast();
}

function _deployAccountImpl(bytes32 salt, address expected) internal {
console2.log(string.concat("Deploying AccountImpl with salt: ", vm.toString(salt)));

address addr = Create2.computeAddress(
salt,
keccak256(abi.encodePacked(type(UpgradeableModularAccount).creationCode, abi.encode(entryPoint))),
CREATE2_FACTORY
);
if (addr != expected) {
console2.log("Expected address mismatch");
console2.log("Expected: ", expected);
console2.log("Actual: ", addr);
revert();
}

if (addr.code.length == 0) {
console2.log("No code found at expected address, deploying...");
UpgradeableModularAccount deployed = new UpgradeableModularAccount{salt: salt}(entryPoint);

if (address(deployed) != expected) {
console2.log("Deployed address mismatch");
console2.log("Expected: ", expected);
console2.log("Deployed: ", address(deployed));
revert();
}

console2.log("Deployed AccountImpl at: ", address(deployed));
} else {
console2.log("Code found at expected address, skipping deployment");
}
}

function _deploySingleSignerValidation(bytes32 salt, address expected) internal {
console2.log(string.concat("Deploying SingleSignerValidation with salt: ", vm.toString(salt)));

address addr = Create2.computeAddress(
salt, keccak256(abi.encodePacked(type(SingleSignerValidation).creationCode)), CREATE2_FACTORY
);
if (addr != expected) {
console2.log("Expected address mismatch");
console2.log("Expected: ", expected);
console2.log("Actual: ", addr);
revert();
}

if (addr.code.length == 0) {
console2.log("No code found at expected address, deploying...");
SingleSignerValidation deployed = new SingleSignerValidation{salt: salt}();

if (address(deployed) != expected) {
console2.log("Deployed address mismatch");
console2.log("Expected: ", expected);
console2.log("Deployed: ", address(deployed));
revert();
}

console2.log("Deployed SingleSignerValidation at: ", address(deployed));
} else {
console2.log("Code found at expected address, skipping deployment");
}
}

function _deployAccountFactory(bytes32 salt, address expected) internal {
console2.log(string.concat("Deploying AccountFactory with salt: ", vm.toString(salt)));

address addr = Create2.computeAddress(
salt,
keccak256(
abi.encodePacked(
type(AccountFactory).creationCode,
abi.encode(entryPoint, accountImpl, singleSignerValidation, owner)
)
),
CREATE2_FACTORY
);
if (addr != expected) {
console2.log("Expected address mismatch");
console2.log("Expected: ", expected);
console2.log("Actual: ", addr);
revert();
}

if (addr.code.length == 0) {
console2.log("No code found at expected address, deploying...");
AccountFactory deployed = new AccountFactory{salt: salt}(
entryPoint, UpgradeableModularAccount(payable(accountImpl)), singleSignerValidation, owner
);

if (address(deployed) != expected) {
console2.log("Deployed address mismatch");
console2.log("Expected: ", expected);
console2.log("Deployed: ", address(deployed));
revert();
}

console2.log("Deployed AccountFactory at: ", address(deployed));
} else {
console2.log("Code found at expected address, skipping deployment");
}
}

function _addStakeForFactory(uint32 unstakeDelay, uint256 stakeAmount) internal {
console2.log("Adding stake to factory");

uint256 currentStake = entryPoint.getDepositInfo(address(factory)).stake;
console2.log("Current stake: ", currentStake);
uint256 stakeToAdd = stakeAmount - currentStake;

if (stakeToAdd > 0) {
console2.log("Adding stake: ", stakeToAdd);
entryPoint.addStake{value: stakeToAdd}(unstakeDelay);
console2.log("Staked factory: ", address(factory));
console2.log("Total stake amount: ", entryPoint.getDepositInfo(address(factory)).stake);
console2.log("Unstake delay: ", entryPoint.getDepositInfo(address(factory)).unstakeDelaySec);
} else {
console2.log("No stake to add");
}
}
}
Loading