-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
111 changed files
with
690 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"figma.autocompleteBlocks": true, | ||
"cursor.chat.showSuggestedFiles": true, | ||
"cursor.cpp.enablePartialAccepts": true, | ||
"debug.console.acceptSuggestionOnEnter": "on", | ||
"editor.suggest.preview": true, | ||
"editor.suggest.shareSuggestSelections": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Account Abstraction | ||
|
||
This repository contains a minimal implementation of an account abstraction system using the Account Abstraction standard. | ||
|
||
## Overview | ||
|
||
1. Create a basic AA on Ethereum | ||
2. Create a basic AA on Zkysync | ||
3. Deploy and send a userOp/transaction through them |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule account-abstraction
updated
48 files
Submodule foundry-era-contracts
added at
3f99de
Submodule openzeppelin-contracts
updated
467 files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.20; | ||
|
||
import {MinimalAccount} from "../src/ethereum/MinimalAccount.sol"; | ||
import {Script} from "forge-std/Script.sol"; | ||
import {HelperConfig} from "./HelperConfig.s.sol"; | ||
|
||
contract DeployMinimal is Script { | ||
// MinimalAccount public minimalAccount; | ||
function run() external { | ||
// minimalAccount = new deployMinimalAccount(); | ||
} | ||
|
||
function deployMinimalAccount() public returns (MinimalAccount, HelperConfig) { | ||
HelperConfig helperConfig = new HelperConfig(); | ||
HelperConfig.NetworkConfig memory config = helperConfig.getConfig(); | ||
|
||
vm.startBroadcast(config.account); | ||
MinimalAccount minimalAccount = new MinimalAccount(config.entryPoint); | ||
minimalAccount.transferOwnership(config.account); | ||
vm.stopBroadcast(); | ||
return (minimalAccount, helperConfig); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.20; | ||
|
||
import {Script, console2} from "forge-std/Script.sol"; | ||
import {EntryPoint} from "account-abstraction/core/EntryPoint.sol"; | ||
|
||
contract HelperConfig is Script { | ||
error HelperConfig__InvalidChainId(); | ||
|
||
struct NetworkConfig { | ||
address entryPoint; | ||
address account; | ||
} | ||
|
||
uint256 constant ETH_SEPOLIA_CHAIN_ID = 11155111; | ||
uint256 constant ZKSYNC_SEPOLIA_CHAIN_ID = 300; | ||
uint256 constant LOCAL_ANVIL_CHAIN_ID = 31337; | ||
address constant BURNER_WALLET = 0x70997970C59cfa742bb70896FB3BB598232BC248; | ||
address constant FOUNDRY_DEFAULT_SENDER = 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38; | ||
address constant ANVIL_DEFAULT_ACCOUNT = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266; | ||
|
||
NetworkConfig public localNetworkConfig; | ||
mapping(uint256 chainId => NetworkConfig networkConfig) public networkConfigs; | ||
|
||
constructor() { | ||
networkConfigs[ETH_SEPOLIA_CHAIN_ID] = getEthSepoliaConfig(); | ||
} | ||
|
||
function getConfig() public returns (NetworkConfig memory) { | ||
return getConfigByChainId(block.chainid); | ||
} | ||
|
||
function getConfigByChainId(uint256 chainId) public returns (NetworkConfig memory) { | ||
if (chainId == LOCAL_ANVIL_CHAIN_ID) { | ||
return getOrCreateAnvilEthConfig(); | ||
} else if (networkConfigs[chainId].entryPoint != address(0)) { | ||
return networkConfigs[chainId]; | ||
} else { | ||
revert HelperConfig__InvalidChainId(); | ||
} | ||
} | ||
|
||
function getEthSepoliaConfig() public pure returns (NetworkConfig memory) { | ||
return NetworkConfig({entryPoint: 0x5Ff137d4B0fdCd49dcA30c7Cf57E578D498a27c4, account: BURNER_WALLET}); | ||
} | ||
|
||
function getZkSyncSepoliaConfig() public pure returns (NetworkConfig memory) { | ||
return NetworkConfig({entryPoint: address(0), account: BURNER_WALLET}); | ||
} | ||
|
||
function getOrCreateAnvilEthConfig() public returns (NetworkConfig memory) { | ||
if (localNetworkConfig.entryPoint != address(0)) { | ||
return localNetworkConfig; | ||
} | ||
// deploy a mock | ||
EntryPoint entryPoint; | ||
console2.log("Deploying a mock EntryPoint"); | ||
vm.startBroadcast(ANVIL_DEFAULT_ACCOUNT); | ||
entryPoint = new EntryPoint(); | ||
vm.stopBroadcast(); | ||
|
||
localNetworkConfig = NetworkConfig({entryPoint: address(entryPoint), account: ANVIL_DEFAULT_ACCOUNT}); | ||
return localNetworkConfig; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.20; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
import {HelperConfig} from "./HelperConfig.s.sol"; | ||
import {PackedUserOperation} from "lib/account-abstraction/contracts/interfaces/PackedUserOperation.sol"; | ||
import {IEntryPoint} from "lib/account-abstraction/contracts/interfaces/IEntryPoint.sol"; | ||
import {MessageHashUtils} from "lib/openzeppelin-contracts/contracts/utils/cryptography/MessageHashUtils.sol"; | ||
|
||
contract SendPackedUserOp is Script { | ||
using MessageHashUtils for bytes32; | ||
|
||
function run() external {} | ||
|
||
function generateSignedUserOps( | ||
bytes memory functionData, | ||
HelperConfig.NetworkConfig memory config, | ||
address minimalAccount | ||
) public view returns (PackedUserOperation memory) { | ||
// Add validation for EntryPoint address | ||
// require(config.entryPoint != address(0), "EntryPoint address cannot be zero"); | ||
|
||
//1. Generate the unsigned userOps | ||
uint256 nonce = vm.getNonce(minimalAccount) - 1; | ||
PackedUserOperation memory userOp = _generateUnsignedUserOps(functionData, address(minimalAccount), nonce); | ||
|
||
// Get the userOp Hash | ||
bytes32 userOpHash = IEntryPoint(config.entryPoint).getUserOpHash(userOp); | ||
bytes32 digest = userOpHash.toEthSignedMessageHash(); | ||
|
||
//2. Sign the userOps | ||
uint8 v; | ||
bytes32 r; | ||
bytes32 s; | ||
uint256 ANVIL_DEFAULT_KEY = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80; | ||
if (block.chainid == 31337) { | ||
(v, r, s) = vm.sign(ANVIL_DEFAULT_KEY, digest); | ||
} else { | ||
(v, r, s) = vm.sign(config.account, digest); | ||
} | ||
userOp.signature = abi.encodePacked(r, s, v); | ||
|
||
//3. Return the signed userOps | ||
return userOp; | ||
} | ||
|
||
function _generateUnsignedUserOps(bytes memory functionData, address sender, uint256 nonce) | ||
internal | ||
pure | ||
returns (PackedUserOperation memory) | ||
{ | ||
// Set more reasonable gas limits | ||
uint128 verificationGasLimit = 16777216; | ||
uint128 callGasLimit = verificationGasLimit; // Add explicit call gas limit | ||
uint128 maxPriorityFeePerGas = 256; // 0.1 gwei | ||
uint128 maxFeePerGas = maxPriorityFeePerGas; | ||
bytes32 gasLimits = bytes32((uint256(verificationGasLimit) << 128) | uint256(callGasLimit)); | ||
|
||
return PackedUserOperation({ | ||
sender: sender, | ||
nonce: nonce, | ||
initCode: hex"", | ||
callData: functionData, | ||
accountGasLimits: gasLimits, // Combined verification and call gas limits | ||
preVerificationGas: verificationGasLimit, // Standard transaction base cost | ||
gasFees: bytes32(uint256(maxPriorityFeePerGas) << 128 | uint256(maxFeePerGas)), | ||
paymasterAndData: hex"", | ||
signature: hex"" | ||
}); | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.