Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions src/accounts/erc7579/ERC7579Factory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,73 @@ contract ERC7579Factory is IAccountFactory, ERC7579Precompiles {
return deployMSAPRoxy(salt, address(implementation), initCode);
}

function createAccountWithModules(
bytes32 salt,
ERC7579BootstrapConfig[] calldata validators,
ERC7579BootstrapConfig[] calldata executors,
ERC7579BootstrapConfig calldata _fallback,
ERC7579BootstrapConfig[] calldata hooks
)
public
payable
virtual
returns (address)
{
bytes memory initData = abi.encode(
bootstrapDefault,
abi.encodeCall(IERC7579Bootstrap.initMSA, (validators, executors, _fallback, hooks))
);

address account = deployMSAPRoxy(salt, address(implementation), initData);

return account;
}

function getInitData(bytes memory initCode) public view returns (bytes memory _init) {
(
ERC7579BootstrapConfig[] memory _validators,
ERC7579BootstrapConfig[] memory _executors,
ERC7579BootstrapConfig memory hook,
ERC7579BootstrapConfig[] memory fallbacks
) = abi.decode(
initCode,
(
ERC7579BootstrapConfig[],
ERC7579BootstrapConfig[],
ERC7579BootstrapConfig,
ERC7579BootstrapConfig[]
)
);
_init = abi.encode(
address(bootstrapDefault),
abi.encodeCall(IERC7579Bootstrap.initMSA, (_validators, _executors, hook, fallbacks))
);
}

function getInitData(
IAccountFactory.ModuleInitData[] memory _validators,
IAccountFactory.ModuleInitData[] memory _executors,
IAccountFactory.ModuleInitData memory _hook,
IAccountFactory.ModuleInitData[] memory _fallbacks
)
public
view
returns (bytes memory _init)
{
ERC7579BootstrapConfig[] memory validators =
abi.decode(abi.encode(_validators), (ERC7579BootstrapConfig[]));
ERC7579BootstrapConfig[] memory executors =
abi.decode(abi.encode(_executors), (ERC7579BootstrapConfig[]));
ERC7579BootstrapConfig memory hook = abi.decode(abi.encode(_hook), (ERC7579BootstrapConfig));
ERC7579BootstrapConfig[] memory fallbacks =
abi.decode(abi.encode(_fallbacks), (ERC7579BootstrapConfig[]));

_init = abi.encode(
address(bootstrapDefault),
abi.encodeCall(IERC7579Bootstrap.initMSA, (validators, executors, hook, fallbacks))
);
}

function getAddress(
bytes32 salt,
bytes memory initCode
Expand Down
14 changes: 14 additions & 0 deletions src/accounts/factory/interface/IAccountFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
pragma solidity >=0.8.23 <0.9.0;

interface IAccountFactory {
struct ModuleInitData {
address module;
bytes data;
}

function init() external;

function createAccount(
Expand All @@ -19,4 +24,13 @@ interface IAccountFactory {
)
external
returns (bytes memory init);

function getInitData(
IAccountFactory.ModuleInitData[] memory validators,
IAccountFactory.ModuleInitData[] memory executors,
IAccountFactory.ModuleInitData memory hook,
IAccountFactory.ModuleInitData[] memory fallbacks
)
external
returns (bytes memory _init);
}
119 changes: 119 additions & 0 deletions src/accounts/kernel/KernelFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ import { IHook } from "../../accounts/kernel/interfaces/IERC7579Module.sol";
import { IAccountFactory } from "../../accounts/factory/interface/IAccountFactory.sol";
import { MockHookMultiPlexer } from "../../Mocks.sol";
import { KernelPrecompiles } from "../../deployment/precompiles/KernelPrecompiles.sol";
import {
MODULE_TYPE_VALIDATOR,
MODULE_TYPE_EXECUTOR,
MODULE_TYPE_FALLBACK
} from "./types/Constants.sol";

struct ModuleBootstrapConfig {
address module;
bytes initData;
}

contract KernelFactory is IAccountFactory, KernelPrecompiles {
IKernelAccountFactory internal factory;
Expand Down Expand Up @@ -56,6 +66,115 @@ contract KernelFactory is IAccountFactory, KernelPrecompiles {
);
}

function getInitData(
IAccountFactory.ModuleInitData[] memory validators,
IAccountFactory.ModuleInitData[] memory executors,
IAccountFactory.ModuleInitData memory hook,
IAccountFactory.ModuleInitData[] memory fallbacks
)
public
pure
override
returns (bytes memory _init)
{
address[] memory attesters = new address[](1);
attesters[0] = address(0x000000333034E9f539ce08819E12c1b8Cb29084d);

ValidationId rootValidator =
ValidatorLib.validatorToIdentifier(IValidator(validators[0].module));
// Encode the rest of the validators, executors and fallbacks are onInstall calls with the
// appropriate address and initData
bytes[] memory otherModules =
new bytes[](validators.length - 1 + executors.length + fallbacks.length);
uint256 index = 0;
for (uint256 i = 1; i < validators.length; i++) {
otherModules[index] = abi.encodeCall(
IKernel.installModule,
(MODULE_TYPE_VALIDATOR, validators[i].module, validators[i].data)
);
index++;
}
for (uint256 i = 0; i < executors.length; i++) {
otherModules[index] = abi.encodeCall(
IKernel.installModule,
(MODULE_TYPE_EXECUTOR, executors[i].module, executors[i].data)
);
index++;
}
for (uint256 i = 0; i < fallbacks.length; i++) {
otherModules[index] = abi.encodeCall(
IKernel.installModule,
(MODULE_TYPE_FALLBACK, fallbacks[i].module, fallbacks[i].data)
);
index++;
}
_init = abi.encodeCall(
IKernel.initialize,
(
rootValidator,
IHook(address(hook.module)),
validators[0].data,
hook.data,
otherModules
)
);
}

function getInitData(bytes memory initData) public pure returns (bytes memory _init) {
(
ModuleBootstrapConfig[] memory validators,
ModuleBootstrapConfig[] memory executors,
ModuleBootstrapConfig memory hook,
ModuleBootstrapConfig[] memory fallbacks
) = abi.decode(
initData,
(
ModuleBootstrapConfig[],
ModuleBootstrapConfig[],
ModuleBootstrapConfig,
ModuleBootstrapConfig[]
)
);
ValidationId rootValidator =
ValidatorLib.validatorToIdentifier(IValidator(validators[0].module));
// Encode the rest of the validators, executors and fallbacks are onInstall calls with the
// appropriate address and initData
bytes[] memory otherModules =
new bytes[](validators.length - 1 + executors.length + fallbacks.length);
uint256 index = 0;
for (uint256 i = 1; i < validators.length; i++) {
otherModules[index] = abi.encodeCall(
IKernel.installModule,
(MODULE_TYPE_VALIDATOR, validators[i].module, validators[i].initData)
);
index++;
}
for (uint256 i = 0; i < executors.length; i++) {
otherModules[index] = abi.encodeCall(
IKernel.installModule,
(MODULE_TYPE_EXECUTOR, executors[i].module, executors[i].initData)
);
index++;
}
for (uint256 i = 0; i < fallbacks.length; i++) {
otherModules[index] = abi.encodeCall(
IKernel.installModule,
(MODULE_TYPE_FALLBACK, fallbacks[i].module, fallbacks[i].initData)
);
index++;
}
_init = abi.encodeCall(
IKernel.initialize,
(
rootValidator,
IHook(address(hook.module)),
validators[0].initData,
hook.initData,
otherModules
)
);
}

function setHookMultiPlexer(address hook) public {
hookMultiPlexer = MockHookMultiPlexer(hook);
}
Expand Down
86 changes: 86 additions & 0 deletions src/accounts/nexus/NexusFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,90 @@ contract NexusFactory is IAccountFactory, NexusPrecompiles {
config, IERC7484(REGISTRY_ADDR), attesters, 1
);
}

function createAccountWithModules(
bytes32 salt,
NexusBootstrapConfig[] calldata validators,
NexusBootstrapConfig[] calldata executors,
NexusBootstrapConfig calldata hook,
NexusBootstrapConfig[] calldata fallbacks
)
public
payable
virtual
returns (address)
{
address[] memory attesters = new address[](1);
attesters[0] = address(0x000000333034E9f539ce08819E12c1b8Cb29084d);

bytes memory initData = abi.encode(
bootstrapDefault,
abi.encodeCall(
INexusBootstrap.initNexus,
(validators, executors, hook, fallbacks, IERC7484(REGISTRY_ADDR), attesters, 1)
)
);

address account = deployNexusProxy(salt, nexusImpl, initData);

return account;
}

function getInitData(
IAccountFactory.ModuleInitData[] memory _validators,
IAccountFactory.ModuleInitData[] memory _executors,
IAccountFactory.ModuleInitData memory _hook,
IAccountFactory.ModuleInitData[] memory _fallbacks
)
public
view
override
returns (bytes memory _init)
{
NexusBootstrapConfig[] memory validators =
abi.decode(abi.encode(_validators), (NexusBootstrapConfig[]));
NexusBootstrapConfig[] memory executors =
abi.decode(abi.encode(_executors), (NexusBootstrapConfig[]));
NexusBootstrapConfig memory hook = abi.decode(abi.encode(_hook), (NexusBootstrapConfig));
NexusBootstrapConfig[] memory fallbacks =
abi.decode(abi.encode(_fallbacks), (NexusBootstrapConfig[]));

address[] memory attesters = new address[](1);
attesters[0] = address(0x000000333034E9f539ce08819E12c1b8Cb29084d);

_init = abi.encode(
address(bootstrapDefault),
abi.encodeCall(
INexusBootstrap.initNexus,
(validators, executors, hook, fallbacks, IERC7484(REGISTRY_ADDR), attesters, 1)
)
);
}

function getInitData(bytes memory initData) public view returns (bytes memory _init) {
(
NexusBootstrapConfig[] memory validators,
NexusBootstrapConfig[] memory executors,
NexusBootstrapConfig memory hook,
NexusBootstrapConfig[] memory fallbacks
) = abi.decode(
initData,
(
NexusBootstrapConfig[],
NexusBootstrapConfig[],
NexusBootstrapConfig,
NexusBootstrapConfig[]
)
);
address[] memory attesters = new address[](1);
attesters[0] = address(0x000000333034E9f539ce08819E12c1b8Cb29084d);

_init = abi.encode(
address(bootstrapDefault),
abi.encodeCall(
INexusBootstrap.initNexus,
(validators, executors, hook, fallbacks, IERC7484(REGISTRY_ADDR), attesters, 1)
)
);
}
}
71 changes: 71 additions & 0 deletions src/accounts/safe/SafeFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,75 @@ contract SafeFactory is IAccountFactory, Safe7579Precompiles {
});
_init = abi.encode(initDataSafe);
}

function getInitData(
IAccountFactory.ModuleInitData[] memory _validators,
IAccountFactory.ModuleInitData[] memory _executors,
IAccountFactory.ModuleInitData memory _hook,
IAccountFactory.ModuleInitData[] memory _fallbacks
)
public
view
returns (bytes memory _init)
{
ModuleInit[] memory validators = abi.decode(abi.encode(_validators), (ModuleInit[]));
ModuleInit[] memory executors = abi.decode(abi.encode(_executors), (ModuleInit[]));
ModuleInit memory hook = abi.decode(abi.encode(_hook), (ModuleInit));
ModuleInit[] memory hooks = new ModuleInit[](1);
hooks[0] = hook;
ModuleInit[] memory fallbacks = abi.decode(abi.encode(_fallbacks), (ModuleInit[]));

ISafe7579Launchpad.InitData memory initDataSafe = ISafe7579Launchpad.InitData({
singleton: address(safeSingleton),
owners: Solarray.addresses(makeAddr("owner1")),
threshold: 1,
setupTo: address(launchpad),
setupData: abi.encodeCall(
ISafe7579Launchpad.initSafe7579,
(
address(safe7579),
executors,
fallbacks,
hooks,
Solarray.addresses(makeAddr("attester1"), makeAddr("attester2")),
2
)
),
safe7579: ISafe7579(safe7579),
validators: validators,
callData: ""
});
_init = abi.encode(initDataSafe);
}

function getInitData(bytes memory initData) public view returns (bytes memory _init) {
(
ModuleInit[] memory validators,
ModuleInit[] memory executors,
ModuleInit[] memory hooks,
ModuleInit[] memory fallbacks
) = abi.decode(initData, (ModuleInit[], ModuleInit[], ModuleInit[], ModuleInit[]));
ISafe7579Launchpad.InitData memory initDataSafe = ISafe7579Launchpad.InitData({
singleton: address(safeSingleton),
owners: Solarray.addresses(makeAddr("owner1")),
threshold: 1,
setupTo: address(launchpad),
setupData: abi.encodeCall(
ISafe7579Launchpad.initSafe7579,
(
address(safe7579),
executors,
fallbacks,
hooks,
Solarray.addresses(makeAddr("attester1"), makeAddr("attester2")),
2
)
),
safe7579: ISafe7579(safe7579),
validators: validators,
callData: ""
});

_init = abi.encode(initDataSafe);
}
}
Loading
Loading