@@ -21,6 +21,7 @@ abstract contract BaseLightAccount is BaseAccount, TokenCallbackHandler, UUPSUpg
2121 }
2222
2323 error ArrayLengthMismatch ();
24+ error CreateFailed ();
2425 error InvalidSignatureType ();
2526 error NotAuthorized (address caller );
2627 error ZeroAddressNotAllowed ();
@@ -75,6 +76,71 @@ abstract contract BaseLightAccount is BaseAccount, TokenCallbackHandler, UUPSUpg
7576 }
7677 }
7778
79+ /// @notice Creates a contract.
80+ /// @param value The value to send to the new contract constructor.
81+ /// @param initCode The initCode to deploy.
82+ /// @return createdAddr The created contract address.
83+ ///
84+ /// @dev Assembly procedure:
85+ /// 1. Load the free memory pointer.
86+ /// 2. Get the initCode length.
87+ /// 3. Copy the initCode from callata to memory at the free memory pointer.
88+ /// 4. Create the contract.
89+ /// 5. If creation failed (the address returned is zero), revert with CreateFailed().
90+ function performCreate (uint256 value , bytes calldata initCode )
91+ external
92+ payable
93+ virtual
94+ onlyAuthorized
95+ returns (address createdAddr )
96+ {
97+ assembly ("memory-safe" ) {
98+ let fmp := mload (0x40 )
99+ let len := initCode.length
100+ calldatacopy (fmp, initCode.offset, len)
101+
102+ createdAddr := create (value, fmp, len)
103+
104+ if iszero (createdAddr) {
105+ mstore (0x00 , 0x7e16b8cd )
106+ revert (0x1c , 0x04 )
107+ }
108+ }
109+ }
110+
111+ /// @notice Creates a contract using create2 deterministic deployment.
112+ /// @param value The value to send to the new contract constructor.
113+ /// @param initCode The initCode to deploy.
114+ /// @param salt The salt to use for the create2 operation.
115+ /// @return createdAddr The created contract address.
116+ ///
117+ /// @dev Assembly procedure:
118+ /// 1. Load the free memory pointer.
119+ /// 2. Get the initCode length.
120+ /// 3. Copy the initCode from callata to memory at the free memory pointer.
121+ /// 4. Create the contract using Create2 with the passed salt parameter.
122+ /// 5. If creation failed (the address returned is zero), revert with CreateFailed().
123+ function performCreate2 (uint256 value , bytes calldata initCode , bytes32 salt )
124+ external
125+ payable
126+ virtual
127+ onlyAuthorized
128+ returns (address createdAddr )
129+ {
130+ assembly ("memory-safe" ) {
131+ let fmp := mload (0x40 )
132+ let len := initCode.length
133+ calldatacopy (fmp, initCode.offset, len)
134+
135+ createdAddr := create2 (value, fmp, len, salt)
136+
137+ if iszero (createdAddr) {
138+ mstore (0x00 , 0x7e16b8cd )
139+ revert (0x1c , 0x04 )
140+ }
141+ }
142+ }
143+
78144 /// @notice Deposit more funds for this account in the entry point.
79145 function addDeposit () external payable {
80146 entryPoint ().depositTo {value: msg .value }(address (this ));
@@ -122,11 +188,25 @@ abstract contract BaseLightAccount is BaseAccount, TokenCallbackHandler, UUPSUpg
122188 return success ? SIG_VALIDATION_SUCCESS : SIG_VALIDATION_FAILED;
123189 }
124190
191+ /// @dev Assembly procedure:
192+ /// 1. Execute the call, passing:
193+ /// 1. The gas
194+ /// 2. The target address
195+ /// 3. The call value
196+ /// 4. The pointer to the start location of the callData in memory
197+ /// 5. The length of the calldata
198+ /// 2. If the call failed, bubble up the revert reason by doing the following:
199+ /// 1. Load the free memory pointer
200+ /// 2. Copy the return data (which is the revert reason) to memory at the free memory pointer
201+ /// 3. Revert with the copied return data
125202 function _call (address target , uint256 value , bytes memory data ) internal {
126- (bool success , bytes memory result ) = target.call {value: value}(data);
127- if (! success) {
128- assembly ("memory-safe" ) {
129- revert (add (result, 32 ), mload (result))
203+ assembly ("memory-safe" ) {
204+ let succ := call (gas (), target, value, add (data, 0x20 ), mload (data), 0x00 , 0 )
205+
206+ if iszero (succ) {
207+ let fmp := mload (0x40 )
208+ returndatacopy (fmp, 0x00 , returndatasize ())
209+ revert (fmp, returndatasize ())
130210 }
131211 }
132212 }
0 commit comments