Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: codesize reduction #231

Merged
merged 25 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
aaf4fd0
refactor: combine SMA specific functions
Zer0dot Oct 7, 2024
813a988
refactor: remove domain separator as it can be precomputed
Zer0dot Oct 7, 2024
fbfea09
refactor: refactor create and create2 into the same function
Zer0dot Oct 11, 2024
bc538e6
feat: refactor execution install functions into external lib
Zer0dot Oct 11, 2024
f255d01
chore: snapshots
Zer0dot Oct 11, 2024
8f8bafe
refactor: refactor ExecutionInstallLib to external contract
Zer0dot Oct 11, 2024
af1889b
feat: add onlyDelegateCall modifier
Zer0dot Oct 11, 2024
7d20635
chore: update snapshots and test
Zer0dot Oct 11, 2024
a1447d2
test: add fuzz test for sma flow
Zer0dot Oct 15, 2024
05db3ce
chore: fix rebase changes
Zer0dot Oct 16, 2024
c24aeb7
chore: prep
Zer0dot Oct 16, 2024
8af5a9a
fix: add missing comments
Zer0dot Oct 16, 2024
5a97c5a
refactor: move delegatecall to assembly
Zer0dot Oct 16, 2024
9d3a7e0
refactor: make known selectors use uint32
Zer0dot Oct 16, 2024
e253b5e
feat: modify native function check to be external lib based
Zer0dot Oct 16, 2024
4eddf15
feat: native function delegate
Zer0dot Oct 16, 2024
2b427d7
refactor: reduce unnecessary error params
Zer0dot Oct 16, 2024
3f085a3
fix: fix incorrect test error
Zer0dot Oct 16, 2024
5b45362
chore: NatSpec
Zer0dot Oct 16, 2024
fbdd8cd
chore: slight cleanup
Zer0dot Oct 16, 2024
85ed3ce
fix: fix rebase errors
Zer0dot Oct 16, 2024
8b3da4f
chore: remove unused errors
Zer0dot Oct 16, 2024
cd9e37f
chore: update optimizer runs
Zer0dot Oct 16, 2024
7f8cbe6
chore: uncomment parameters
Zer0dot Oct 16, 2024
d7d699a
chore: update fallback natspec
Zer0dot Oct 16, 2024
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
Original file line number Diff line number Diff line change
@@ -1 +1 @@
176008
175965
Original file line number Diff line number Diff line change
@@ -1 +1 @@
93101
92963
2 changes: 1 addition & 1 deletion .forge-snapshots/ModularAccount_Runtime_Erc20Transfer.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
78526
78372
Original file line number Diff line number Diff line change
@@ -1 +1 @@
423482
422934
Original file line number Diff line number Diff line change
@@ -1 +1 @@
54675
54521
Original file line number Diff line number Diff line change
@@ -1 +1 @@
78838
78584
Original file line number Diff line number Diff line change
@@ -1 +1 @@
112223
111897
2 changes: 1 addition & 1 deletion .forge-snapshots/ModularAccount_UserOp_BatchTransfers.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
198437
198297
2 changes: 1 addition & 1 deletion .forge-snapshots/ModularAccount_UserOp_Erc20Transfer.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
185406
185250
Original file line number Diff line number Diff line change
@@ -1 +1 @@
531716
531166
2 changes: 1 addition & 1 deletion .forge-snapshots/ModularAccount_UserOp_NativeTransfer.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
161687
161531
Original file line number Diff line number Diff line change
@@ -1 +1 @@
195559
195236
Original file line number Diff line number Diff line change
@@ -1 +1 @@
226591
226220
Original file line number Diff line number Diff line change
@@ -1 +1 @@
261264
260935
Original file line number Diff line number Diff line change
@@ -1 +1 @@
89199
88968
Original file line number Diff line number Diff line change
@@ -1 +1 @@
74716
74425
Original file line number Diff line number Diff line change
@@ -1 +1 @@
422162
421505
Original file line number Diff line number Diff line change
@@ -1 +1 @@
50875
50584
Original file line number Diff line number Diff line change
@@ -1 +1 @@
79254
78934
Original file line number Diff line number Diff line change
@@ -1 +1 @@
112639
112247
Original file line number Diff line number Diff line change
@@ -1 +1 @@
193639
193462
Original file line number Diff line number Diff line change
@@ -1 +1 @@
180735
180498
Original file line number Diff line number Diff line change
@@ -1 +1 @@
529289
528686
Original file line number Diff line number Diff line change
@@ -1 +1 @@
157010
156773
Original file line number Diff line number Diff line change
@@ -1 +1 @@
195853
195464
Original file line number Diff line number Diff line change
@@ -1 +1 @@
226897
226460
Original file line number Diff line number Diff line change
@@ -1 +1 @@
257961
257489
4 changes: 2 additions & 2 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ depth = 10
deny_warnings = true
via_ir = true
test = 'src'
optimizer_runs = 10000
optimizer_runs = 15000
out = 'out-optimized'
cache_path = 'cache-optimized'

Expand Down Expand Up @@ -59,7 +59,7 @@ depth = 32
via_ir = true
deny_warnings = true
test = 'gas'
optimizer_runs = 10000
optimizer_runs = 15000
out = 'out-optimized'
cache_path = 'cache-optimized'
ffi = true
Expand Down
63 changes: 22 additions & 41 deletions src/account/ModularAccountBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/Messa
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {UUPSUpgradeable} from "solady/utils/UUPSUpgradeable.sol";

import {ExecutionInstallDelegate} from "../helpers/ExecutionInstallDelegate.sol";
import {_coalescePreValidation, _coalesceValidation} from "../helpers/ValidationResHelpers.sol";
import {
DensePostHookData,
Expand Down Expand Up @@ -89,6 +90,8 @@ abstract contract ModularAccountBase is
uint8 internal constant _IS_GLOBAL_VALIDATION_BIT = 1;
uint8 internal constant _HAS_DEFERRED_ACTION_BIT = 2;

address internal immutable _EXECUTION_INSTALL_DELEGATE;

event DeferredActionNonceInvalidated(uint256 nonce);

error CreateFailed();
Expand All @@ -115,15 +118,19 @@ abstract contract ModularAccountBase is

constructor(IEntryPoint anEntryPoint) AccountBase(anEntryPoint) {
_disableInitializers();

_EXECUTION_INSTALL_DELEGATE = address(new ExecutionInstallDelegate());
}

// EXTERNAL FUNCTIONS

receive() external payable {}

/// @notice Fallback function
/// @dev We route calls to execution functions based on incoming msg.sig
/// @dev If there's no module associated with this function selector, revert
/// @dev Routes calls to execution functions based on the incoming msg.sig. If there's no module associated
/// with this function selector, revert.
///
/// @return The raw returned data from the invoked execution function.
fallback(bytes calldata) external payable returns (bytes memory) {
address execModule = getAccountStorage().executionStorage[msg.sig].module;
if (execModule == address(0)) {
Expand All @@ -144,40 +151,7 @@ abstract contract ModularAccountBase is
/// @param value The value to send to the new contract constructor
/// @param initCode The initCode to deploy.
/// @return createdAddr The created contract address.
function performCreate(uint256 value, bytes calldata initCode)
external
payable
virtual
wrapNativeFunction
returns (address createdAddr)
{
assembly ("memory-safe") {
// Load the free memory pointer.
let fmp := mload(0x40)

// Get the initCode length.
let len := initCode.length

// Copy the initCode from callata to memory at the free memory pointer.
calldatacopy(fmp, initCode.offset, len)

// Create the contract.
createdAddr := create(value, fmp, len)

if iszero(createdAddr) {
// If creation failed (the address returned is zero), revert with CreateFailed().
mstore(0x00, 0x7e16b8cd)
revert(0x1c, 0x04)
}
}
}

/// @notice Creates a contract using create2 deterministic deployment.
/// @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.
/// @return createdAddr The created contract address.
function performCreate2(uint256 value, bytes calldata initCode, bytes32 salt)
function performCreate(uint256 value, bytes calldata initCode, bool isCreate2, bytes32 salt)
external
payable
virtual
Expand All @@ -194,8 +168,9 @@ abstract contract ModularAccountBase is
// Copy the initCode from callata to memory at the free memory pointer.
calldatacopy(fmp, initCode.offset, len)

// Create the contract using Create2 with the passed salt parameter.
createdAddr := create2(value, fmp, len, salt)
switch isCreate2
case 1 { createdAddr := create2(value, fmp, len, salt) }
default { createdAddr := create(value, fmp, len) }

if iszero(createdAddr) {
// If creation failed (the address returned is zero), revert with CreateFailed().
Expand Down Expand Up @@ -320,7 +295,10 @@ abstract contract ModularAccountBase is
ExecutionManifest calldata manifest,
bytes calldata moduleInstallData
) external override wrapNativeFunction {
_installExecution(module, manifest, moduleInstallData);
// Access params to prevent compiler unused parameter flags.
(module, manifest, moduleInstallData);
address delegate = _EXECUTION_INSTALL_DELEGATE;
ExecutionLib.delegatecallBubbleOnRevertTransient(delegate);
}

/// @inheritdoc IModularAccount
Expand All @@ -330,7 +308,10 @@ abstract contract ModularAccountBase is
ExecutionManifest calldata manifest,
bytes calldata moduleUninstallData
) external override wrapNativeFunction {
_uninstallExecution(module, manifest, moduleUninstallData);
// Access params to prevent compiler unused parameter flags.
(module, manifest, moduleUninstallData);
address delegate = _EXECUTION_INSTALL_DELEGATE;
ExecutionLib.delegatecallBubbleOnRevertTransient(delegate);
}

/// @inheritdoc IModularAccount
Expand Down Expand Up @@ -797,7 +778,7 @@ abstract contract ModularAccountBase is
|| selector == this.installValidation.selector || selector == this.uninstallValidation.selector
|| selector == this.upgradeToAndCall.selector
|| selector == this.invalidateDeferredValidationInstallNonce.selector
|| selector == this.performCreate.selector || selector == this.performCreate2.selector
|| selector == this.performCreate.selector
) {
return true;
}
Expand Down
15 changes: 13 additions & 2 deletions src/account/ModularAccountView.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
ValidationDataView
} from "@erc6900/reference-implementation/interfaces/IModularAccountView.sol";

import {KnownSelectorsLib} from "../libraries/KnownSelectorsLib.sol";
import {NativeFunctionDelegate} from "../helpers/NativeFunctionDelegate.sol";
import {MemManagementLib} from "../libraries/MemManagementLib.sol";
import {ExecutionStorage, ValidationStorage, getAccountStorage} from "./AccountStorage.sol";

Expand All @@ -17,11 +17,18 @@ import {ExecutionStorage, ValidationStorage, getAccountStorage} from "./AccountS
/// @notice This abstract contract implements the two view functions to get validation and execution data for an
/// account.
abstract contract ModularAccountView is IModularAccountView {
NativeFunctionDelegate internal immutable _NATIVE_FUNCTION_DELEGATE;

constructor() {
_NATIVE_FUNCTION_DELEGATE = new NativeFunctionDelegate();
}

/// @inheritdoc IModularAccountView
function getExecutionData(bytes4 selector) external view override returns (ExecutionDataView memory data) {
// return ModularAccountViewLib.getExecutionData(selector, _isNativeFunction(selector));
ExecutionStorage storage executionStorage = getAccountStorage().executionStorage[selector];

if (KnownSelectorsLib.isNativeFunction(selector)) {
if (_isNativeFunction(uint32(selector))) {
data.module = address(this);
data.allowGlobalValidation = true;
} else {
Expand Down Expand Up @@ -57,4 +64,8 @@ abstract contract ModularAccountView is IModularAccountView {
MemManagementLib.reverseArr(selectors);
data.selectors = selectors;
}

function _isNativeFunction(uint32 selector) internal view virtual returns (bool) {
return _NATIVE_FUNCTION_DELEGATE.isNativeFunction(selector);
}
}
Loading
Loading