Skip to content

Commit 47f61d2

Browse files
committed
test
1 parent e46bb5e commit 47f61d2

File tree

5 files changed

+59
-111
lines changed

5 files changed

+59
-111
lines changed

script/DeployMinimal.s.sol

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ import {HelperConfig} from "./HelperConfig.s.sol";
88
contract DeployMinimal is Script {
99
function run() public {}
1010

11-
function deployMinimalAccount()
12-
public
13-
returns (HelperConfig, MinimalAccount)
14-
{
11+
function deployMinimalAccount() public returns (HelperConfig, MinimalAccount) {
1512
HelperConfig helperConfig = new HelperConfig();
1613
HelperConfig.NetworkConfig memory config = helperConfig.getConfig();
1714

script/HelperConfig.s.sol

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ contract HelperConfig is Script {
2020
// address constant FOUNDRY_DEFAULT_WALLET =
2121
// 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38;
2222

23-
address constant ANVIL_DEFAULT_ACCOUNT =
24-
0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
23+
address constant ANVIL_DEFAULT_ACCOUNT = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
2524

2625
NetworkConfig public localNetworkConfig;
2726
mapping(uint256 chainId => NetworkConfig) public networkConfigs;
@@ -34,9 +33,7 @@ contract HelperConfig is Script {
3433
return getConfigByChainId(block.chainid);
3534
}
3635

37-
function getConfigByChainId(
38-
uint256 chainId
39-
) public returns (NetworkConfig memory) {
36+
function getConfigByChainId(uint256 chainId) public returns (NetworkConfig memory) {
4037
if (chainId == LOCAL) {
4138
return getOrCreateAnvilEthConfig();
4239
} else if (networkConfigs[chainId].account != address(0)) {
@@ -47,11 +44,7 @@ contract HelperConfig is Script {
4744
}
4845

4946
function getAMOYConfig() public pure returns (NetworkConfig memory) {
50-
return
51-
NetworkConfig({
52-
entryPoint: 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789,
53-
account: BURNER_WALLET
54-
});
47+
return NetworkConfig({entryPoint: 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789, account: BURNER_WALLET});
5548
}
5649

5750
function ZKConfig() public pure returns (NetworkConfig memory) {

script/SendPackedUserOp.s.sol

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,16 @@ contract SendPackedUserOp is Script {
1313

1414
function run() public {}
1515

16-
function generateSignedUserOperation(
17-
bytes memory callData,
18-
HelperConfig.NetworkConfig memory config
19-
) public view returns (PackedUserOperation memory, bytes32) {
16+
function generateSignedUserOperation(bytes memory callData, HelperConfig.NetworkConfig memory config)
17+
public
18+
view
19+
returns (PackedUserOperation memory, bytes32)
20+
{
2021
// 1 . Generate the unsigned data
2122
uint256 nonce = vm.getNonce(config.account);
22-
PackedUserOperation memory userOp = _generateUnsignedUserOperation(
23-
callData,
24-
config.account,
25-
nonce
26-
);
23+
PackedUserOperation memory userOp = _generateUnsignedUserOperation(callData, config.account, nonce);
2724
// 2. Get the userOpHash
28-
bytes32 userOpHash = IEntryPoint(config.entryPoint).getUserOpHash(
29-
userOp
30-
);
25+
bytes32 userOpHash = IEntryPoint(config.entryPoint).getUserOpHash(userOp);
3126

3227
bytes32 digest = userOpHash.toEthSignedMessageHash();
3328

@@ -37,8 +32,8 @@ contract SendPackedUserOp is Script {
3732

3833
uint256 ANVIL_DEFAULT_KEY = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80;
3934
if (block.chainid == 31337) {
40-
(v, r, s) = vm.sign(ANVIL_DEFAULT_KEY, digest);
41-
userOp.signature = abi.encodePacked(r, s, v);
35+
(v, r, s) = vm.sign(ANVIL_DEFAULT_KEY, digest); // here the issue will come because the foundry is yet to add wallet instead of pvt key support
36+
userOp.signature = abi.encodePacked(r, s, v); // 65 bytes in length
4237
} else {
4338
// 3. Sign it and return it
4439
(v, r, s) = vm.sign(config.account, digest);
@@ -62,31 +57,26 @@ contract SendPackedUserOp is Script {
6257
}
6358
*/
6459

65-
function _generateUnsignedUserOperation(
66-
bytes memory callData,
67-
address sender,
68-
uint256 nonce
69-
) internal pure returns (PackedUserOperation memory) {
60+
function _generateUnsignedUserOperation(bytes memory callData, address sender, uint256 nonce)
61+
internal
62+
pure
63+
returns (PackedUserOperation memory)
64+
{
7065
uint128 verificationGasLimit = 16777216;
7166
uint128 callGasLimit = verificationGasLimit;
7267

7368
uint128 maxPriorityFeePerGas = 256;
7469
uint128 maxFeePerGas = maxPriorityFeePerGas;
75-
return
76-
PackedUserOperation({
77-
sender: sender,
78-
nonce: nonce,
79-
initCode: hex"",
80-
callData: callData,
81-
accountGasLimits: bytes32(
82-
(uint256(verificationGasLimit) << 128) | callGasLimit
83-
),
84-
preVerificationGas: verificationGasLimit,
85-
gasFees: bytes32(
86-
(uint256(maxPriorityFeePerGas) << 128) | maxFeePerGas
87-
),
88-
paymasterAndData: hex"",
89-
signature: hex""
90-
});
70+
return PackedUserOperation({
71+
sender: sender,
72+
nonce: nonce,
73+
initCode: hex"",
74+
callData: callData,
75+
accountGasLimits: bytes32((uint256(verificationGasLimit) << 128) | callGasLimit),
76+
preVerificationGas: verificationGasLimit,
77+
gasFees: bytes32((uint256(maxPriorityFeePerGas) << 128) | maxFeePerGas),
78+
paymasterAndData: hex"",
79+
signature: hex""
80+
});
9181
}
9282
}

src/Ethereum/Minimal-Account.sol

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,16 @@ contract MinimalAccount is IAccount, Ownable {
3333
IEntryPoint private immutable i_entryPoint;
3434

3535
modifier requireFromEntryPoint() {
36-
if (msg.sender != address(i_entryPoint))
36+
if (msg.sender != address(i_entryPoint)) {
3737
revert MinimalAccount_NotFromEntryPoint();
38+
}
3839
_;
3940
}
4041

4142
modifier requireFromEntryPointOrOwner() {
42-
if (msg.sender != address(i_entryPoint) && msg.sender != owner())
43+
if (msg.sender != address(i_entryPoint) && msg.sender != owner()) {
4344
revert MinimalAccount_NotFromEntryPointOrOwner();
45+
}
4446
_;
4547
}
4648

@@ -49,24 +51,23 @@ contract MinimalAccount is IAccount, Ownable {
4951
}
5052

5153
/// @dev This function will validate the userOp basically like a signature verification
52-
function validateUserOp(
53-
PackedUserOperation calldata userOp,
54-
bytes32 userOpHash,
55-
uint256 missingAccountFunds
56-
) external requireFromEntryPoint returns (uint256 validationData) {
54+
function validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)
55+
external
56+
requireFromEntryPoint
57+
returns (uint256 validationData)
58+
{
5759
validationData = _validateSignature(userOp, userOpHash);
5860

5961
_payRefund(missingAccountFunds);
6062
}
6163

6264
// EIP-191 version of signed hash
63-
function _validateSignature(
64-
PackedUserOperation calldata userOp,
65-
bytes32 userOpHash
66-
) internal view returns (uint256 validationData) {
67-
bytes32 ethSignedMessageHash = MessageHashUtils.toEthSignedMessageHash(
68-
userOpHash
69-
);
65+
function _validateSignature(PackedUserOperation calldata userOp, bytes32 userOpHash)
66+
internal
67+
view
68+
returns (uint256 validationData)
69+
{
70+
bytes32 ethSignedMessageHash = MessageHashUtils.toEthSignedMessageHash(userOpHash);
7071

7172
address signer = ECDSA.recover(ethSignedMessageHash, userOp.signature);
7273

@@ -78,10 +79,7 @@ contract MinimalAccount is IAccount, Ownable {
7879
}
7980

8081
function _payRefund(uint256 missingAccountFunds) internal {
81-
(bool success, ) = payable(address(i_entryPoint)).call{
82-
value: missingAccountFunds,
83-
gas: type(uint256).max
84-
}("");
82+
(bool success,) = payable(address(i_entryPoint)).call{value: missingAccountFunds, gas: type(uint256).max}("");
8583

8684
(success);
8785
}
@@ -94,11 +92,7 @@ contract MinimalAccount is IAccount, Ownable {
9492
EXECUTE
9593
//////////////////////////////////////////////////////////////*/
9694

97-
function execute(
98-
address dest,
99-
uint256 value,
100-
bytes calldata funcData
101-
) external requireFromEntryPointOrOwner {
95+
function execute(address dest, uint256 value, bytes calldata funcData) external requireFromEntryPointOrOwner {
10296
(bool success, bytes memory result) = dest.call{value: value}(funcData);
10397
if (!success) revert MinimalAccount_CallFailed(result);
10498
}

test/MinimalAccount.t.sol

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,7 @@ contract MinimalAccountTest is Test {
3939
assertEq(usdc.balanceOf(address(minimalAccount)), 0);
4040
address dest = address(usdc);
4141
uint256 value = 0;
42-
bytes memory functionData = abi.encodeWithSelector(
43-
ERC20Mock.mint.selector,
44-
address(minimalAccount),
45-
AMOUNT
46-
);
42+
bytes memory functionData = abi.encodeWithSelector(ERC20Mock.mint.selector, address(minimalAccount), AMOUNT);
4743

4844
vm.startPrank(minimalAccount.owner());
4945
// vm.deal(minimalAccount.owner(), 10e18);
@@ -57,16 +53,10 @@ contract MinimalAccountTest is Test {
5753
assertEq(usdc.balanceOf(address(minimalAccount)), 0);
5854
address dest = address(usdc);
5955
uint256 value = 0;
60-
bytes memory functionData = abi.encodeWithSelector(
61-
ERC20Mock.mint.selector,
62-
address(minimalAccount),
63-
AMOUNT
64-
);
56+
bytes memory functionData = abi.encodeWithSelector(ERC20Mock.mint.selector, address(minimalAccount), AMOUNT);
6557

6658
vm.prank(randomUser);
67-
vm.expectRevert(
68-
MinimalAccount.MinimalAccount_NotFromEntryPointOrOwner.selector
69-
);
59+
vm.expectRevert(MinimalAccount.MinimalAccount_NotFromEntryPointOrOwner.selector);
7060
minimalAccount.execute(dest, value, functionData);
7161
}
7262

@@ -92,32 +82,16 @@ contract MinimalAccountTest is Test {
9282
assertEq(usdc.balanceOf(address(minimalAccount)), 0);
9383
address dest = address(usdc);
9484
uint256 value = 0;
95-
bytes memory functionData = abi.encodeWithSelector(
96-
ERC20Mock.mint.selector,
97-
address(minimalAccount),
98-
AMOUNT
99-
);
100-
101-
bytes memory executeCallData = abi.encodeWithSelector(
102-
MinimalAccount.execute.selector,
103-
dest,
104-
value,
105-
functionData
106-
);
107-
108-
(PackedUserOperation memory packedUserOperation, ) = sendPackedUserOp
109-
.generateSignedUserOperation(
110-
executeCallData,
111-
helperConfig.getConfig()
112-
);
113-
bytes32 userOperationHash = IEntryPoint(
114-
helperConfig.getConfig().entryPoint
115-
).getUserOpHash(packedUserOperation);
116-
117-
address actualSigner = ECDSA.recover(
118-
userOperationHash.toEthSignedMessageHash(),
119-
packedUserOperation.signature
120-
);
85+
bytes memory functionData = abi.encodeWithSelector(ERC20Mock.mint.selector, address(minimalAccount), AMOUNT);
86+
87+
bytes memory executeCallData =
88+
abi.encodeWithSelector(MinimalAccount.execute.selector, dest, value, functionData);
89+
90+
(PackedUserOperation memory packedUserOperation,) =
91+
sendPackedUserOp.generateSignedUserOperation(executeCallData, helperConfig.getConfig());
92+
bytes32 userOperationHash = IEntryPoint(helperConfig.getConfig().entryPoint).getUserOpHash(packedUserOperation);
93+
94+
address actualSigner = ECDSA.recover(userOperationHash.toEthSignedMessageHash(), packedUserOperation.signature);
12195

12296
assertEq(actualSigner, minimalAccount.owner());
12397
}

0 commit comments

Comments
 (0)