Skip to content

Commit

Permalink
refactor: codesize reduction (#231)
Browse files Browse the repository at this point in the history
  • Loading branch information
Zer0dot authored Oct 16, 2024
1 parent dbfd294 commit de20d70
Show file tree
Hide file tree
Showing 52 changed files with 785 additions and 465 deletions.
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

0 comments on commit de20d70

Please sign in to comment.