Skip to content

Commit a47f873

Browse files
committed
completed minimal account abstraction for eth
1 parent 7c546a9 commit a47f873

File tree

2 files changed

+60
-7
lines changed

2 files changed

+60
-7
lines changed

script/SendPackedUserOp.s.sol

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@ contract SendPackedUserOp is Script {
1313

1414
function run() public {}
1515

16-
function generateSignedUserOperation(bytes memory callData, HelperConfig.NetworkConfig memory config)
16+
function generateSignedUserOperation(bytes memory callData, HelperConfig.NetworkConfig memory config,address minimalAccount)
1717
public
1818
view
1919
returns (PackedUserOperation memory, bytes32)
2020
{
2121
// 1 . Generate the unsigned data
22-
uint256 nonce = vm.getNonce(config.account);
23-
PackedUserOperation memory userOp = _generateUnsignedUserOperation(callData, config.account, nonce);
22+
// uint256 nonce = vm.getNonce(config.account);
23+
// uint256 nonce = vm.getNonce(minimalAccount);
24+
uint256 nonce = vm.getNonce(minimalAccount)-1;
25+
// PackedUserOperation memory userOp = _generateUnsignedUserOperation(callData, config.account, nonce);
26+
PackedUserOperation memory userOp = _generateUnsignedUserOperation(callData, minimalAccount, nonce);
2427
// 2. Get the userOpHash
2528
bytes32 userOpHash = IEntryPoint(config.entryPoint).getUserOpHash(userOp);
2629

@@ -33,12 +36,12 @@ contract SendPackedUserOp is Script {
3336
uint256 ANVIL_DEFAULT_KEY = 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80;
3437
if (block.chainid == 31337) {
3538
(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
39+
// userOp.signature = abi.encodePacked(r, s, v); // 65 bytes in length
3740
} else {
3841
// 3. Sign it and return it
3942
(v, r, s) = vm.sign(config.account, digest);
40-
userOp.signature = abi.encodePacked(r, s, v); // Note the order
4143
}
44+
userOp.signature = abi.encodePacked(r, s, v); // Note the order
4245

4346
return (userOp, digest);
4447
}

test/MinimalAccount.t.sol

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,63 @@ contract MinimalAccountTest is Test {
8888
abi.encodeWithSelector(MinimalAccount.execute.selector, dest, value, functionData);
8989

9090
(PackedUserOperation memory packedUserOperation,) =
91-
sendPackedUserOp.generateSignedUserOperation(executeCallData, helperConfig.getConfig());
91+
sendPackedUserOp.generateSignedUserOperation(executeCallData, helperConfig.getConfig(),address(minimalAccount));
9292
bytes32 userOperationHash = IEntryPoint(helperConfig.getConfig().entryPoint).getUserOpHash(packedUserOperation);
9393

9494
address actualSigner = ECDSA.recover(userOperationHash.toEthSignedMessageHash(), packedUserOperation.signature);
9595

9696
assertEq(actualSigner, minimalAccount.owner());
9797
}
9898

99-
// function testValidationOfUserOps() public {}
99+
100+
101+
//1. Sign UserOps
102+
// 2. Call Validate userOps
103+
// 3. Assert the return is correct
104+
//
105+
function testValidationOfUserOps() public {
106+
assertEq(usdc.balanceOf(address(minimalAccount)), 0);
107+
address dest = address(usdc);
108+
uint256 value = 0;
109+
bytes memory functionData = abi.encodeWithSelector(ERC20Mock.mint.selector, address(minimalAccount), AMOUNT);
110+
111+
bytes memory executeCallData =
112+
abi.encodeWithSelector(MinimalAccount.execute.selector, dest, value, functionData);
113+
114+
(PackedUserOperation memory packedUserOperation,) =
115+
sendPackedUserOp.generateSignedUserOperation(executeCallData, helperConfig.getConfig(), address(minimalAccount));
116+
bytes32 userOperationHash = IEntryPoint(helperConfig.getConfig().entryPoint).getUserOpHash(packedUserOperation);
117+
uint256 missingAccountFunds = 1e18;
118+
// ACT
119+
vm.prank(helperConfig.getConfig().entryPoint);
120+
uint256 validationData = minimalAccount.validateUserOp(packedUserOperation,userOperationHash,missingAccountFunds);
121+
assertEq(validationData,0);
122+
123+
}
124+
125+
126+
function testEntryPointCanExecuteCommands() public {
127+
assertEq(usdc.balanceOf(address(minimalAccount)), 0);
128+
address dest = address(usdc);
129+
uint256 value = 0;
130+
bytes memory functionData = abi.encodeWithSelector(ERC20Mock.mint.selector, address(minimalAccount), AMOUNT);
131+
132+
bytes memory executeCallData =
133+
abi.encodeWithSelector(MinimalAccount.execute.selector, dest, value, functionData);
134+
135+
(PackedUserOperation memory packedUserOperation,) =
136+
sendPackedUserOp.generateSignedUserOperation(executeCallData, helperConfig.getConfig(), address(minimalAccount));
137+
// bytes32 userOperationHash = IEntryPoint(helperConfig.getConfig().entryPoint).getUserOpHash(packedUserOperation);
138+
// uint256 missingAccountFunds = 1e18;
139+
140+
PackedUserOperation[] memory ops = new PackedUserOperation[](1);
141+
ops[0] = packedUserOperation;
142+
// ACT
143+
vm.deal(address(minimalAccount),1e18);
144+
vm.prank(randomUser);
145+
IEntryPoint(helperConfig.getConfig().entryPoint).handleOps(ops,payable(randomUser));
146+
147+
//Assert
148+
assertEq(usdc.balanceOf(address(minimalAccount)), AMOUNT);
149+
}
100150
}

0 commit comments

Comments
 (0)