Skip to content

Commit

Permalink
works
Browse files Browse the repository at this point in the history
  • Loading branch information
zeroknots committed Feb 20, 2024
1 parent fee71bc commit 3c650b4
Show file tree
Hide file tree
Showing 8 changed files with 490 additions and 41 deletions.
4 changes: 4 additions & 0 deletions accounts/safe7579/src/SafeERC7579.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import {
} from "@ERC4337/account-abstraction/contracts/core/UserOperationLib.sol";
import { _packValidationData } from "@ERC4337/account-abstraction/contracts/core/Helpers.sol";

import "forge-std/console2.sol";

/**
* @title ERC7579 Adapter for Safe accounts.
* By using Safe's Fallback and Execution modules,
Expand Down Expand Up @@ -358,6 +360,8 @@ contract SafeERC7579 is
_initModuleManager();

(address bootstrap, bytes memory bootstrapCall) = abi.decode(data, (address, bytes));
console2.log("bootstrap: ", bootstrap);

(bool success,) = bootstrap.delegatecall(bootstrapCall);
if (!success) revert AccountInitializationFailed();
}
Expand Down
65 changes: 63 additions & 2 deletions packages/modulekit/src/accountFactory/MultiAccountFactory.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "forge-std/Base.sol";
import "./safe7579/Safe7579Factory.sol";
import "./referenceImpl/RefImplFactory.sol";
import { ERC7579BootstrapConfig } from "../external/ERC7579.sol";

enum AccountType {
DEFAULT,
Expand All @@ -23,7 +24,13 @@ contract MultiAccountFactory is TestBase, Safe7579Factory, RefImplFactory {
}
}

function makeAccount(bytes32 salt, bytes calldata initCode) public returns (address account) {
function createAccount(
bytes32 salt,
bytes calldata initCode
)
public
returns (address account)
{
if (env == AccountType.SAFE7579) {
return _makeSafe(salt, initCode);
} else {
Expand All @@ -36,6 +43,60 @@ contract MultiAccountFactory is TestBase, Safe7579Factory, RefImplFactory {
}

function _makeSafe(bytes32 salt, bytes calldata initCode) public returns (address) {
return _createSafe(address(erc7579Mod), initCode);
return _createSafe(salt, initCode);
}

function getAddress(
bytes32 salt,
bytes memory initCode
)
public
view
virtual
returns (address)
{
if (env == AccountType.SAFE7579) {
return getAddressSafe(salt, initCode);
} else {
return getAddressUMSA(salt, initCode);
}
}

function _getSalt(
bytes32 _salt,
bytes memory initCode
)
public
pure
virtual
override(RefImplFactory, Safe7579Factory)
returns (bytes32 salt)
{
salt = keccak256(abi.encodePacked(_salt, initCode));
}

function getBootstrapCallData(
ERC7579BootstrapConfig[] calldata _validators,
ERC7579BootstrapConfig[] calldata _executors,
ERC7579BootstrapConfig calldata _hook,
ERC7579BootstrapConfig calldata _fallback
)
external
view
returns (bytes memory init)
{
if (env == AccountType.SAFE7579) {
init = abi.encode(
address(bootstrapSafe),
abi.encodeCall(
ERC7579Bootstrap.initMSA, (_validators, _executors, _hook, _fallback)
)
);
} else {
init = abi.encode(
address(bootstrapDefault),
abi.encodeCall(BootstrapSafe.initMSA, (_validators, _executors, _hook, _fallback))
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ interface IMSA {
function initializeAccount(bytes calldata initCode) external;
}

contract RefImplFactory {
abstract contract RefImplFactory {
ERC7579Account internal implementation;
ERC7579Bootstrap internal bootstrapDefault;

constructor() {
implementation = new ERC7579Account();
bootstrapDefault = new ERC7579Bootstrap();
}

function _createUMSA(bytes32 salt, bytes memory initCode) public returns (address account) {
Expand All @@ -20,7 +22,7 @@ contract RefImplFactory {
return account;
}

function getAddress(
function getAddressUMSA(
bytes32 salt,
bytes memory initCode
)
Expand All @@ -42,8 +44,5 @@ contract RefImplFactory {
public
pure
virtual
returns (bytes32 salt)
{
salt = keccak256(abi.encodePacked(_salt, initCode));
}
returns (bytes32 salt);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@ import "@rhinestone/safe7579/src/core/HookManager.sol";

import "../../external/ERC7579.sol";

struct BootstrapConfig {
address module;
bytes data;
}

contract Bootstrap is ModuleManager, HookManager {
contract BootstrapSafe is ModuleManager, HookManager {
function singleInitMSA(IERC7579Validator validator, bytes calldata data) external {
// init validator
_installValidator(address(validator), data);
Expand All @@ -23,10 +19,10 @@ contract Bootstrap is ModuleManager, HookManager {
* calling this function
*/
function initMSA(
BootstrapConfig[] calldata _validators,
BootstrapConfig[] calldata _executors,
BootstrapConfig calldata _hook,
BootstrapConfig calldata _fallback
ERC7579BootstrapConfig[] calldata _validators,
ERC7579BootstrapConfig[] calldata _executors,
ERC7579BootstrapConfig calldata _hook,
ERC7579BootstrapConfig calldata _fallback
)
external
{
Expand All @@ -53,10 +49,10 @@ contract Bootstrap is ModuleManager, HookManager {
}

function _getInitMSACalldata(
BootstrapConfig[] calldata _validators,
BootstrapConfig[] calldata _executors,
BootstrapConfig calldata _hook,
BootstrapConfig calldata _fallback
ERC7579BootstrapConfig[] calldata _validators,
ERC7579BootstrapConfig[] calldata _executors,
ERC7579BootstrapConfig calldata _hook,
ERC7579BootstrapConfig calldata _fallback
)
external
view
Expand Down
43 changes: 31 additions & 12 deletions packages/modulekit/src/accountFactory/safe7579/Safe7579Factory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,27 @@ import { SafeERC7579 } from "@rhinestone/safe7579/src/SafeERC7579.sol";
import "@safe-global/safe-contracts/contracts/Safe.sol";
import { LibClone } from "solady/src/utils/LibClone.sol";

import { Bootstrap } from "./Bootstrap.sol";
import { BootstrapSafe } from "./BootstrapSafe.sol";

contract Safe7579Factory is TestBase {
abstract contract Safe7579Factory is TestBase {
// singletons

SafeERC7579 internal erc7579Mod;
Safe internal safeImpl;

Bootstrap internal bootstrap;
BootstrapSafe internal bootstrapSafe;

constructor() {
// Set up MSA and Factory
erc7579Mod = new SafeERC7579();
safeImpl = new Safe();
bootstrap = new Bootstrap();
bootstrapSafe = new BootstrapSafe();
}

function _createSafe(
address defaultValidator,
bytes calldata initCode
)
internal
returns (address safe)
{
Safe clone = Safe(payable(LibClone.clone(address(safeImpl))));
function _createSafe(bytes32 salt, bytes calldata initCode) internal returns (address safe) {
bytes32 _salt = _getSalt(salt, initCode);
Safe clone =
Safe(payable(LibClone.cloneDeterministic(0, address(safeImpl), initCode, _salt)));

address[] memory signers = new address[](2);
signers[0] = address(0x12345);
Expand All @@ -54,4 +50,27 @@ contract Safe7579Factory is TestBase {

return address(clone);
}

function getAddressSafe(
bytes32 salt,
bytes memory initCode
)
public
view
virtual
returns (address)
{
bytes32 _salt = _getSalt(salt, initCode);
return
LibClone.predictDeterministicAddress(address(safeImpl), initCode, _salt, address(this));
}

function _getSalt(
bytes32 _salt,
bytes memory initCode
)
public
pure
virtual
returns (bytes32 salt);
}
26 changes: 18 additions & 8 deletions packages/modulekit/src/test/RhinestoneModuleKit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity ^0.8.23;

import { Auxiliary, AuxiliaryFactory } from "./Auxiliary.sol";
import { MultiAccountFactory } from "../accountFactory/MultiAccountFactory.sol";
import { PackedUserOperation, IEntryPoint, IStakeManager } from "../external/ERC4337.sol";
import { ERC7579Helpers, BootstrapUtil } from "./utils/ERC7579Helpers.sol";
import { ENTRYPOINT_ADDR } from "./predeploy/EntryPoint.sol";
Expand All @@ -22,6 +23,8 @@ import "./utils/Vm.sol";
import "./utils/ModuleKitCache.sol";
import "./utils/Log.sol";

import "forge-std/console2.sol";

struct AccountInstance {
address account;
Auxiliary aux;
Expand All @@ -37,8 +40,10 @@ struct UserOpData {
}

contract RhinestoneModuleKit is AuxiliaryFactory {
ERC7579AccountFactory public accountFactory;
IERC7579Account public accountImplementationSingleton;
// ERC7579AccountFactory public accountFactory;
// IERC7579Account public accountImplementationSingleton;

MultiAccountFactory public accountFactory;

bool internal isInit;

Expand All @@ -60,11 +65,13 @@ contract RhinestoneModuleKit is AuxiliaryFactory {

isInit = true;

// Deploy default contracts
accountImplementationSingleton = new ERC7579Account();
label(address(accountImplementationSingleton), "ERC7579AccountImpl");
accountFactory = new ERC7579AccountFactory(address(accountImplementationSingleton));
label(address(accountFactory), "ERC7579AccountFactory");
// // Deploy default contracts
// accountImplementationSingleton = new ERC7579Account();
// label(address(accountImplementationSingleton), "ERC7579AccountImpl");
// accountFactory = new ERC7579AccountFactory(address(accountImplementationSingleton));
// label(address(accountFactory), "ERC7579AccountFactory");

accountFactory = new MultiAccountFactory();
defaultValidator = new MockValidator();
label(address(defaultValidator), "DefaultValidator");

Expand Down Expand Up @@ -140,9 +147,12 @@ contract RhinestoneModuleKit is AuxiliaryFactory {
validators = _validators;
}

// bytes memory bootstrapCalldata =
// auxiliary.bootstrap._getInitMSACalldata(validators, executors, hook, fallBack);
bytes memory bootstrapCalldata =
auxiliary.bootstrap._getInitMSACalldata(validators, executors, hook, fallBack);
accountFactory.getBootstrapCallData(validators, executors, hook, fallBack);
address account = accountFactory.getAddress(salt, bootstrapCalldata);
console2.log("Account address: ", account);

// using MSAFactory from ERC7579 repo.
bytes memory createAccountOnFactory =
Expand Down
Loading

0 comments on commit 3c650b4

Please sign in to comment.