Skip to content

Commit 4e9bfb4

Browse files
feat: add core contracts
1 parent 29defdb commit 4e9bfb4

24 files changed

+1200
-3
lines changed

.gitmodules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@
1616
[submodule "lib/account-abstraction"]
1717
path = lib/account-abstraction
1818
url = https://github.com/eth-infinitism/account-abstraction
19+
[submodule "lib/sentinellist"]
20+
path = lib/sentinellist
21+
url = https://github.com/rhinestonewtf/sentinellist
22+
[submodule "lib/ExcessivelySafeCall"]
23+
path = lib/ExcessivelySafeCall
24+
url = https://github.com/nomad-xyz/ExcessivelySafeCall

lib/ExcessivelySafeCall

Submodule ExcessivelySafeCall added at 81cd99c

lib/sentinellist

Submodule sentinellist added at 6dff696

remappings.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
halmos-cheatcodes=node_modules/halmos-cheatcodes
2-
32
forge-std/=lib/forge-std/src/
43
solady/=lib/solady/src/
54
@account-abstraction/=lib/account-abstraction/
65
@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
76
@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/
87
openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/
9-
openzeppelin-contracts/=lib/openzeppelin-contracts/
8+
openzeppelin-contracts/=lib/openzeppelin-contracts/
9+
sentinellist=lib/sentinellist/src/
10+
excessively-safe-call=lib/ExcessivelySafeCall/src/

src/core/AllStorage.sol

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.28;
3+
4+
import {IAllStorage} from '../interfaces/core/IAllStorage.sol';
5+
6+
/// @title Startale - Storage
7+
/// @notice Manages isolated storage spaces for Modular Smart Account in compliance with ERC-7201 standard to ensure collision-resistant storage.
8+
/// @dev Implements the ERC-7201 namespaced storage pattern to maintain secure and isolated storage sections for different states within Startale suite.
9+
/// @author Startale Labs
10+
contract AllStorage is IAllStorage {
11+
/// @custom:storage-location erc7201:startale.account.storage
12+
/// ERC-7201 namespaced via `keccak256(abi.encode(uint256(keccak256(bytes("startale.account.storage"))) - 1)) & ~bytes32(uint256(0xff));`
13+
bytes32 private constant _STORAGE_LOCATION = 0x9195d48440658ac27f13a7bd256a2e74da1f2416f468d66228b37e6ac4790c00;
14+
15+
/// @dev Utilizes ERC-7201's namespaced storage pattern for isolated storage access. This method computes
16+
/// the storage slot based on a predetermined location, ensuring collision-resistant storage for contract states.
17+
/// @custom:storage-location ERC-7201 formula applied to "startale.account.storage", facilitating unique
18+
/// namespace identification and storage segregation, as detailed in the specification.
19+
/// @return $ The proxy to the `AccountStorage` struct, providing a reference to the namespaced storage slot.
20+
function _getAccountStorage() internal pure returns (AccountStorage storage $) {
21+
assembly {
22+
$.slot := _STORAGE_LOCATION
23+
}
24+
}
25+
}

src/core/BaseAccount.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {IEntryPoint} from 'account-abstraction/interfaces/IEntryPoint.sol';
88
/// @notice Implements ERC-4337 and ERC-7579 standards for account management and access control.
99
/// @dev Manages entry points and configurations as specified in the ERC-4337 and ERC-7579 documentation.
1010
/// @author Startale Labs
11-
/// Special thanks to the Biconomy team for https://github.com/bcnmy/nexus/ on which this implementation is highly based on.
11+
/// Special thanks to the Biconomy team for https://github.com/bcnmy/nexus/ and ERC7579 reference implementation on which this implementation is highly based on.
1212
contract BaseAccount is IBaseAccount {
1313
/// @notice Identifier for this implementation on the network
1414
string internal constant _ACCOUNT_IMPLEMENTATION_ID = 'startale.smart-account.0.0.1';

src/core/ERC7779Adapter.sol

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.28;
3+
4+
import {IERC7779} from '../interfaces/IERC7779.sol';
5+
6+
// Note: To inherit from when we are ready to utilize 7702 fully.
7+
8+
abstract contract ERC7779Adapter is IERC7779 {
9+
error NonAuthorizedOnRedelegationCaller();
10+
11+
// keccak256(abi.encode(uint256(keccak256(bytes("InteroperableDelegatedAccount.ERC.Storage"))) -
12+
// 1)) & ~bytes32(uint256(0xff));
13+
bytes32 internal constant ERC7779_STORAGE_BASE = 0xc473de86d0138e06e4d4918a106463a7cc005258d2e21915272bcb4594c18900;
14+
15+
struct ERC7779Storage {
16+
bytes32[] storageBases;
17+
}
18+
/*
19+
* @dev Externally shares the storage bases that has been used throughout the account.
20+
* Majority of 7702 accounts will have their distinctive storage base to reduce the
21+
chance of storage collision.
22+
* This allows the external entities to know what the storage base is of the account.
23+
* Wallets willing to redelegate already-delegated accounts should call
24+
accountStorageBase() to check if it confirms with the account it plans to redelegate.
25+
*
26+
* The bytes32 array should be stored at the storage slot:
27+
keccak(keccak('InteroperableDelegatedAccount.ERC.Storage')-1) & ~0xff
28+
* This is an append-only array so newly redelegated accounts should not overwrite the
29+
storage at this slot, but just append their base to the array.
30+
* This append operation should be done during the initialization of the account.
31+
*/
32+
33+
function accountStorageBases() external view returns (bytes32[] memory) {
34+
ERC7779Storage storage $;
35+
assembly {
36+
$.slot := ERC7779_STORAGE_BASE
37+
}
38+
return $.storageBases;
39+
}
40+
41+
function _addStorageBase(bytes32 storageBase) internal {
42+
ERC7779Storage storage $;
43+
assembly {
44+
$.slot := ERC7779_STORAGE_BASE
45+
}
46+
$.storageBases.push(storageBase);
47+
}
48+
49+
/*
50+
* @dev Function called before redelegation.
51+
* This function should prepare the account for a delegation to a different
52+
implementation.
53+
* This function could be triggered by the new wallet that wants to redelegate an already
54+
delegated EOA.
55+
* It should uninitialize storages if needed and execute wallet-specific logic to prepare
56+
for redelegation.
57+
* msg.sender should be the owner of the account.
58+
*/
59+
function onRedelegation() external returns (bool) {
60+
require(msg.sender == address(this), NonAuthorizedOnRedelegationCaller());
61+
_onRedelegation();
62+
return true;
63+
}
64+
65+
/// @dev This function is called before redelegation.
66+
/// @dev Account should override this function to implement the specific logic.
67+
function _onRedelegation() internal virtual;
68+
}

0 commit comments

Comments
 (0)