Skip to content

Commit

Permalink
feat(create): add performCreate[2] method.
Browse files Browse the repository at this point in the history
  • Loading branch information
andysim3d committed Jul 30, 2024
1 parent c81e712 commit 92149cc
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/account/UpgradeableModularAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ contract UpgradeableModularAccount is
error UnrecognizedFunction(bytes4 selector);
error UserOpNotFromEntryPoint();
error UserOpValidationFunctionMissing(bytes4 selector);
error CreateFailed();

constructor(IEntryPoint anEntryPoint) {
_ENTRY_POINT = anEntryPoint;
Expand Down Expand Up @@ -376,6 +377,52 @@ contract UpgradeableModularAccount is
_postNativeFunction(postExecHooks, postHookArgs);
}

///
/// @param value The value to send to the new contract constructor
/// @param initCode The initCode to deploy.
function performCreate(uint256 value, bytes calldata initCode)
external
payable
virtual
returns (address createdAddr)
{
assembly ("memory-safe") {
let fmp := mload(0x40)
let len := initCode.length
calldatacopy(fmp, initCode.offset, len)

createdAddr := create(value, fmp, len)

if iszero(createdAddr) {
mstore(0x00, 0x7e16b8cd)
revert(0x1c, 0x04)
}
}
}

///
/// @param value The value to send to the new contract constructor.
/// @param initCode The initCode to deploy.
/// @param salt The salt to use for the create2 operation.
function performCreate2(uint256 value, bytes calldata initCode, bytes32 salt)
external
payable
virtual
returns (address createdAddr)
{
assembly ("memory-safe") {
let fmp := mload(0x40)
let len := initCode.length
calldatacopy(fmp, initCode.offset, len)

createdAddr := create2(value, fmp, len, salt)
if iszero(createdAddr) {
mstore(0x00, 0x7e16b8cd)
revert(0x1c, 0x04)
}
}
}

/// @inheritdoc IERC777Recipient
/// @dev Runtime validation is bypassed for this function, but we still allow pre and post exec hooks to be
/// assigned and run.
Expand Down
31 changes: 31 additions & 0 deletions test/account/UpgradeableModularAccount.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,37 @@ contract UpgradeableModularAccountTest is Test {
vm.stopPrank();
}

function testCreate() public {
address account = factory.createAccount(0, owners1);

address expectedAddr = computeCreateAddress(account, vm.getNonce(account));
address returnedAddr = account1.performCreate(
0, abi.encodePacked(type(UpgradeableModularAccount).creationCode, abi.encode(address(entryPoint)))
);

assertEq(address(UpgradeableModularAccount(payable(expectedAddr)).entryPoint()), address(entryPoint));
assertEq(returnedAddr, expectedAddr);
}

function testCreate2() public {
address account = factory.createAccount(0, owners1);

bytes memory initCode =
abi.encodePacked(type(UpgradeableModularAccount).creationCode, abi.encode(address(entryPoint)));
bytes32 initCodeHash = keccak256(initCode);
bytes32 salt = bytes32(hex"01234b");

address expectedAddr = computeCreate2Address(salt, initCodeHash, address(account));
address returnedAddr = account1.performCreate2(0, initCode, salt);

assertEq(address(UpgradeableModularAccount(payable(expectedAddr)).entryPoint()), address(entryPoint));
assertEq(returnedAddr, expectedAddr);

vm.expectRevert(UpgradeableModularAccount.CreateFailed.selector);
// multi-depoly with same salt got reverted
account1.performCreate2(0, initCode, salt);
}

// Internal Functions

function _printStorageReadsAndWrites(address addr) internal {
Expand Down

0 comments on commit 92149cc

Please sign in to comment.