Skip to content

Commit 06de56d

Browse files
authored
♻️ ERC6551 new executable interface ID (#861)
1 parent 91d5f64 commit 06de56d

File tree

3 files changed

+38
-23
lines changed

3 files changed

+38
-23
lines changed

.gas-snapshot

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -265,23 +265,23 @@ ERC4626Test:testWithdrawWithNoUnderlyingAmountReverts() (gas: 13102)
265265
ERC4626Test:testWithdrawWithNotEnoughUnderlyingAmountReverts() (gas: 144074)
266266
ERC4626Test:testWithdrawZero() (gas: 52807)
267267
ERC4626Test:test__codesize() (gas: 39940)
268-
ERC6551Test:testCdFallback() (gas: 894305)
269-
ERC6551Test:testDeployERC6551(uint256) (runs: 257, μ: 171193, ~: 168789)
268+
ERC6551Test:testCdFallback() (gas: 894295)
269+
ERC6551Test:testDeployERC6551(uint256) (runs: 257, μ: 171077, ~: 168788)
270270
ERC6551Test:testDeployERC6551Proxy() (gas: 80351)
271-
ERC6551Test:testExecute() (gas: 507899)
272-
ERC6551Test:testExecuteBatch() (gas: 817000)
273-
ERC6551Test:testExecuteBatch(uint256) (runs: 257, μ: 627737, ~: 586245)
271+
ERC6551Test:testExecute() (gas: 508100)
272+
ERC6551Test:testExecuteBatch() (gas: 817200)
273+
ERC6551Test:testExecuteBatch(uint256) (runs: 257, μ: 622293, ~: 483183)
274274
ERC6551Test:testInitializeERC6551ProxyImplementation() (gas: 189796)
275275
ERC6551Test:testIsValidSignature() (gas: 187642)
276-
ERC6551Test:testIsValidSigner(address) (runs: 257, μ: 167326, ~: 167324)
276+
ERC6551Test:testIsValidSigner(address) (runs: 257, μ: 167327, ~: 167324)
277277
ERC6551Test:testOnERC1155BatchReceived() (gas: 1526537)
278278
ERC6551Test:testOnERC1155Received() (gas: 1523871)
279279
ERC6551Test:testOnERC721Received() (gas: 1501317)
280280
ERC6551Test:testOnERC721ReceivedCycles() (gas: 1713680)
281-
ERC6551Test:testOnERC721ReceivedCyclesWithDifferentChainIds(uint256) (runs: 257, μ: 448971, ~: 454680)
281+
ERC6551Test:testOnERC721ReceivedCyclesWithDifferentChainIds(uint256) (runs: 257, μ: 448372, ~: 454235)
282282
ERC6551Test:testSupportsInterface() (gas: 169367)
283-
ERC6551Test:testUpgrade() (gas: 1165638)
284-
ERC6551Test:test__codesize() (gas: 47524)
283+
ERC6551Test:testUpgrade() (gas: 1164238)
284+
ERC6551Test:test__codesize() (gas: 47510)
285285
ERC6909Test:testApprove() (gas: 36771)
286286
ERC6909Test:testApprove(address,uint256,uint256) (runs: 257, μ: 36483, ~: 37413)
287287
ERC6909Test:testBurn() (gas: 40676)

src/accounts/ERC6551.sol

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,15 @@ import {UUPSUpgradeable} from "../utils/UUPSUpgradeable.sol";
2525
/// the click on "Is this a proxy?" on the clone's page on Etherscan.
2626
///
2727
/// Note:
28-
/// - ERC6551 accounts are not compatible with ERC4337
29-
/// (at least not without crazy hacks)
30-
/// due to storage access limitations during ERC4337 UserOp validation.
28+
/// - This implementation does NOT include ERC4337 functionality.
29+
/// This is intentional, because the canonical ERC4337 entry point may still change and we
30+
/// don't want to encourage upgradeability by default for ERC6551 accounts just to handle this.
31+
/// We may include ERC4337 functionality once ERC4337 has been finalized.
32+
/// Recent updates to the account abstraction validation scope rules
33+
/// [ERC7562](https://eips.ethereum.org/EIPS/eip-7562) has made ERC6551 compatible with ERC4337.
34+
/// For an opinionated implementation, see https://github.com/tokenbound/contracts.
35+
/// If you want to add it yourself, you'll just need to add in the
36+
/// user operation validation functionality (and use ERC6551's execution functionality).
3137
/// - Please refer to the official [ERC6551](https://github.com/erc6551/reference) reference
3238
/// for latest updates on the ERC6551 standard, as well as canonical registry information.
3339
abstract contract ERC6551 is UUPSUpgradeable, Receiver, ERC1271 {
@@ -172,15 +178,26 @@ abstract contract ERC6551 is UUPSUpgradeable, Receiver, ERC1271 {
172178
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
173179

174180
/// @dev Execute a call from this account.
181+
/// Reverts and bubbles up error if operation fails.
182+
/// Returns the result of the operation.
183+
///
184+
/// Accounts MUST accept the following operation parameter values:
185+
/// - 0 = CALL
186+
/// - 1 = DELEGATECALL
187+
/// - 2 = CREATE
188+
/// - 3 = CREATE2
189+
///
190+
/// Accounts MAY support additional operations or restrict a signer's
191+
/// ability to execute certain operations.
175192
function execute(address target, uint256 value, bytes calldata data, uint8 operation)
176193
public
177194
payable
178195
virtual
179196
onlyValidSigner
180-
onlyValidExecuteOperation(operation)
181197
incrementState
182198
returns (bytes memory result)
183199
{
200+
if (operation != 0) revert OperationNotSupported();
184201
/// @solidity memory-safe-assembly
185202
assembly {
186203
result := mload(0x40)
@@ -198,15 +215,19 @@ abstract contract ERC6551 is UUPSUpgradeable, Receiver, ERC1271 {
198215
}
199216

200217
/// @dev Execute a sequence of calls from this account.
218+
/// Reverts and bubbles up error if an operation fails.
219+
/// Returns the results of the operations.
220+
///
221+
/// This is a batch variant of `execute` and is not required for `IERC6551Executable`.
201222
function executeBatch(Call[] calldata calls, uint8 operation)
202223
public
203224
payable
204225
virtual
205226
onlyValidSigner
206-
onlyValidExecuteOperation(operation)
207227
incrementState
208228
returns (bytes[] memory results)
209229
{
230+
if (operation != 0) revert OperationNotSupported();
210231
/// @solidity memory-safe-assembly
211232
assembly {
212233
results := mload(0x40)
@@ -235,12 +256,6 @@ abstract contract ERC6551 is UUPSUpgradeable, Receiver, ERC1271 {
235256
}
236257
}
237258

238-
/// @dev Requires that the execute `operation` is supported.
239-
modifier onlyValidExecuteOperation(uint8 operation) virtual {
240-
if (operation != 0) revert OperationNotSupported();
241-
_;
242-
}
243-
244259
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
245260
/* ERC165 */
246261
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
@@ -252,8 +267,8 @@ abstract contract ERC6551 is UUPSUpgradeable, Receiver, ERC1271 {
252267
/// @solidity memory-safe-assembly
253268
assembly {
254269
let s := shr(224, interfaceId)
255-
// ERC165: 0x01ffc9a7, ERC6551: 0x6faff5f1, ERC6551Executable: 0x74420f4c.
256-
result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x6faff5f1)), eq(s, 0x74420f4c))
270+
// ERC165: 0x01ffc9a7, ERC6551: 0x6faff5f1, ERC6551Executable: 0x51945447.
271+
result := or(or(eq(s, 0x01ffc9a7), eq(s, 0x6faff5f1)), eq(s, 0x51945447))
257272
}
258273
}
259274

test/ERC6551.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ contract ERC6551Test is SoladyTest {
333333
_TestTemps memory t = _testTemps();
334334
assertTrue(t.account.supportsInterface(0x01ffc9a7));
335335
assertTrue(t.account.supportsInterface(0x6faff5f1));
336-
assertTrue(t.account.supportsInterface(0x74420f4c));
336+
assertTrue(t.account.supportsInterface(0x51945447));
337337
assertFalse(t.account.supportsInterface(0x00000001));
338338
}
339339

0 commit comments

Comments
 (0)