Skip to content

Commit

Permalink
7779 bases management + use in MSA
Browse files Browse the repository at this point in the history
  • Loading branch information
Filipp Makarov authored and Filipp Makarov committed Dec 18, 2024
1 parent 709dbe0 commit b2b5cd3
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 7 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@
],
"publishConfig": {
"access": "public"
}
},
"packageManager": "[email protected]+sha512.7f1de9cffea40ff4594c48a94776112a0db325e81fb18a9400362ff7b7247f4fbd76c3011611c9f8ac58743c3dc526017894e07948de9b72052f874ee2edfdcd"
}
5 changes: 3 additions & 2 deletions src/MSAAdvanced.sol
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ contract MSAAdvanced is
if (signer != address(this)) {
return VALIDATION_FAILED;
}

_addStorageBase(MODULEMANAGER_STORAGE_LOCATION);
return VALIDATION_SUCCESS;
} else {
return VALIDATION_FAILED;
Expand Down Expand Up @@ -369,7 +369,8 @@ contract MSAAdvanced is

// checks if already initialized and reverts before setting the state to initialized
_initModuleManager();

_addStorageBase(MODULEMANAGER_STORAGE_LOCATION);

// bootstrap the account
(address bootstrap, bytes memory bootstrapCall) = abi.decode(data, (address, bytes));
_initAccount(bootstrap, bootstrapCall);
Expand Down
32 changes: 28 additions & 4 deletions src/core/ERC7779Adapter.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;
pragma solidity ^0.8.27;

abstract contract ERC7779Adapter {
error NonAuthorizedOnRedelegationCaller();

// keccak256(abi.encode(uint256(keccak256(bytes("InteroperableDelegatedAccount.ERC.Storage"))) - 1)) & ~bytes32(uint256(0xff));
bytes32 internal constant ERC7779_STORAGE_BASE = 0xc473de86d0138e06e4d4918a106463a7cc005258d2e21915272bcb4594c18900;

struct ERC7779Storage {
bytes32[] storageBases;
}

/*
* @dev Externally shares the storage bases that has been used throughout the account.
* Majority of 7702 accounts will have their distinctive storage base to reduce the
Expand All @@ -16,7 +25,21 @@ abstract contract ERC7779Adapter {
storage at this slot, but just append their base to the array.
* This append operation should be done during the initialization of the account.
*/
function accountStorageBases() external view returns (bytes32[] memory) { }
function accountStorageBases() external view returns (bytes32[] memory) {
ERC7779Storage storage $;
assembly {
$.slot := ERC7779_STORAGE_BASE
}
return $.storageBases;
}

function _addStorageBase(bytes32 storageBase) internal {
ERC7779Storage storage $;
assembly {
$.slot := ERC7779_STORAGE_BASE
}
$.storageBases.push(storageBase);
}

/*
* @dev Function called before redelegation.
Expand All @@ -28,9 +51,10 @@ abstract contract ERC7779Adapter {
for redelegation.
* msg.sender should be the owner of the account.
*/
function onRedelegation() external pure returns (bool) {
function onRedelegation() external returns (bool) {
require(msg.sender == address(this), NonAuthorizedOnRedelegationCaller());
// this is not implemented at the moment so that the account can preserve state across
// delegations
return true;
}
}
}
35 changes: 35 additions & 0 deletions test/core/TestFuzz_ERC7779Adapter.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import { MockERC7779 } from "../mocks/MockERC7779.sol";
import "forge-std/Test.sol";

/// @title TestFuzz_ERC7779Adapter
/// @notice Tests the ERC7779Adapter contract
contract TestFuzz_ERC7779Adapter is Test {
MockERC7779 private mockERC7779;

function setUp() public {
mockERC7779 = new MockERC7779();
//bytes32 erc7779StorageBase = keccak256(abi.encode(uint256(keccak256(bytes("InteroperableDelegatedAccount.ERC.Storage"))) - 1)) & ~bytes32(uint256(0xff));
//console.logBytes32(erc7779StorageBase);
}

function test_Fuzz_ERC7779Adapter_AddStorageBases(uint256 amountOfBases) public {
vm.assume(amountOfBases > 0 && amountOfBases < 100);
bytes32[] memory expectedStorageBases = new bytes32[](amountOfBases);

for (uint256 i = 0; i < amountOfBases; i++) {
bytes32 storageBase = bytes32(uint256(i));
expectedStorageBases[i] = storageBase;
mockERC7779.addStorageBase(storageBase);
}

bytes32[] memory retrievedStorageBases = mockERC7779.accountStorageBases();
assertEq(retrievedStorageBases.length, amountOfBases);
for (uint256 i = 0; i < amountOfBases; i++) {
assertEq(retrievedStorageBases[i], expectedStorageBases[i]);
}
}
}

12 changes: 12 additions & 0 deletions test/mocks/MockERC7779.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

import { ERC7779Adapter } from "src/core/ERC7779Adapter.sol";

contract MockERC7779 is ERC7779Adapter {

function addStorageBase(bytes32 storageBase) external {
_addStorageBase(storageBase);
}

}

0 comments on commit b2b5cd3

Please sign in to comment.