Skip to content

Commit 4e6281f

Browse files
authored
feat: sync the latest development (#72)
## Summary I've synced the code from the development repository to this repository. I also manually validated the hash using the following command: ```sh ( jq -c '.dependencies' package.json | sha256sum find src test .gitmodules -type f -exec sha256sum {} \; ) | sha256sum ``` Result: `bf428b0b456fd87dbbdc0c8715a817f71364cd4c86aed90b019c99cab1db19ed` (both repos) This ensures the integrity of the sync. Note: `foundry.toml` is not included because it differs between the two repositories. However, I have manually verified that the compilation-related sections are the same. ## Detail ### Changeset * Sync `src/` * Update `foundry.toml` * Update pr template per request from techops ### Checklist - [x] Did you add new tests and confirm all tests pass? (`yarn test`) - [x] Did you ensure any new Solidity source code files meet minimum test coverage requirements? (`yarn coverage`) - [ ] Did you update relevant docs? (docs are found in the `docs` folder) - [x] Do your commits follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard? - [x] Does your PR title also follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard? - [ ] If you have a breaking change, is it [correctly reflected in your commit message](https://www.conventionalcommits.org/en/v1.0.0/#examples)? (e.g. `feat!: breaking change`) - [x] Did you run lint (`yarn lint`) and fix any issues? - [x] Did you run formatter (`yarn format:check`) and fix any issues (`yarn format:write`)? ## Testing * Sync `test/` ## Documentation n/a
1 parent a0fdf60 commit 4e6281f

24 files changed

+1235
-217
lines changed

.github/pull_request_template.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ Mandatory section.
1212
- [ ] Did you update relevant docs? (docs are found in the `docs` folder)
1313
- [ ] Do your commits follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard?
1414
- [ ] Does your PR title also follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard?
15-
- [ ] If you have a breaking change, is it [correctly reflected in your commit message](https://www.conventionalcommits.org/en/v1.0.0/#examples)? (e.g. `feat!: breaking change`)
1615
- [ ] Did you run lint (`yarn lint`) and fix any issues?
1716
- [ ] Did you run formatter (`yarn format:check`) and fix any issues (`yarn format:write`)?
1817

foundry.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ libs = ['lib', 'node_modules']
88
solc_version = "0.8.24"
99
evm_version = 'paris'
1010
test = 'test'
11+
optimizer = true
12+
optimizer_runs = 200
1113
via_ir = true
1214
auto_detect_solc = false
1315
auto_detect_remappings = false

src/msca/6900/v0.8/README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
# Modular Smart Contract Account
2-
MSCA that's in compliant with [EIP-6900](https://eips.ethereum.org/EIPS/eip-6900).
2+
MSCA that's in compliant with [ERC-6900](https://eips.ethereum.org/EIPS/eip-6900).
33

44
## Disclaimer
55
Please be aware that all contracts within this package are still in active development and are not deployed on any mainnets yet, so proceed with caution if you intend to test them on your own.
66

7-
## Signature Encoding
8-
TODO.
7+
## Features
8+
1. Deploy an account using the account factory.
9+
2. Receive **ERC-721, ERC-1155,** and **ERC-777** tokens.
10+
3. Supports **ERC-1271** for contract signatures.
11+
4. Enables **upgradeability** via the **ERC-1967 proxy**, allowing users to update their proxy’s implementation and choose different smart account versions. We follow the **ERC-7201 namespaced storage standard** to prevent storage collisions when switching implementations.
12+
5. **Extensible through modules**, allowing additional functionality to be integrated into the account.
13+
14+
## Acknowledgements
15+
The contracts in this repository follow the **ERC-6900 specification** and are largely inspired by the design of its reference implementation.

src/msca/6900/v0.8/account/BaseMSCA.sol

Lines changed: 61 additions & 34 deletions
Large diffs are not rendered by default.

src/msca/6900/v0.8/account/UpgradableMSCA.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ contract UpgradableMSCA is BaseMSCA, DefaultCallbackHandler, UUPSUpgradeable {
8686
payable
8787
override
8888
onlyProxy
89-
validateNativeFunction
89+
wrapNativeExecutionFunction
9090
{
9191
super.upgradeToAndCall(newImplementation, data);
9292
}

src/msca/6900/v0.8/account/WalletStorageInitializable.sol

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*/
1919
pragma solidity 0.8.24;
2020

21-
import {WalletStorageLib} from "../libs/WalletStorageLib.sol";
21+
import {WalletStorageV2Lib} from "../libs/WalletStorageV2Lib.sol";
2222

2323
/// @notice Forked from OpenZeppelin (proxy/utils/Initializable.sol) with wallet storage access.
2424
/// Reinitialization is removed.
@@ -43,8 +43,8 @@ abstract contract WalletStorageInitializable {
4343
* Emits an {WalletStorageInitialized} event.
4444
*/
4545
modifier walletStorageInitializer() {
46-
bool isTopLevelCall = !WalletStorageLib.getLayout().initializing;
47-
uint8 initialized = WalletStorageLib.getLayout().initialized;
46+
bool isTopLevelCall = !WalletStorageV2Lib.getLayout().initializing;
47+
uint8 initialized = WalletStorageV2Lib.getLayout().initialized;
4848

4949
// Allowed calls:
5050
// - initialSetup: the contract is not in the initializing state and no previous version was
@@ -56,13 +56,13 @@ abstract contract WalletStorageInitializable {
5656
if (!initialSetup && !deploying) {
5757
revert WalletStorageIsInitialized();
5858
}
59-
WalletStorageLib.getLayout().initialized = 1;
59+
WalletStorageV2Lib.getLayout().initialized = 1;
6060
if (isTopLevelCall) {
61-
WalletStorageLib.getLayout().initializing = true;
61+
WalletStorageV2Lib.getLayout().initializing = true;
6262
}
6363
_;
6464
if (isTopLevelCall) {
65-
WalletStorageLib.getLayout().initializing = false;
65+
WalletStorageV2Lib.getLayout().initializing = false;
6666
emit WalletStorageInitialized();
6767
}
6868
}
@@ -72,7 +72,7 @@ abstract contract WalletStorageInitializable {
7272
* {walletStorageInitializer} modifier, directly or indirectly.
7373
*/
7474
modifier onlyWalletStorageInitializing() {
75-
if (!WalletStorageLib.getLayout().initializing) {
75+
if (!WalletStorageV2Lib.getLayout().initializing) {
7676
revert WalletStorageIsNotInitializing();
7777
}
7878
_;
@@ -87,11 +87,11 @@ abstract contract WalletStorageInitializable {
8787
* Emits an {WalletStorageInitialized} event the first time it is successfully executed.
8888
*/
8989
function _disableWalletStorageInitializers() internal virtual {
90-
if (WalletStorageLib.getLayout().initializing) {
90+
if (WalletStorageV2Lib.getLayout().initializing) {
9191
revert WalletStorageIsInitializing();
9292
}
93-
if (WalletStorageLib.getLayout().initialized != type(uint8).max) {
94-
WalletStorageLib.getLayout().initialized = type(uint8).max;
93+
if (WalletStorageV2Lib.getLayout().initialized != type(uint8).max) {
94+
WalletStorageV2Lib.getLayout().initialized = type(uint8).max;
9595
emit WalletStorageInitialized();
9696
}
9797
}

src/msca/6900/v0.8/factories/UpgradableMSCAFactory.sol

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
*/
1919
pragma solidity 0.8.24;
2020

21-
import {InvalidLength} from "../../../../common/Errors.sol";
21+
import {InvalidLength, Unsupported} from "../../../../common/Errors.sol";
2222
import {Create2FailedDeployment} from "../../shared/common/Errors.sol";
2323
import {UpgradableMSCA} from "../account/UpgradableMSCA.sol";
2424

@@ -143,6 +143,11 @@ contract UpgradableMSCAFactory is Ownable2Step {
143143
ENTRY_POINT.withdrawStake(_withdrawAddress);
144144
}
145145

146+
/// @notice Disable renouncing ownership.
147+
function renounceOwnership() public view override onlyOwner {
148+
revert Unsupported();
149+
}
150+
146151
function _getAddressWithValidation(
147152
bytes32 _sender,
148153
bytes32 _salt,

src/msca/6900/v0.8/libs/SelectorRegistryLib.sol

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,36 @@
1818
*/
1919
pragma solidity 0.8.24;
2020

21-
import {IExecutionHookModule} from "@erc6900/reference-implementation/interfaces/IExecutionHookModule.sol";
22-
import {IModularAccountView} from "@erc6900/reference-implementation/interfaces/IModularAccountView.sol";
23-
import {IModule} from "@erc6900/reference-implementation/interfaces/IModule.sol";
24-
25-
import {IModularAccount} from "@erc6900/reference-implementation/interfaces/IModularAccount.sol";
26-
2721
import {IAccount} from "@account-abstraction/contracts/interfaces/IAccount.sol";
22+
import {IAccountExecute} from "@account-abstraction/contracts/interfaces/IAccountExecute.sol";
2823
import {IAggregator} from "@account-abstraction/contracts/interfaces/IAggregator.sol";
24+
25+
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
26+
2927
import {IPaymaster} from "@account-abstraction/contracts/interfaces/IPaymaster.sol";
28+
import {IExecutionHookModule} from "@erc6900/reference-implementation/interfaces/IExecutionHookModule.sol";
3029
import {IExecutionModule} from "@erc6900/reference-implementation/interfaces/IExecutionModule.sol";
30+
import {IModularAccount} from "@erc6900/reference-implementation/interfaces/IModularAccount.sol";
31+
import {IModularAccountView} from "@erc6900/reference-implementation/interfaces/IModularAccountView.sol";
32+
import {IModule} from "@erc6900/reference-implementation/interfaces/IModule.sol";
3133
import {IValidationHookModule} from "@erc6900/reference-implementation/interfaces/IValidationHookModule.sol";
34+
35+
import {BaseMSCA} from "../account/BaseMSCA.sol";
3236
import {IValidationModule} from "@erc6900/reference-implementation/interfaces/IValidationModule.sol";
3337
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
3438

35-
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
39+
import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";
40+
import {IERC777Recipient} from "@openzeppelin/contracts/interfaces/IERC777Recipient.sol";
41+
import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
42+
import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
3643

3744
library SelectorRegistryLib {
3845
/**
39-
* @dev Check if the selector is native execution function.
46+
* @dev Determines whether a function is a native execution function with the validateNativeFunction modifier,
47+
* indicating that it triggers execution hooks (if any) associated with execution selector from msg.sig.
4048
* @param selector the function selector.
4149
*/
42-
function _isNativeExecutionFunction(bytes4 selector) internal pure returns (bool) {
50+
function _isWrappedNativeExecutionFunction(bytes4 selector) internal pure returns (bool) {
4351
return selector == IModularAccount.execute.selector || selector == IModularAccount.executeBatch.selector
4452
|| selector == IModularAccount.installExecution.selector
4553
|| selector == IModularAccount.uninstallExecution.selector
@@ -48,21 +56,48 @@ library SelectorRegistryLib {
4856
|| selector == IModularAccount.uninstallValidation.selector;
4957
}
5058

59+
/**
60+
* @dev Determines whether a function is a native execution function without the validateNativeFunction modifier,
61+
* indicating that it triggers execution hooks (if any) associated with the validation function.
62+
* @param selector the function selector.
63+
*/
64+
function _isNonWrappedNativeExecutionFunction(bytes4 selector) internal pure returns (bool) {
65+
return selector == IAccountExecute.executeUserOp.selector
66+
|| selector == IModularAccount.executeWithRuntimeValidation.selector;
67+
}
68+
69+
/**
70+
* @dev Check whether a selector is a native execution function that allows global validation.
71+
* @param selector the function selector.
72+
*/
73+
function _isNativeExecutionFunction(bytes4 selector) internal pure returns (bool) {
74+
return _isWrappedNativeExecutionFunction(selector) || _isNonWrappedNativeExecutionFunction(selector);
75+
}
76+
77+
/**
78+
* @dev Check whether a selector is a native view function.
79+
* @param selector the function selector.
80+
*/
81+
function _isNativeViewFunction(bytes4 selector) internal pure returns (bool) {
82+
return selector == BaseMSCA.entryPoint.selector || selector == IModularAccount.accountId.selector
83+
|| selector == UUPSUpgradeable.proxiableUUID.selector
84+
|| selector == IModularAccountView.getExecutionData.selector
85+
|| selector == IModularAccountView.getValidationData.selector || selector == IAccount.validateUserOp.selector
86+
|| selector == IERC165.supportsInterface.selector || selector == IERC1271.isValidSignature.selector
87+
|| selector == IERC1155Receiver.onERC1155BatchReceived.selector
88+
|| selector == IERC1155Receiver.onERC1155Received.selector
89+
|| selector == IERC721Receiver.onERC721Received.selector || selector == IERC777Recipient.tokensReceived.selector;
90+
}
91+
5192
/**
5293
* @dev Check if the selector is for native function.
5394
* @param selector the function selector.
5495
*/
5596
function _isNativeFunction(bytes4 selector) internal pure returns (bool) {
56-
return _isNativeExecutionFunction(selector) || selector == IModularAccount.executeWithRuntimeValidation.selector
57-
|| selector == IModularAccount.accountId.selector || selector == UUPSUpgradeable.proxiableUUID.selector
58-
// check against IERC165 methods
59-
|| selector == IERC165.supportsInterface.selector
60-
// check against IModularAccountView methods
61-
|| selector == IModularAccountView.getExecutionData.selector
62-
|| selector == IModularAccountView.getValidationData.selector || selector == IAccount.validateUserOp.selector;
97+
return _isNativeExecutionFunction(selector) || _isNativeViewFunction(selector);
6398
}
6499

65-
function _isErc4337Function(bytes4 selector) internal pure returns (bool) {
100+
function _isERC4337Function(bytes4 selector) internal pure returns (bool) {
66101
return selector == IAggregator.validateSignatures.selector
67102
|| selector == IAggregator.validateUserOpSignature.selector
68103
|| selector == IAggregator.aggregateSignatures.selector
@@ -76,6 +111,7 @@ library SelectorRegistryLib {
76111
|| selector == IValidationModule.validateRuntime.selector
77112
|| selector == IValidationModule.validateSignature.selector
78113
|| selector == IValidationHookModule.preRuntimeValidationHook.selector
114+
|| selector == IValidationHookModule.preSignatureValidationHook.selector
79115
|| selector == IExecutionHookModule.preExecutionHook.selector
80116
|| selector == IExecutionHookModule.postExecutionHook.selector
81117
|| selector == IExecutionModule.executionManifest.selector;

src/msca/6900/v0.8/libs/WalletStorageLib.sol renamed to src/msca/6900/v0.8/libs/WalletStorageV2Lib.sol

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,15 @@ pragma solidity 0.8.24;
2121
import {ExecutionStorage, ValidationStorage} from "../common/Structs.sol";
2222
import {ModuleEntity} from "@erc6900/reference-implementation/interfaces/IModularAccount.sol";
2323

24-
/// @dev The same storage will be used for ERC6900 v0.8 MSCAs.
25-
library WalletStorageLib {
26-
// keccak256 hash of "circle.msca.v0_8.storage" subtracted by 1
27-
bytes32 internal constant WALLET_STORAGE_SLOT = 0x45b8c59e88d59f48fa992cc87612124331f3e8b18f76fa4c146925e98c37c228;
24+
/// @dev The same storage will be used for v2.x.y of MSCAs.
25+
library WalletStorageV2Lib {
26+
// @notice On 12/16/2024, storage was aligned to 256 as a potential optimization in anticipation of gas schedule
27+
// changes following the Verkle state tree migration. This adjustment accounts for scenarios where groups
28+
// of 256 storage slots may become warm simultaneously and will only apply to newly deployed accounts.
29+
// For more details, please refer to https://eips.ethereum.org/EIPS/eip-7201.
30+
// 1. id = "circle.msca.v2.storage"
31+
// 2. keccak256(abi.encode(uint256(keccak256(id)) - 1)) & ~bytes32(uint256(0xff))
32+
bytes32 internal constant WALLET_STORAGE_SLOT = 0x1ffef775e8122370efaac4f28eeec94f03b0484eca026ee3ab713094c73f5d00;
2833

2934
struct Layout {
3035
// list of ERC-165 interfaceIds to add to account to support introspection checks

src/msca/6900/v0.8/modules/multisig/IWeightedMultisigValidationModule.sol

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@
1919
pragma solidity 0.8.24;
2020

2121
import {PublicKey} from "../../../../../common/CommonStructs.sol";
22-
import {AccountMetadata, CheckNSignaturesRequest, SignerMetadata, SignerMetadataWithId} from "./MultisigStructs.sol";
22+
import {
23+
AccountMetadata,
24+
CheckNSignaturesRequest,
25+
CheckNSignaturesResponse,
26+
SignerMetadata,
27+
SignerMetadataWithId
28+
} from "./MultisigStructs.sol";
2329
import {IValidationModule} from "@erc6900/reference-implementation/interfaces/IValidationModule.sol";
2430

2531
/// @title Weighted Multisig Validation Module Interface
@@ -52,6 +58,9 @@ interface IWeightedMultisigValidationModule is IValidationModule {
5258
error InvalidSigOffset(uint32 entityId, address account, uint256 offset);
5359
error InvalidNumSigsOnActualDigest(uint32 entityId, address account, uint256 numSigs);
5460
error InvalidUserOpDigest(uint32 entityId, address account);
61+
error UnsupportedSigType(uint32 entityId, address account, uint8 sigType);
62+
error InvalidAuthorizationLength(uint32 entityId, address account, uint256 length);
63+
error InvalidRuntimeDigest(uint32 entityId, address account);
5564

5665
/// @notice Get the signer id.
5766
/// @param signer The signer to check.
@@ -130,14 +139,15 @@ interface IWeightedMultisigValidationModule is IValidationModule {
130139
/// entityId - entity id for the account and signer.
131140
/// account - the account to check the signatures for.
132141
/// signatures - the signatures to check.
133-
/// @return success true if the signatures are valid.
134-
/// @return firstFailure first failure, if failed is true.
142+
/// @return response - success true if the signatures are valid.
143+
/// firstFailure if failed is true.
144+
/// returnError for debugging if available.
135145
/// (Note: if all signatures are individually valid but do not satisfy the
136146
/// multisig, firstFailure will be set to the last signature's index.)
137147
function checkNSignatures(CheckNSignaturesRequest calldata nSignaturesInput)
138148
external
139149
view
140-
returns (bool success, uint256 firstFailure);
150+
returns (CheckNSignaturesResponse memory response);
141151

142152
/// @notice Return all the signer metadata of an account.
143153
/// @param entityId entity id for the account and signers.

0 commit comments

Comments
 (0)