diff --git a/src/libraries/AssociatedLinkedListSetLib.sol b/src/libraries/AssociatedLinkedListSetLib.sol deleted file mode 100644 index 4663e4ac..00000000 --- a/src/libraries/AssociatedLinkedListSetLib.sol +++ /dev/null @@ -1,519 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; - -// type SetValue is bytes30; - -// /// @dev The sentinel value is used to indicate the head and tail of the list. -// bytes32 constant SENTINEL_VALUE = bytes32(uint256(1)); - -// /// @dev Removing the last element will result in this flag not being set correctly, but all operations will -// /// function normally, albeit with one extra sload for getAll. -// bytes32 constant HAS_NEXT_FLAG = bytes32(uint256(2)); - -// /// @dev Type representing the set, which is just a storage slot placeholder like the solidity mapping type. -// struct AssociatedLinkedListSet { -// bytes32 placeholder; -// } - -// /// @title Associated Linked List Set Library -// /// @notice Provides a set data structure that is enumerable and held in address-associated storage (per the -// /// ERC-4337 spec) -// library AssociatedLinkedListSetLib { -// // Mapping Entry Byte Layout -// // | value | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA____ | -// // | meta | 0x____________________________________________________________BBBB | - -// // Bit-layout of the meta bytes (2 bytes) -// // | user flags | 11111111 11111100 | -// // | has next | 00000000 00000010 | -// // | sentinel | 00000000 00000001 | - -// // Mapping keys exclude the upper 15 bits of the meta bytes, which allows keys to be either a value or the -// // sentinel. - -// bytes4 internal constant _ASSOCIATED_STORAGE_PREFIX = 0x9cc6c923; // -// bytes4(keccak256("AssociatedLinkedListSet")) - -// // A custom type representing the index of a storage slot -// type StoragePointer is bytes32; - -// // A custom type representing a pointer to a location in memory beyond the current free memory pointer. -// // Holds a fixed-size buffer similar to "bytes memory", but without a length field. -// // Care must be taken when using these, as they may be overwritten if ANY memory is allocated after -// allocating -// // a TempBytesMemory. -// type TempBytesMemory is bytes32; - -// // INTERNAL METHODS - -// /// @notice Adds a value to a set. -// /// @param set The set to add the value to. -// /// @param associated The address the set is associated with. -// /// @param value The value to add. -// /// @return True if the value was added, false if the value cannot be added (already exists or is zero). -// function tryAdd(AssociatedLinkedListSet storage set, address associated, SetValue value) -// internal -// returns (bool) -// { -// bytes32 unwrappedKey = bytes32(SetValue.unwrap(value)); -// if (unwrappedKey == bytes32(0)) { -// // Cannot add the zero value -// return false; -// } - -// TempBytesMemory keyBuffer = _allocateTempKeyBuffer(set, associated); - -// StoragePointer valueSlot = _mapLookup(keyBuffer, unwrappedKey); -// if (_load(valueSlot) != bytes32(0)) { -// // Entry already exists -// return false; -// } - -// // Load the head of the set -// StoragePointer sentinelSlot = _mapLookup(keyBuffer, SENTINEL_VALUE); -// bytes32 prev = _load(sentinelSlot); -// if (prev == bytes32(0) || isSentinel(prev)) { -// // set is empty, need to do: -// // map[SENTINEL_VALUE] = unwrappedKey; -// // map[unwrappedKey] = SENTINEL_VALUE; -// _store(sentinelSlot, unwrappedKey); -// _store(valueSlot, SENTINEL_VALUE); -// } else { -// // set is not empty, need to do: -// // map[SENTINEL_VALUE] = unwrappedKey | HAS_NEXT_FLAG; -// // map[unwrappedKey] = prev; -// _store(sentinelSlot, unwrappedKey | HAS_NEXT_FLAG); -// _store(valueSlot, prev); -// } - -// return true; -// } - -// /// @notice Removes a value from a set. -// /// @dev This is an O(n) operation, where n is the number of elements in the set. -// /// @param set The set to remove the value from -// /// @param associated The address the set is associated with -// /// @param value The value to remove -// /// @return True if the value was removed, false if the value does not exist -// function tryRemove(AssociatedLinkedListSet storage set, address associated, SetValue value) -// internal -// returns (bool) -// { -// bytes32 unwrappedKey = bytes32(SetValue.unwrap(value)); -// TempBytesMemory keyBuffer = _allocateTempKeyBuffer(set, associated); - -// StoragePointer valueSlot = _mapLookup(keyBuffer, unwrappedKey); -// bytes32 nextValue = _load(valueSlot); -// if (unwrappedKey == bytes32(0) || nextValue == bytes32(0)) { -// // Entry does not exist -// return false; -// } - -// bytes32 prevKey = SENTINEL_VALUE; -// bytes32 currentVal; -// do { -// // Load the current entry -// StoragePointer prevSlot = _mapLookup(keyBuffer, prevKey); -// currentVal = _load(prevSlot); -// bytes32 currentKey = clearFlags(currentVal); -// if (currentKey == unwrappedKey) { -// // Found the entry -// // Set the previous value's next value to the next value, -// // and the flags to the current value's flags. -// // and the next value's `hasNext` flag to determine whether or not the next value is (or points -// to) -// // the sentinel value. - -// // Need to do: -// // map[prevKey] = clearFlags(nextValue) | getUserFlags(currentVal) | (nextValue & -// HAS_NEXT_FLAG); -// // map[currentKey] = bytes32(0); - -// _store(prevSlot, clearFlags(nextValue) | getUserFlags(currentVal) | (nextValue & -// HAS_NEXT_FLAG)); -// _store(valueSlot, bytes32(0)); - -// return true; -// } -// prevKey = currentKey; -// } while (!isSentinel(currentVal) && currentVal != bytes32(0)); -// return false; -// } - -// /// @notice Removes a value from a set, given the previous value in the set. -// /// @dev This is an O(1) operation but requires additional knowledge. -// /// @param set The set to remove the value from -// /// @param associated The address the set is associated with -// /// @param value The value to remove -// /// @param prev The previous value in the set -// /// @return True if the value was removed, false if the value does not exist -// function tryRemoveKnown(AssociatedLinkedListSet storage set, address associated, SetValue value, bytes32 -// prev) -// internal -// returns (bool) -// { -// bytes32 unwrappedKey = bytes32(SetValue.unwrap(value)); -// TempBytesMemory keyBuffer = _allocateTempKeyBuffer(set, associated); - -// prev = clearFlags(prev); - -// if (prev == bytes32(0) || unwrappedKey == bytes32(0)) { -// return false; -// } - -// // assert that the previous key's next value is the value to be removed -// StoragePointer prevSlot = _mapLookup(keyBuffer, prev); -// bytes32 currentValue = _load(prevSlot); -// if (clearFlags(currentValue) != unwrappedKey) { -// return false; -// } - -// StoragePointer valueSlot = _mapLookup(keyBuffer, unwrappedKey); -// bytes32 next = _load(valueSlot); -// if (next == bytes32(0)) { -// // The set didn't actually contain the value -// return false; -// } - -// // Need to do: -// // map[prev] = clearFlags(next) | getUserFlags(currentValue) | (next & HAS_NEXT_FLAG); -// // map[unwrappedKey] = bytes32(0); -// _store(prevSlot, clearFlags(next) | getUserFlags(currentValue) | (next & HAS_NEXT_FLAG)); -// _store(valueSlot, bytes32(0)); - -// return true; -// } - -// /// @notice Removes all values from a set. -// /// @dev This is an O(n) operation, where n is the number of elements in the set. -// /// @param set The set to remove the values from -// /// @param associated The address the set is associated with -// function clear(AssociatedLinkedListSet storage set, address associated) internal { -// TempBytesMemory keyBuffer = _allocateTempKeyBuffer(set, associated); - -// bytes32 cursor = SENTINEL_VALUE; - -// do { -// bytes32 cleared = clearFlags(cursor); -// StoragePointer cursorSlot = _mapLookup(keyBuffer, cleared); -// bytes32 next = _load(cursorSlot); -// _store(cursorSlot, bytes32(0)); -// cursor = next; -// } while (!isSentinel(cursor) && cursor != bytes32(0)); - -// StoragePointer sentinelSlot = _mapLookup(keyBuffer, SENTINEL_VALUE); -// _store(sentinelSlot, bytes32(0)); -// } - -// /// @notice Set the flags on a value in the set. -// /// @dev The user flags can only be set on the upper 14 bits, because the lower two are reserved for the -// /// sentinel and has next bit. -// /// @param set The set containing the value. -// /// @param associated The address the set is associated with. -// /// @param value The value to set the flags on. -// /// @param flags The flags to set. -// /// @return True if the set contains the value and the operation succeeds, false otherwise. -// function trySetFlags(AssociatedLinkedListSet storage set, address associated, SetValue value, uint16 flags) -// internal -// returns (bool) -// { -// bytes32 unwrappedKey = SetValue.unwrap(value); -// TempBytesMemory keyBuffer = _allocateTempKeyBuffer(set, associated); - -// // Ignore the lower 2 bits. -// flags &= 0xFFFC; - -// // If the set doesn't actually contain the value, return false; -// StoragePointer valueSlot = _mapLookup(keyBuffer, unwrappedKey); -// bytes32 next = _load(valueSlot); -// if (next == bytes32(0)) { -// return false; -// } - -// // Set the flags -// _store(valueSlot, clearUserFlags(next) | bytes32(uint256(flags))); - -// return true; -// } - -// /// @notice Set the given flags on a value in the set, preserving the values of other flags. -// /// @dev The user flags can only be set on the upper 14 bits, because the lower two are reserved for the -// /// sentinel and has next bit. -// /// Short-circuits if the flags are already enabled, returning true. -// /// @param set The set containing the value. -// /// @param associated The address the set is associated with. -// /// @param value The value to enable the flags on. -// /// @param flags The flags to enable. -// /// @return True if the operation succeeds or short-circuits due to the flags already being enabled. False -// /// otherwise. -// function tryEnableFlags(AssociatedLinkedListSet storage set, address associated, SetValue value, uint16 -// flags) -// internal -// returns (bool) -// { -// flags &= 0xFFFC; // Allow short-circuit if lower bits are accidentally set -// uint16 currFlags = getFlags(set, associated, value); -// if (currFlags & flags == flags) return true; // flags are already enabled -// return trySetFlags(set, associated, value, currFlags | flags); -// } - -// /// @notice Clear the given flags on a value in the set, preserving the values of other flags. -// /// @notice If the value is not in the set, this function will still return true. -// /// @dev The user flags can only be set on the upper 14 bits, because the lower two are reserved for the -// /// sentinel and has next bit. -// /// Short-circuits if the flags are already disabled, or if set does not contain the value. Short-circuits -// /// return true. -// /// @param set The set containing the value. -// /// @param associated The address the set is associated with. -// /// @param value The value to disable the flags on. -// /// @param flags The flags to disable. -// /// @return True if the operation succeeds, or short-circuits due to the flags already being disabled or if -// the -// /// set does not contain the value. False otherwise. -// function tryDisableFlags(AssociatedLinkedListSet storage set, address associated, SetValue value, uint16 -// flags) -// internal -// returns (bool) -// { -// flags &= 0xFFFC; // Allow short-circuit if lower bits are accidentally set -// uint16 currFlags = getFlags(set, associated, value); -// if (currFlags & flags == 0) return true; // flags are already disabled -// return trySetFlags(set, associated, value, currFlags & ~flags); -// } - -// /// @notice Checks if a set contains a value -// /// @dev This method does not clear the upper bits of `value`, that is expected to be done as part of -// casting -// /// to the correct type. If this function is provided the sentinel value by using the upper bits, this -// function -// /// may returns `true`. -// /// @param set The set to check -// /// @param associated The address the set is associated with -// /// @param value The value to check for -// /// @return True if the set contains the value, false otherwise -// function contains(AssociatedLinkedListSet storage set, address associated, SetValue value) -// internal -// view -// returns (bool) -// { -// bytes32 unwrappedKey = bytes32(SetValue.unwrap(value)); -// TempBytesMemory keyBuffer = _allocateTempKeyBuffer(set, associated); - -// StoragePointer slot = _mapLookup(keyBuffer, unwrappedKey); -// return _load(slot) != bytes32(0); -// } - -// /// @notice Checks if a set is empty -// /// @param set The set to check -// /// @param associated The address the set is associated with -// /// @return True if the set is empty, false otherwise -// function isEmpty(AssociatedLinkedListSet storage set, address associated) internal view returns (bool) { -// TempBytesMemory keyBuffer = _allocateTempKeyBuffer(set, associated); - -// StoragePointer sentinelSlot = _mapLookup(keyBuffer, SENTINEL_VALUE); -// bytes32 val = _load(sentinelSlot); -// return val == bytes32(0) || isSentinel(val); // either the sentinel is unset, or points to itself -// } - -// /// @notice Get the flags on a value in the set. -// /// @dev The reserved lower 2 bits will not be returned, as those are reserved for the sentinel and has next -// /// bit. -// /// @param set The set containing the value. -// /// @param associated The address the set is associated with. -// /// @param value The value to get the flags from. -// /// @return The flags set on the value. -// function getFlags(AssociatedLinkedListSet storage set, address associated, SetValue value) -// internal -// view -// returns (uint16) -// { -// bytes32 unwrappedKey = SetValue.unwrap(value); -// TempBytesMemory keyBuffer = _allocateTempKeyBuffer(set, associated); -// return uint16(uint256(_load(_mapLookup(keyBuffer, unwrappedKey))) & 0xFFFC); -// } - -// /// @notice Check if the flags on a value are enabled. -// /// @dev The reserved lower 2 bits will be ignored, as those are reserved for the sentinel and has next bit. -// /// @param set The set containing the value. -// /// @param associated The address the set is associated with. -// /// @param value The value to check the flags on. -// /// @param flags The flags to check. -// /// @return True if all of the flags are enabled, false otherwise. -// function flagsEnabled(AssociatedLinkedListSet storage set, address associated, SetValue value, uint16 flags) -// internal -// view -// returns (bool) -// { -// flags &= 0xFFFC; -// return getFlags(set, associated, value) & flags == flags; -// } - -// /// @notice Check if the flags on a value are disabled. -// /// @dev The reserved lower 2 bits will be ignored, as those are reserved for the sentinel and has next bit. -// /// @param set The set containing the value. -// /// @param associated The address the set is associated with. -// /// @param value The value to check the flags on. -// /// @param flags The flags to check. -// /// @return True if all of the flags are disabled, false otherwise. -// function flagsDisabled(AssociatedLinkedListSet storage set, address associated, SetValue value, uint16 -// flags) -// internal -// view -// returns (bool) -// { -// flags &= 0xFFFC; -// return ~(getFlags(set, associated, value)) & flags == flags; -// } - -// /// @notice Gets all elements in a set. -// /// @dev This is an O(n) operation, where n is the number of elements in the set. -// /// @param set The set to get the elements of. -// /// @return res An array of all elements in the set. -// function getAll(AssociatedLinkedListSet storage set, address associated) -// internal -// view -// returns (SetValue[] memory res) -// { -// TempBytesMemory keyBuffer = _allocateTempKeyBuffer(set, associated); - -// StoragePointer sentinelSlot = _mapLookup(keyBuffer, SENTINEL_VALUE); -// bytes32 cursor = _load(sentinelSlot); - -// uint256 count; -// while (!isSentinel(cursor) && cursor != bytes32(0)) { -// unchecked { -// ++count; -// } -// bytes32 cleared = clearFlags(cursor); - -// if (hasNext(cursor)) { -// StoragePointer cursorSlot = _mapLookup(keyBuffer, cleared); -// cursor = _load(cursorSlot); -// } else { -// cursor = bytes32(0); -// } -// } - -// res = new SetValue[](count); - -// if (count == 0) { -// return res; -// } - -// // Re-allocate the key buffer because we just overwrote it! -// keyBuffer = _allocateTempKeyBuffer(set, associated); - -// cursor = SENTINEL_VALUE; -// for (uint256 i = 0; i < count;) { -// StoragePointer cursorSlot = _mapLookup(keyBuffer, cursor); -// bytes32 cursorValue = _load(cursorSlot); -// bytes32 cleared = clearFlags(cursorValue); -// res[i] = SetValue.wrap(bytes30(cleared)); -// cursor = cleared; - -// unchecked { -// ++i; -// } -// } -// } - -// function isSentinel(bytes32 value) internal pure returns (bool ret) { -// assembly ("memory-safe") { -// ret := and(value, 1) -// } -// } - -// function hasNext(bytes32 value) internal pure returns (bool) { -// return value & HAS_NEXT_FLAG != 0; -// } - -// function clearFlags(bytes32 val) internal pure returns (bytes32) { -// return val & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0001; -// } - -// /// @dev Preserves the lower two bits -// function clearUserFlags(bytes32 val) internal pure returns (bytes32) { -// return val & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0003; -// } - -// function getUserFlags(bytes32 val) internal pure returns (bytes32) { -// return val & bytes32(uint256(0xFFFC)); -// } - -// // PRIVATE METHODS - -// /// @notice Given an allocated key buffer, returns the storage slot for a given key -// function _mapLookup(TempBytesMemory keyBuffer, bytes32 value) private pure returns (StoragePointer slot) { -// assembly ("memory-safe") { -// // Store the value in the last word. -// let keyWord2 := value -// mstore(add(keyBuffer, 0x60), keyWord2) -// slot := keccak256(keyBuffer, 0x80) -// } -// } - -// /// @notice Allocates a key buffer for a given ID and associated address into scratch space memory. -// /// @dev The returned buffer must not be used if any additional memory is allocated after calling this -// /// function. -// /// @param set The set to allocate the key buffer for. -// /// @param associated The address the set is associated with. -// /// @return key A key buffer that can be used to lookup values in the set -// function _allocateTempKeyBuffer(AssociatedLinkedListSet storage set, address associated) -// private -// pure -// returns (TempBytesMemory key) -// { -// // Key derivation for an entry -// // associated addr (left-padded) || prefix || uint224(0) batchIndex || set storage slot || entry -// // Word 1: -// // | zeros | 0x000000000000000000000000________________________________________ | -// // | address | 0x________________________AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | -// // Word 2: -// // | prefix | 0xPPPPPPPP________________________________________________________ | -// // | batch index (zero) | 0x________00000000000000000000000000000000000000000000000000000000 | -// // Word 3: -// // | set storage slot | 0xSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS | -// // Word 4: -// // | entry value | 0xVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV____ | -// // | entry meta | 0x____________________________________________________________MMMM | - -// // The batch index is for consistency with PluginStorageLib, and the prefix in front of it is -// // to prevent any potential crafted collisions where the batch index may be equal to storage slot -// // of the ALLS. The prefix is set to the upper bits of the batch index to make it infeasible to -// // reach from just incrementing the value. - -// // This segment is memory-safe because it only uses the scratch space memory after the value of the free -// // memory pointer. -// // See https://docs.soliditylang.org/en/v0.8.21/assembly.html#memory-safety -// assembly ("memory-safe") { -// // Clean upper bits of arguments -// associated := and(associated, 0xffffffffffffffffffffffffffffffffffffffff) - -// // Use memory past-the-free-memory-pointer without updating it, as this is just scratch space -// key := mload(0x40) -// // Store the associated address in the first word, left-padded with zeroes -// mstore(key, associated) -// // Store the prefix and a batch index of 0 -// mstore(add(key, 0x20), _ASSOCIATED_STORAGE_PREFIX) -// // Store the list's storage slot in the third word -// mstore(add(key, 0x40), set.slot) -// // Leaves the last word open for the value entry -// } - -// return key; -// } - -// /// @dev Loads a value from storage -// function _load(StoragePointer ptr) private view returns (bytes32 val) { -// assembly ("memory-safe") { -// val := sload(ptr) -// } -// } - -// /// @dev Writes a value into storage -// function _store(StoragePointer ptr, bytes32 val) private { -// assembly ("memory-safe") { -// sstore(ptr, val) -// } -// } -// } diff --git a/src/libraries/PluginStorageLib.sol b/src/libraries/PluginStorageLib.sol deleted file mode 100644 index 5811f8f8..00000000 --- a/src/libraries/PluginStorageLib.sol +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.25; - -// type StoragePointer is bytes32; - -// /// @title Plugin Storage Library -// /// @notice Library for allocating and accessing ERC-4337 address-associated storage within plugins. -// library PluginStorageLib { -// /// @notice Allocates a memory buffer for an associated storage key, and sets the associated address and -// batch -// /// index. -// /// @param addr The address to associate with the storage key. -// /// @param batchIndex The batch index to associate with the storage key. -// /// @param keySize The size of the key in words, where each word is 32 bytes. Not inclusive of the address -// and -// /// batch index. -// /// @return key The allocated memory buffer. -// function allocateAssociatedStorageKey(address addr, uint256 batchIndex, uint8 keySize) -// internal -// pure -// returns (bytes memory key) -// { -// assembly ("memory-safe") { -// // Clear any dirty upper bits of keySize to prevent overflow -// keySize := and(keySize, 0xff) - -// // compute the total size of the buffer, include the address and batch index -// let totalSize := add(64, mul(32, keySize)) - -// // Allocate memory for the key -// key := mload(0x40) -// mstore(0x40, add(add(key, totalSize), 32)) -// mstore(key, totalSize) - -// // Clear any dirty upper bits of address -// addr := and(addr, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) -// // Store the address and batch index in the key buffer -// mstore(add(key, 32), addr) -// mstore(add(key, 64), batchIndex) -// } -// } - -// function associatedStorageLookup(bytes memory key, bytes32 input) internal pure returns (StoragePointer ptr) -// { -// assembly ("memory-safe") { -// mstore(add(key, 96), input) -// ptr := keccak256(add(key, 32), mload(key)) -// } -// } - -// function associatedStorageLookup(bytes memory key, bytes32 input1, bytes32 input2) -// internal -// pure -// returns (StoragePointer ptr) -// { -// assembly ("memory-safe") { -// mstore(add(key, 96), input1) -// mstore(add(key, 128), input2) -// ptr := keccak256(add(key, 32), mload(key)) -// } -// } -// } diff --git a/src/samples/plugins/ModularSessionKeyPlugin.sol b/src/samples/plugins/ModularSessionKeyPlugin.sol deleted file mode 100644 index 53b4c0eb..00000000 --- a/src/samples/plugins/ModularSessionKeyPlugin.sol +++ /dev/null @@ -1,373 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.25; - -// import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -// import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; -// import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interfaces/PackedUserOperation.sol"; -// import {UpgradeableModularAccount} from "../../account/UpgradeableModularAccount.sol"; -// import { -// ManifestFunction, -// ManifestAssociatedFunctionType, -// ManifestAssociatedFunction, -// PluginManifest, -// PluginMetadata, -// SelectorPermission -// } from "../../interfaces/IPlugin.sol"; -// import {BasePlugin} from "../../plugins/BasePlugin.sol"; -// import {IModularSessionKeyPlugin} from "./interfaces/ISessionKeyPlugin.sol"; -// import {ISingleOwnerPlugin} from "../../plugins/owner/ISingleOwnerPlugin.sol"; -// import {SingleOwnerPlugin} from "../../plugins/owner/SingleOwnerPlugin.sol"; -// import {PluginStorageLib, StoragePointer} from "../../libraries/PluginStorageLib.sol"; - -// /// @title Modular Session Key Plugin -// /// @author Decipher ERC-6900 Team -// /// @notice This plugin allows some designated EOA or smart contract to temporarily -// /// own a modular account. Note that this plugin is ONLY for demonstrating the purpose -// /// of the functionalities of ERC-6900, and MUST not be used at the production level. -// /// This modular session key plugin acts as a 'parent plugin' for all specific session -// /// keys. Using dependency, this plugin can be thought as a parent contract that stores -// /// session key duration information, and validation functions for session keys. All -// /// logics for session keys will be implemented in child plugins. -// /// It allows for session key owners to access MSCA both through user operation and -// /// runtime, with its own validation functions. -// /// Also, it has a dependency on SingleOwnerPlugin, to make sure that only the owner of -// /// the MSCA can add or remove session keys. -// contract ModularSessionKeyPlugin is BasePlugin, IModularSessionKeyPlugin { -// using ECDSA for bytes32; -// using PluginStorageLib for address; -// using PluginStorageLib for bytes; -// using EnumerableSet for EnumerableSet.Bytes32Set; - -// string public constant NAME = "Modular Session Key Plugin"; -// string public constant VERSION = "1.0.0"; -// string public constant AUTHOR = "Decipher ERC-6900 Team"; - -// uint256 internal constant _SIG_VALIDATION_FAILED = 1; - -// mapping(address account => EnumerableSet.Bytes32Set) private _sessionKeySet; - -// struct SessionInfo { -// uint48 validAfter; -// uint48 validUntil; -// } - -// // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -// // ┃ Execution functions ┃ -// // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - -// /// @inheritdoc IModularSessionKeyPlugin -// function addSessionKey(address sessionKey, bytes4 allowedSelector, uint48 validAfter, uint48 validUntil) -// external -// { -// _addSessionKey(msg.sender, sessionKey, allowedSelector, validAfter, validUntil); -// emit SessionKeyAdded(msg.sender, sessionKey, allowedSelector, validAfter, validUntil); -// } - -// /// @inheritdoc IModularSessionKeyPlugin -// function removeSessionKey(address sessionKey, bytes4 allowedSelector) external { -// _removeSessionKey(msg.sender, sessionKey, allowedSelector); -// emit SessionKeyRemoved(msg.sender, sessionKey, allowedSelector); -// } - -// /// @inheritdoc IModularSessionKeyPlugin -// function addSessionKeyBatch( -// address[] calldata sessionKeys, -// bytes4[] calldata allowedSelectors, -// uint48[] calldata validAfters, -// uint48[] calldata validUntils -// ) external { -// if ( -// sessionKeys.length != allowedSelectors.length || sessionKeys.length != validAfters.length -// || sessionKeys.length != validUntils.length -// ) { -// revert WrongDataLength(); -// } -// for (uint256 i = 0; i < sessionKeys.length;) { -// _addSessionKey(msg.sender, sessionKeys[i], allowedSelectors[i], validAfters[i], validUntils[i]); - -// unchecked { -// ++i; -// } -// } -// emit SessionKeysAdded(msg.sender, sessionKeys, allowedSelectors, validAfters, validUntils); -// } - -// function removeSessionKeyBatch(address[] calldata sessionKeys, bytes4[] calldata allowedSelectors) external -// { -// if (sessionKeys.length != allowedSelectors.length) { -// revert WrongDataLength(); -// } -// for (uint256 i = 0; i < sessionKeys.length;) { -// _removeSessionKey(msg.sender, sessionKeys[i], allowedSelectors[i]); - -// unchecked { -// ++i; -// } -// } -// emit SessionKeysRemoved(msg.sender, sessionKeys, allowedSelectors); -// } - -// // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -// // ┃ Plugin view functions ┃ -// // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - -// /// @inheritdoc IModularSessionKeyPlugin -// function getSessionDuration(address account, address sessionKey, bytes4 allowedSelector) -// external -// view -// returns (uint48 validAfter, uint48 validUntil) -// { -// bytes memory key = account.allocateAssociatedStorageKey(0, 1); -// StoragePointer ptr = key.associatedStorageLookup(keccak256(abi.encodePacked(sessionKey, -// allowedSelector))); -// SessionInfo storage sessionInfo = _castPtrToStruct(ptr); -// validAfter = sessionInfo.validAfter; -// validUntil = sessionInfo.validUntil; -// } - -// /// @inheritdoc IModularSessionKeyPlugin -// function getSessionKeysAndSelectors(address account) -// external -// view -// returns (address[] memory sessionKeys, bytes4[] memory selectors) -// { -// EnumerableSet.Bytes32Set storage sessionKeySet = _sessionKeySet[account]; -// uint256 length = sessionKeySet.length(); -// sessionKeys = new address[](length); -// selectors = new bytes4[](length); -// for (uint256 i = 0; i < length;) { -// (sessionKeys[i], selectors[i]) = _castToAddressAndBytes4(sessionKeySet.at(i)); - -// unchecked { -// ++i; -// } -// } -// } - -// // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -// // ┃ Plugin interface functions ┃ -// // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - -// /// @inheritdoc BasePlugin -// function onInstall(bytes calldata data) external override { -// if (data.length != 0) { -// ( -// address[] memory sessionKeys, -// bytes4[] memory allowedSelectors, -// uint48[] memory validAfters, -// uint48[] memory validUntils -// ) = abi.decode(data, (address[], bytes4[], uint48[], uint48[])); -// if ( -// sessionKeys.length != allowedSelectors.length || sessionKeys.length != validAfters.length -// || sessionKeys.length != validUntils.length -// ) { -// revert WrongDataLength(); -// } -// for (uint256 i = 0; i < sessionKeys.length;) { -// _addSessionKey(msg.sender, sessionKeys[i], allowedSelectors[i], validAfters[i], validUntils[i]); - -// unchecked { -// ++i; -// } -// } -// } -// } - -// /// @inheritdoc BasePlugin -// function onUninstall(bytes calldata) external override { -// EnumerableSet.Bytes32Set storage sessionKeySet = _sessionKeySet[msg.sender]; -// uint256 length = sessionKeySet.length(); -// for (uint256 i = 0; i < length;) { -// (address sessionKey, bytes4 allowedSelecor) = _castToAddressAndBytes4(sessionKeySet.at(i)); -// _removeSessionKey(msg.sender, sessionKey, allowedSelecor); - -// unchecked { -// ++i; -// } -// } -// } - -// /// @inheritdoc BasePlugin -// function userOpValidationFunction(uint8 functionId, PackedUserOperation calldata userOp, bytes32 userOpHash) -// external -// view -// override -// returns (uint256) -// { -// if (functionId == uint8(FunctionId.VALIDATION_TEMPORARY_OWNER)) { -// (address signer, ECDSA.RecoverError err) = -// userOpHash.toEthSignedMessageHash().tryRecover(userOp.signature); -// if (err != ECDSA.RecoverError.NoError) { -// revert InvalidSignature(); -// } -// bytes4 selector = bytes4(userOp.callData[0:4]); -// bytes memory key = msg.sender.allocateAssociatedStorageKey(0, 1); -// StoragePointer ptr = key.associatedStorageLookup(keccak256(abi.encodePacked(signer, selector))); -// SessionInfo storage duration = _castPtrToStruct(ptr); -// uint48 validAfter = duration.validAfter; -// uint48 validUntil = duration.validUntil; - -// return _packValidationData(validUntil == 0, validUntil, validAfter); -// } -// revert NotImplemented(); -// } - -// /// @inheritdoc BasePlugin -// function runtimeValidationFunction(uint8 functionId, address sender, uint256, bytes calldata data) -// external -// view -// override -// { -// if (functionId == uint8(FunctionId.VALIDATION_TEMPORARY_OWNER)) { -// bytes4 selector = bytes4(data[0:4]); -// bytes memory key = msg.sender.allocateAssociatedStorageKey(0, 1); -// StoragePointer ptr = key.associatedStorageLookup(keccak256(abi.encodePacked(sender, selector))); -// SessionInfo storage duration = _castPtrToStruct(ptr); -// uint48 validAfter = duration.validAfter; -// uint48 validUntil = duration.validUntil; - -// if (validUntil != 0) { -// if (block.timestamp < validAfter || block.timestamp > validUntil) { -// revert WrongTimeRangeForSession(); -// } -// return; -// } -// revert NotAuthorized(); -// } -// revert NotImplemented(); -// } - -// /// @inheritdoc BasePlugin -// function pluginManifest() external pure override returns (PluginManifest memory) { -// PluginManifest memory manifest; - -// manifest.executionFunctions = new bytes4[](4); -// manifest.executionFunctions[0] = this.addSessionKey.selector; -// manifest.executionFunctions[1] = this.removeSessionKey.selector; -// manifest.executionFunctions[2] = this.addSessionKeyBatch.selector; -// manifest.executionFunctions[3] = this.removeSessionKeyBatch.selector; - -// ManifestFunction memory ownerValidationFunction = ManifestFunction({ -// functionType: ManifestAssociatedFunctionType.DEPENDENCY, -// functionId: 0, // Unused. -// dependencyIndex: 0 // Used as first index. -// }); -// manifest.validationFunctions = new ManifestAssociatedFunction[](5); -// manifest.validationFunctions[0] = ManifestAssociatedFunction({ -// executionSelector: this.addSessionKey.selector, -// associatedFunction: ownerValidationFunction -// }); -// manifest.validationFunctions[1] = ManifestAssociatedFunction({ -// executionSelector: this.removeSessionKey.selector, -// associatedFunction: ownerValidationFunction -// }); -// manifest.validationFunctions[2] = ManifestAssociatedFunction({ -// executionSelector: this.addSessionKeyBatch.selector, -// associatedFunction: ownerValidationFunction -// }); -// manifest.validationFunctions[3] = ManifestAssociatedFunction({ -// executionSelector: this.removeSessionKeyBatch.selector, -// associatedFunction: ownerValidationFunction -// }); - -// ManifestFunction memory alwaysAllowFunction = ManifestFunction({ -// functionType: ManifestAssociatedFunctionType.RUNTIME_VALIDATION_ALWAYS_ALLOW, -// functionId: 0, // Unused. -// dependencyIndex: 0 // Unused. -// }); - -// manifest.validationFunctions[4] = ManifestAssociatedFunction({ -// executionSelector: this.getSessionDuration.selector, -// associatedFunction: alwaysAllowFunction -// }); - -// manifest.dependencyInterfaceIds = new bytes4[](1); -// manifest.dependencyInterfaceIds[0] = type(ISingleOwnerPlugin).interfaceId; - -// return manifest; -// } - -// /// @inheritdoc BasePlugin -// function pluginMetadata() external pure virtual override returns (PluginMetadata memory) { -// PluginMetadata memory metadata; -// metadata.name = NAME; -// metadata.version = VERSION; -// metadata.author = AUTHOR; - -// return metadata; -// } - -// // ┏━━━━━━━━━━━━━━━┓ -// // ┃ EIP-165 ┃ -// // ┗━━━━━━━━━━━━━━━┛ - -// /// @inheritdoc BasePlugin -// function supportsInterface(bytes4 interfaceId) public view override returns (bool) { -// return interfaceId == type(IModularSessionKeyPlugin).interfaceId || -// super.supportsInterface(interfaceId); -// } - -// // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -// // ┃ Internal / Private functions ┃ -// // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - -// function _addSessionKey( -// address account, -// address sessionKey, -// bytes4 allowedSelector, -// uint48 validAfter, -// uint48 validUntil -// ) internal { -// if (validUntil <= validAfter) { -// revert WrongTimeRangeForSession(); -// } -// bytes memory key = account.allocateAssociatedStorageKey(0, 1); -// StoragePointer ptr = key.associatedStorageLookup(keccak256(abi.encodePacked(sessionKey, -// allowedSelector))); -// SessionInfo storage sessionInfo = _castPtrToStruct(ptr); -// sessionInfo.validAfter = validAfter; -// sessionInfo.validUntil = validUntil; - -// EnumerableSet.Bytes32Set storage sessionKeySet = _sessionKeySet[account]; -// sessionKeySet.add(_castToBytes32(sessionKey, allowedSelector)); -// } - -// function _removeSessionKey(address account, address sessionKey, bytes4 allowedSelector) internal { -// bytes memory key = account.allocateAssociatedStorageKey(0, 1); -// StoragePointer ptr = key.associatedStorageLookup(keccak256(abi.encodePacked(sessionKey, -// allowedSelector))); -// SessionInfo storage sessionInfo = _castPtrToStruct(ptr); -// sessionInfo.validAfter = 0; -// sessionInfo.validUntil = 0; - -// EnumerableSet.Bytes32Set storage sessionKeySet = _sessionKeySet[account]; -// sessionKeySet.remove(_castToBytes32(sessionKey, allowedSelector)); -// } - -// function _castPtrToStruct(StoragePointer ptr) internal pure returns (SessionInfo storage val) { -// assembly ("memory-safe") { -// val.slot := ptr -// } -// } - -// function _castToBytes32(address addr, bytes4 b4) internal pure returns (bytes32 res) { -// assembly { -// res := or(shl(32, addr), b4) -// } -// } - -// function _castToAddressAndBytes4(bytes32 b32) internal pure returns (address addr, bytes4 b4) { -// assembly { -// addr := shr(32, b32) -// b4 := and(b32, 0xFFFFFFFF) -// } -// } - -// function _packValidationData(bool sigFailed, uint48 validUntil, uint48 validAfter) -// internal -// pure -// returns (uint256) -// { -// return (sigFailed ? 1 : 0) | (uint256(validUntil) << 160) | (uint256(validAfter) << (160 + 48)); -// } -// } diff --git a/src/samples/plugins/TokenSessionKeyPlugin.sol b/src/samples/plugins/TokenSessionKeyPlugin.sol deleted file mode 100644 index 09275374..00000000 --- a/src/samples/plugins/TokenSessionKeyPlugin.sol +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.25; - -// import { -// ManifestFunction, -// ManifestAssociatedFunctionType, -// ManifestAssociatedFunction, -// PluginManifest, -// PluginMetadata, -// SelectorPermission, -// ManifestExternalCallPermission -// } from "../../interfaces/IPlugin.sol"; -// import {BasePlugin} from "../../plugins/BasePlugin.sol"; -// import {ModularSessionKeyPlugin} from "./ModularSessionKeyPlugin.sol"; -// import {ITokenSessionKeyPlugin} from "./interfaces/ITokenSessionKeyPlugin.sol"; -// import {IModularSessionKeyPlugin} from "./interfaces/ISessionKeyPlugin.sol"; -// import {IPluginExecutor} from "../../interfaces/IPluginExecutor.sol"; - -// /// @title Token Session Key Plugin -// /// @author Decipher ERC-6900 Team -// /// @notice This plugin acts as a 'child plugin' for ModularSessionKeyPlugin. -// /// It implements the logic for session keys that are allowed to call ERC20 -// /// transferFrom function. It allows for session key owners to access MSCA -// /// with `transferFromSessionKey` function, which calls `executeFromPluginExternal` -// /// function in PluginExecutor contract. -// /// The target ERC20 contract and the selector for transferFrom function are hardcoded -// /// in this plugin, since the pluginManifest function requires the information of -// /// permitted external calls not to be changed in the future. For other child session -// /// key plugins, there can be a set of permitted external calls according to the -// /// specific needs. -// contract TokenSessionKeyPlugin is BasePlugin, ITokenSessionKeyPlugin { -// string public constant NAME = "Token Session Key Plugin"; -// string public constant VERSION = "1.0.0"; -// string public constant AUTHOR = "Decipher ERC-6900 Team"; - -// // Mock address of target ERC20 contract -// address public constant TARGET_ERC20_CONTRACT = 0xdeaDDeADDEaDdeaDdEAddEADDEAdDeadDEADDEaD; -// bytes4 public constant TRANSFERFROM_SELECTOR = -// bytes4(keccak256(bytes("transferFrom(address,address,uint256)"))); - -// // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -// // ┃ Execution functions ┃ -// // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - -// /// @inheritdoc ITokenSessionKeyPlugin -// function transferFromSessionKey(address target, address from, address to, uint256 amount) -// external -// returns (bytes memory returnData) -// { -// bytes memory data = abi.encodeWithSelector(TRANSFERFROM_SELECTOR, from, to, amount); -// returnData = IPluginExecutor(msg.sender).executeFromPluginExternal(target, 0, data); -// } - -// // ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -// // ┃ Plugin interface functions ┃ -// // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - -// /// @inheritdoc BasePlugin -// function onInstall(bytes calldata data) external override {} - -// /// @inheritdoc BasePlugin -// function onUninstall(bytes calldata data) external override {} - -// /// @inheritdoc BasePlugin -// function pluginManifest() external pure override returns (PluginManifest memory) { -// PluginManifest memory manifest; - -// manifest.executionFunctions = new bytes4[](1); -// manifest.executionFunctions[0] = this.transferFromSessionKey.selector; - -// ManifestFunction memory tempOwnerValidationFunction = ManifestFunction({ -// functionType: ManifestAssociatedFunctionType.DEPENDENCY, -// functionId: 0, // Unused -// dependencyIndex: 0 // Used as first index -// }); - -// manifest.validationFunctions = new ManifestAssociatedFunction[](1); -// manifest.validationFunctions[0] = ManifestAssociatedFunction({ -// executionSelector: this.transferFromSessionKey.selector, -// associatedFunction: tempOwnerValidationFunction -// }); - -// manifest.dependencyInterfaceIds = new bytes4[](1); -// manifest.dependencyInterfaceIds[0] = type(IModularSessionKeyPlugin).interfaceId; - -// bytes4[] memory permittedExternalSelectors = new bytes4[](1); -// permittedExternalSelectors[0] = TRANSFERFROM_SELECTOR; - -// manifest.permittedExternalCalls = new ManifestExternalCallPermission[](1); -// manifest.permittedExternalCalls[0] = ManifestExternalCallPermission({ -// externalAddress: TARGET_ERC20_CONTRACT, -// permitAnySelector: false, -// selectors: permittedExternalSelectors -// }); - -// return manifest; -// } - -// /// @inheritdoc BasePlugin -// function pluginMetadata() external pure virtual override returns (PluginMetadata memory) { -// PluginMetadata memory metadata; -// metadata.name = NAME; -// metadata.version = VERSION; -// metadata.author = AUTHOR; - -// return metadata; -// } - -// // ┏━━━━━━━━━━━━━━━┓ -// // ┃ EIP-165 ┃ -// // ┗━━━━━━━━━━━━━━━┛ - -// /// @inheritdoc BasePlugin -// function supportsInterface(bytes4 interfaceId) public view override returns (bool) { -// return interfaceId == type(ITokenSessionKeyPlugin).interfaceId || super.supportsInterface(interfaceId); -// } -// } diff --git a/src/samples/plugins/interfaces/ISessionKeyPlugin.sol b/src/samples/plugins/interfaces/ISessionKeyPlugin.sol deleted file mode 100644 index fd1b9bd0..00000000 --- a/src/samples/plugins/interfaces/ISessionKeyPlugin.sol +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.25; - -// import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interfaces/PackedUserOperation.sol"; - -// interface IModularSessionKeyPlugin { -// enum FunctionId { -// VALIDATION_TEMPORARY_OWNER -// } - -// /// @notice This event is emitted when a session key is added to the account. -// /// @param account The account whose session key is updated. -// /// @param sessionKey The address of the session key. -// /// @param selector The selector of the function that the session key is allowed to call. -// /// @param validAfter The time after which the owner is valid. -// /// @param validUntil The time until which the owner is valid. -// event SessionKeyAdded( -// address indexed account, address indexed sessionKey, bytes4 selector, uint48 validAfter, uint48 -// validUntil -// ); - -// /// @notice This event is emitted when a session key is removed from the account. -// /// @param account The account whose session key is updated. -// /// @param sessionKey The address of the session key. -// /// @param selector The selector of the function that the session key is allowed to call. -// event SessionKeyRemoved(address indexed account, address indexed sessionKey, bytes4 selector); - -// /// @notice This event is emitted when session keys are added to the account. -// /// @param account The account whose session keys are updated. -// /// @param sessionKeys The addresses of the session keys. -// /// @param selectors The selectors of the functions that the session keys are allowed to call. -// /// @param validAfters The times after which the owners are valid. -// /// @param validUntils The times until which the owners are valid. -// event SessionKeysAdded( -// address indexed account, -// address[] sessionKeys, -// bytes4[] selectors, -// uint48[] validAfters, -// uint48[] validUntils -// ); - -// /// @notice This event is emitted when session keys are removed from the account. -// /// @param account The account whose session keys are updated. -// /// @param sessionKeys The addresses of the session keys. -// /// @param selectors The selectors of the functions that the session keys are allowed to call. -// event SessionKeysRemoved(address indexed account, address[] sessionKeys, bytes4[] selectors); - -// error InvalidSignature(); -// error NotAuthorized(); -// error WrongTimeRangeForSession(); -// error WrongDataLength(); - -// /// @notice Add a session key to the account. -// /// @dev This function is installed on the account as part of plugin installation, and should -// /// only be called from an account. The function selector installed by a child session key plugin -// /// is passed as a parameter, which enforces its own permissions on the calls it can make. -// /// @param sessionKey The address of the session key. -// /// @param allowedSelector The selector of the function that the session key is allowed to call. -// /// @param validAfter The time after which the owner is valid. -// /// @param validUntil The time until which the owner is valid. -// function addSessionKey(address sessionKey, bytes4 allowedSelector, uint48 validAfter, uint48 validUntil) -// external; - -// /// @notice Remove a session key from the account. -// /// @dev This function is installed on the account as part of plugin installation, and should -// /// only be called from an account. -// /// @param sessionKey The address of the session key. -// /// @param allowedSelector The selector of the function that the session key is allowed to call. -// function removeSessionKey(address sessionKey, bytes4 allowedSelector) external; - -// /// @notice Add session keys to the account. -// /// @dev This function is installed on the account as part of plugin installation, and should -// /// only be called from an account. -// /// @param sessionKeys The addresses of the session keys. -// /// @param allowedSelectors The selectors of the functions that the session keys are allowed to call. -// /// @param validAfters The times after which the owners are valid. -// /// @param validUntils The times until which the owners are valid. -// function addSessionKeyBatch( -// address[] calldata sessionKeys, -// bytes4[] calldata allowedSelectors, -// uint48[] calldata validAfters, -// uint48[] calldata validUntils -// ) external; - -// /// @notice Remove session keys from the account. -// /// @dev This function is installed on the account as part of plugin installation, and should -// /// only be called from an account. -// /// @param sessionKeys The addresses of the session keys. -// /// @param allowedSelectors The selectors of the functions that the session keys are allowed to call. -// function removeSessionKeyBatch(address[] calldata sessionKeys, bytes4[] calldata allowedSelectors) external; - -// /// @notice Get Session data for a given account and session key. -// /// @param account The account to get session data for. -// /// @param sessionKey The address of the session key. -// /// @param allowedSelector The selector of the function that the session key is allowed to call. -// function getSessionDuration(address account, address sessionKey, bytes4 allowedSelector) -// external -// view -// returns (uint48 validAfter, uint48 validUntil); - -// /// @notice Get all session keys and selectors for a given account. -// /// @param account The account to get session keys and selectors for. -// /// @return sessionKeys The addresses of the session keys. -// /// @return selectors The selectors of the functions that the session keys are allowed to call. -// function getSessionKeysAndSelectors(address account) -// external -// view -// returns (address[] memory sessionKeys, bytes4[] memory selectors); -// } diff --git a/src/samples/plugins/interfaces/ITokenSessionKeyPlugin.sol b/src/samples/plugins/interfaces/ITokenSessionKeyPlugin.sol deleted file mode 100644 index 2de98c0a..00000000 --- a/src/samples/plugins/interfaces/ITokenSessionKeyPlugin.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.25; - -// import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interfaces/PackedUserOperation.sol"; - -// interface ITokenSessionKeyPlugin { -// error NotAuthorized(); - -// /// @notice Route call to executeFromPluginExternal at the MSCA. -// /// @dev This function will call with value = 0, since sending ether -// /// to ERC20 contract is not a normal case. -// /// @param target The target address to execute the call on. -// /// @param from The address to transfer tokens from. -// /// @param to The address to transfer tokens to. -// /// @param amount The amount of tokens to transfer. -// function transferFromSessionKey(address target, address from, address to, uint256 amount) -// external -// returns (bytes memory returnData); -// } diff --git a/test/libraries/AssociatedLinkedListSetLib.t.sol b/test/libraries/AssociatedLinkedListSetLib.t.sol deleted file mode 100644 index 99ed5e25..00000000 --- a/test/libraries/AssociatedLinkedListSetLib.t.sol +++ /dev/null @@ -1,220 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; - -// import {Test} from "forge-std/Test.sol"; -// import { -// AssociatedLinkedListSet, -// AssociatedLinkedListSetLib, -// SENTINEL_VALUE, -// SetValue -// } from "../../src/libraries/AssociatedLinkedListSetLib.sol"; - -// contract AssociatedLinkedListSetLibTest is Test { -// using AssociatedLinkedListSetLib for AssociatedLinkedListSet; - -// AssociatedLinkedListSet internal _set1; -// AssociatedLinkedListSet internal _set2; - -// address internal _associated = address(this); - -// // User-defined function for wrapping from bytes30 (uint240) to SetValue -// // Can define a custom one for addresses, uints, etc. -// function _getListValue(uint240 value) internal pure returns (SetValue) { -// return SetValue.wrap(bytes30(value)); -// } - -// function test_add_contains() public { -// SetValue value = _getListValue(12); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.contains(_associated, value)); -// } - -// function test_empty() public { -// SetValue value = _getListValue(12); - -// assertFalse(_set1.contains(_associated, value)); -// assertTrue(_set1.isEmpty(_associated)); -// } - -// function test_remove() public { -// SetValue value = _getListValue(12); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.contains(_associated, value)); - -// assertTrue(_set1.tryRemove(_associated, value)); -// assertFalse(_set1.contains(_associated, value)); -// } - -// function test_remove_empty() public { -// SetValue value = _getListValue(12); - -// assertFalse(_set1.tryRemove(_associated, value)); -// } - -// function test_remove_nonexistent() public { -// SetValue value = _getListValue(12); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.contains(_associated, value)); - -// SetValue value2 = _getListValue(13); -// assertFalse(_set1.tryRemove(_associated, value2)); -// assertTrue(_set1.contains(_associated, value)); -// } - -// function test_remove_nonexistent_empty() public { -// SetValue value = _getListValue(12); - -// assertFalse(_set1.tryRemove(_associated, value)); -// } - -// function test_remove_nonexistent_empty2() public { -// SetValue value = _getListValue(12); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.contains(_associated, value)); - -// SetValue value2 = _getListValue(13); -// assertFalse(_set1.tryRemove(_associated, value2)); -// assertTrue(_set1.contains(_associated, value)); -// } - -// function test_add_remove_add() public { -// SetValue value = _getListValue(12); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.contains(_associated, value)); - -// assertTrue(_set1.tryRemove(_associated, value)); -// assertFalse(_set1.contains(_associated, value)); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.contains(_associated, value)); -// } - -// function test_add_remove_add_empty() public { -// SetValue value = _getListValue(12); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.contains(_associated, value)); - -// assertTrue(_set1.tryRemove(_associated, value)); -// assertFalse(_set1.contains(_associated, value)); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.contains(_associated, value)); -// } - -// function test_no_address_collision() public { -// SetValue value = _getListValue(12); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.contains(_associated, value)); -// assertFalse(_set2.contains(_associated, value)); -// } - -// function test_clear() public { -// SetValue value = _getListValue(12); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.contains(_associated, value)); - -// _set1.clear(_associated); - -// assertFalse(_set1.contains(_associated, value)); -// assertTrue(_set1.isEmpty(_associated)); -// } - -// function test_getAll() public { -// SetValue value = _getListValue(12); -// SetValue value2 = _getListValue(13); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.tryAdd(_associated, value2)); - -// SetValue[] memory values = _set1.getAll(_associated); -// assertEq(values.length, 2); -// // Returned set will be in reverse order of added elements -// assertEq(SetValue.unwrap(values[1]), SetValue.unwrap(value)); -// assertEq(SetValue.unwrap(values[0]), SetValue.unwrap(value2)); -// } - -// function test_getAll2() public { -// SetValue value = _getListValue(12); -// SetValue value2 = _getListValue(13); -// SetValue value3 = _getListValue(14); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.tryAdd(_associated, value2)); -// assertTrue(_set1.tryAdd(_associated, value3)); - -// SetValue[] memory values = _set1.getAll(_associated); -// assertEq(values.length, 3); -// // Returned set will be in reverse order of added elements -// assertEq(SetValue.unwrap(values[2]), SetValue.unwrap(value)); -// assertEq(SetValue.unwrap(values[1]), SetValue.unwrap(value2)); -// assertEq(SetValue.unwrap(values[0]), SetValue.unwrap(value3)); -// } - -// function test_getAll_empty() public { -// SetValue[] memory values = _set1.getAll(_associated); -// assertEq(values.length, 0); -// } - -// function test_tryRemoveKnown1() public { -// SetValue value = _getListValue(12); - -// assertTrue(_set1.tryAdd(_associated, value)); -// assertTrue(_set1.contains(_associated, value)); - -// assertTrue(_set1.tryRemoveKnown(_associated, value, SENTINEL_VALUE)); -// assertFalse(_set1.contains(_associated, value)); -// assertTrue(_set1.isEmpty(_associated)); -// } - -// function test_tryRemoveKnown2() public { -// SetValue value1 = _getListValue(12); -// SetValue value2 = _getListValue(13); - -// assertTrue(_set1.tryAdd(_associated, value1)); -// assertTrue(_set1.tryAdd(_associated, value2)); -// assertTrue(_set1.contains(_associated, value1)); -// assertTrue(_set1.contains(_associated, value2)); - -// // Assert that getAll returns the correct values -// SetValue[] memory values = _set1.getAll(_associated); -// assertEq(values.length, 2); -// assertEq(SetValue.unwrap(values[1]), SetValue.unwrap(value1)); -// assertEq(SetValue.unwrap(values[0]), SetValue.unwrap(value2)); - -// assertTrue(_set1.tryRemoveKnown(_associated, value1, bytes32(SetValue.unwrap(value2)))); -// assertFalse(_set1.contains(_associated, value1)); -// assertTrue(_set1.contains(_associated, value2)); - -// // Assert that getAll returns the correct values -// values = _set1.getAll(_associated); -// assertEq(values.length, 1); -// assertEq(SetValue.unwrap(values[0]), SetValue.unwrap(value2)); - -// assertTrue(_set1.tryRemoveKnown(_associated, value2, SENTINEL_VALUE)); -// assertFalse(_set1.contains(_associated, value1)); - -// assertTrue(_set1.isEmpty(_associated)); -// } - -// function test_tryRemoveKnown_invalid1() public { -// SetValue value1 = _getListValue(12); -// SetValue value2 = _getListValue(13); - -// assertTrue(_set1.tryAdd(_associated, value1)); -// assertTrue(_set1.tryAdd(_associated, value2)); - -// assertFalse(_set1.tryRemoveKnown(_associated, value1, bytes32(SetValue.unwrap(value1)))); -// assertTrue(_set1.contains(_associated, value1)); - -// assertFalse(_set1.tryRemoveKnown(_associated, value2, bytes32(SetValue.unwrap(value2)))); -// assertTrue(_set1.contains(_associated, value2)); -// } -// } diff --git a/test/libraries/PluginStorageLib.t.sol b/test/libraries/PluginStorageLib.t.sol deleted file mode 100644 index 3bd1dc76..00000000 --- a/test/libraries/PluginStorageLib.t.sol +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; - -// import {Test} from "forge-std/Test.sol"; -// import {PluginStorageLib, StoragePointer} from "../../src/libraries/PluginStorageLib.sol"; - -// contract PluginStorageLibTest is Test { -// using PluginStorageLib for bytes; -// using PluginStorageLib for bytes32; - -// uint256 public constant FUZZ_ARR_SIZE = 32; - -// address public account1; - -// struct TestStruct { -// uint256 a; -// uint256 b; -// } - -// function setUp() public { -// account1 = makeAddr("account1"); -// } - -// function test_storagePointer() public { -// bytes memory key = PluginStorageLib.allocateAssociatedStorageKey(account1, 0, 1); - -// StoragePointer ptr = PluginStorageLib.associatedStorageLookup( -// key, hex"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff" -// ); -// TestStruct storage val = _castPtrToStruct(ptr); - -// vm.record(); -// val.a = 0xdeadbeef; -// val.b = 123; -// (, bytes32[] memory accountWrites) = vm.accesses(address(this)); - -// assertEq(accountWrites.length, 2); -// bytes32 expectedKey = keccak256( -// abi.encodePacked( -// uint256(uint160(account1)), -// uint256(0), -// hex"00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff" -// ) -// ); -// assertEq(accountWrites[0], expectedKey); -// assertEq(vm.load(address(this), expectedKey), bytes32(uint256(0xdeadbeef))); -// assertEq(accountWrites[1], bytes32(uint256(expectedKey) + 1)); -// assertEq(vm.load(address(this), bytes32(uint256(expectedKey) + 1)), bytes32(uint256(123))); -// } - -// function testFuzz_storagePointer( -// address account, -// uint256 batchIndex, -// bytes32 inputKey, -// uint256[FUZZ_ARR_SIZE] calldata values -// ) public { -// bytes memory key = PluginStorageLib.allocateAssociatedStorageKey(account, batchIndex, 1); -// uint256[FUZZ_ARR_SIZE] storage val = -// _castPtrToArray(PluginStorageLib.associatedStorageLookup(key, inputKey)); -// // Write values to storage -// vm.record(); -// for (uint256 i = 0; i < FUZZ_ARR_SIZE; i++) { -// val[i] = values[i]; -// } -// // Assert the writes took place in the right location, and the correct value is stored there -// (, bytes32[] memory accountWrites) = vm.accesses(address(this)); -// assertEq(accountWrites.length, FUZZ_ARR_SIZE); -// for (uint256 i = 0; i < FUZZ_ARR_SIZE; i++) { -// bytes32 expectedKey = bytes32( -// uint256(keccak256(abi.encodePacked(uint256(uint160(account)), uint256(batchIndex), inputKey))) + -// i -// ); -// assertEq(accountWrites[i], expectedKey); -// assertEq(vm.load(address(this), expectedKey), bytes32(uint256(values[i]))); -// } -// } - -// function _castPtrToArray(StoragePointer ptr) internal pure returns (uint256[FUZZ_ARR_SIZE] storage val) { -// assembly ("memory-safe") { -// val.slot := ptr -// } -// } - -// function _castPtrToStruct(StoragePointer ptr) internal pure returns (TestStruct storage val) { -// assembly ("memory-safe") { -// val.slot := ptr -// } -// } -// } diff --git a/test/mocks/MockERC20.sol b/test/mocks/MockERC20.sol deleted file mode 100644 index d87a9234..00000000 --- a/test/mocks/MockERC20.sol +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; - -import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - -contract MockERC20 is ERC20 { - constructor(string memory name, string memory symbol) ERC20(name, symbol) {} - - function mint(address account, uint256 amount) external { - _mint(account, amount); - } -} diff --git a/test/samples/plugins/ModularSessionKeyPlugin.t.sol b/test/samples/plugins/ModularSessionKeyPlugin.t.sol deleted file mode 100644 index 92ee87f6..00000000 --- a/test/samples/plugins/ModularSessionKeyPlugin.t.sol +++ /dev/null @@ -1,375 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.19; - -// import {Test} from "forge-std/Test.sol"; - -// import {EntryPoint} from "@eth-infinitism/account-abstraction/core/EntryPoint.sol"; -// import {PackedUserOperation} from "@eth-infinitism/account-abstraction/interfaces/PackedUserOperation.sol"; -// import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; - -// import {SingleOwnerPlugin} from "../../../src/plugins/owner/SingleOwnerPlugin.sol"; -// import {ISingleOwnerPlugin} from "../../../src/plugins/owner/ISingleOwnerPlugin.sol"; -// import {ModularSessionKeyPlugin} from "../../../src/samples/plugins/ModularSessionKeyPlugin.sol"; -// import {IModularSessionKeyPlugin} from "../../../src/samples/plugins/interfaces/ISessionKeyPlugin.sol"; -// import {TokenSessionKeyPlugin} from "../../../src/samples/plugins/TokenSessionKeyPlugin.sol"; -// import {ITokenSessionKeyPlugin} from "../../../src/samples/plugins/interfaces/ITokenSessionKeyPlugin.sol"; - -// import {UpgradeableModularAccount} from "../../../src/account/UpgradeableModularAccount.sol"; -// import {MSCAFactoryFixture} from "../../mocks/MSCAFactoryFixture.sol"; -// import {FunctionReference, FunctionReferenceLib} from "../../../src/helpers/FunctionReferenceLib.sol"; -// import {IPluginManager} from "../../../src/interfaces/IPluginManager.sol"; -// import {MockERC20} from "../../mocks/MockERC20.sol"; - -// contract ModularSessionKeyPluginTest is Test { -// using ECDSA for bytes32; - -// SingleOwnerPlugin public ownerPlugin; -// ModularSessionKeyPlugin public modularSessionKeyPlugin; -// TokenSessionKeyPlugin public tokenSessionKeyPlugin; -// EntryPoint public entryPoint; -// MSCAFactoryFixture public factory; -// UpgradeableModularAccount public account; - -// MockERC20 public mockERC20impl; -// MockERC20 public mockERC20; -// address public mockEmptyERC20Addr; - -// address public owner; -// uint256 public ownerKey; - -// address public maliciousOwner; - -// address public tempOwner; -// uint256 public tempOwnerKey; - -// address public target; - -// address payable public beneficiary; - -// uint256 public constant CALL_GAS_LIMIT = 150000; -// uint256 public constant VERIFICATION_GAS_LIMIT = 3600000; - -// bytes4 public constant TRANSFERFROM_SESSIONKEY_SELECTOR = -// ITokenSessionKeyPlugin.transferFromSessionKey.selector; - -// // Event declarations (needed for vm.expectEmit) -// event UserOperationRevertReason( -// bytes32 indexed userOpHash, address indexed sender, uint256 nonce, bytes revertReason -// ); -// event SessionKeyAdded( -// address indexed account, address indexed sessionKey, bytes4 allowedSelector, uint48 _after, uint48 -// _until -// ); -// event SessionKeyRemoved(address indexed account, address indexed sessionKey, bytes4 allowedSelector); -// event SessionKeysAdded( -// address indexed account, address[] sessionKeys, bytes4[] allowedSelectors, uint48[] afters, uint48[] -// untils -// ); -// event SessionKeysRemoved(address indexed account, address[] sessionKeys, bytes4[] allowedSelectors); -// event PluginUninstalled(address indexed plugin, bool indexed onUninstallSuccess); - -// function setUp() public { -// ownerPlugin = new SingleOwnerPlugin(); -// modularSessionKeyPlugin = new ModularSessionKeyPlugin(); -// tokenSessionKeyPlugin = new TokenSessionKeyPlugin(); - -// entryPoint = new EntryPoint(); -// factory = new MSCAFactoryFixture(entryPoint, ownerPlugin); -// mockERC20impl = new MockERC20("Mock", "MCK"); - -// // Etching MockERC20 code into hardcoded address at TokenSessionKeyPlugin -// mockEmptyERC20Addr = tokenSessionKeyPlugin.TARGET_ERC20_CONTRACT(); -// bytes memory code = address(mockERC20impl).code; -// vm.etch(mockEmptyERC20Addr, code); -// mockERC20 = MockERC20(mockEmptyERC20Addr); - -// (owner, ownerKey) = makeAddrAndKey("owner"); -// (maliciousOwner,) = makeAddrAndKey("maliciousOwner"); -// (tempOwner, tempOwnerKey) = makeAddrAndKey("tempOwner"); -// target = makeAddr("target"); - -// beneficiary = payable(makeAddr("beneficiary")); -// vm.deal(beneficiary, 1 wei); -// vm.deal(owner, 10 ether); - -// // Here, SingleOwnerPlugin already installed in factory -// account = factory.createAccount(owner, 0); - -// // Mint Mock ERC20 Tokens to account -// mockERC20.mint(address(account), 1 ether); -// // Fund the account with some ether -// vm.deal(address(account), 1 ether); - -// vm.startPrank(owner); -// FunctionReference[] memory modularSessionDependency = new FunctionReference[](1); -// modularSessionDependency[0] = FunctionReferenceLib.pack( -// address(ownerPlugin), uint8(ISingleOwnerPlugin.FunctionId.VALIDATION_OWNER_OR_SELF) -// ); - -// bytes32 modularSessionKeyManifestHash = keccak256(abi.encode(modularSessionKeyPlugin.pluginManifest())); - -// address[] memory tempOwners = new address[](1); -// tempOwners[0] = address(tempOwner); - -// bytes4[] memory allowedSelectors = new bytes4[](1); -// allowedSelectors[0] = TRANSFERFROM_SESSIONKEY_SELECTOR; - -// uint48[] memory afters = new uint48[](1); -// afters[0] = 0; - -// uint48[] memory untils = new uint48[](1); -// untils[0] = 2; - -// bytes memory data = abi.encode(tempOwners, allowedSelectors, afters, untils); - -// account.installPlugin({ -// plugin: address(modularSessionKeyPlugin), -// manifestHash: modularSessionKeyManifestHash, -// pluginInstallData: data, -// dependencies: modularSessionDependency -// }); - -// FunctionReference[] memory tokenSessionDependency = new FunctionReference[](1); -// tokenSessionDependency[0] = FunctionReferenceLib.pack( -// address(modularSessionKeyPlugin), -// uint8(IModularSessionKeyPlugin.FunctionId.VALIDATION_TEMPORARY_OWNER) -// ); -// bytes32 tokenSessionKeyManifestHash = keccak256(abi.encode(tokenSessionKeyPlugin.pluginManifest())); - -// account.installPlugin({ -// plugin: address(tokenSessionKeyPlugin), -// manifestHash: tokenSessionKeyManifestHash, -// pluginInstallData: "", -// dependencies: tokenSessionDependency -// }); -// vm.stopPrank(); - -// vm.startPrank(address(account)); -// mockERC20.approve(address(account), 1 ether); - -// (uint48 _after, uint48 _until) = modularSessionKeyPlugin.getSessionDuration( -// address(account), tempOwner, TRANSFERFROM_SESSIONKEY_SELECTOR -// ); - -// assertEq(_after, 0); -// assertEq(_until, 2); -// vm.stopPrank(); -// } - -// function test_sessionKey_batch() public { -// address tempOwner2 = makeAddr("tempOwner2"); -// address tempOwner3 = makeAddr("tempOwner3"); - -// address[] memory tempOwners = new address[](2); -// tempOwners[0] = tempOwner2; -// tempOwners[1] = tempOwner3; - -// bytes4[] memory allowedSelectors = new bytes4[](2); -// allowedSelectors[0] = TRANSFERFROM_SESSIONKEY_SELECTOR; -// allowedSelectors[1] = TRANSFERFROM_SESSIONKEY_SELECTOR; - -// uint48[] memory afters = new uint48[](2); -// afters[0] = 0; -// afters[1] = 0; - -// uint48[] memory untils = new uint48[](2); -// untils[0] = 2; -// untils[1] = 2; - -// vm.expectEmit(true, true, true, true); -// emit SessionKeysAdded(address(account), tempOwners, allowedSelectors, afters, untils); -// vm.prank(address(account)); -// modularSessionKeyPlugin.addSessionKeyBatch(tempOwners, allowedSelectors, afters, untils); - -// vm.prank(tempOwner3); -// TokenSessionKeyPlugin(address(account)).transferFromSessionKey( -// address(mockERC20), address(account), target, 1 ether -// ); - -// assertEq(mockERC20.balanceOf(address(account)), 0); -// assertEq(mockERC20.balanceOf(target), 1 ether); - -// vm.expectEmit(true, true, true, true); -// emit SessionKeysRemoved(address(account), tempOwners, allowedSelectors); -// vm.prank(address(account)); -// modularSessionKeyPlugin.removeSessionKeyBatch(tempOwners, allowedSelectors); -// } - -// function test_sessionKey_userOp() public { -// PackedUserOperation[] memory userOps = new PackedUserOperation[](1); - -// (, PackedUserOperation memory userOp) = _constructUserOp(address(mockERC20), address(account), target, 1 -// ether); -// userOps[0] = userOp; - -// entryPoint.handleOps(userOps, beneficiary); - -// assertEq(mockERC20.balanceOf(address(account)), 0); -// assertEq(mockERC20.balanceOf(target), 1 ether); -// } - -// function test_sessionKey_runtime() public { -// vm.prank(address(tempOwner)); -// TokenSessionKeyPlugin(address(account)).transferFromSessionKey( -// address(mockERC20), address(account), target, 1 ether -// ); - -// assertEq(mockERC20.balanceOf(address(account)), 0); -// assertEq(mockERC20.balanceOf(target), 1 ether); -// } - -// function test_sessionKey_removeTempOwner() public { -// vm.startPrank(address(account)); - -// vm.expectEmit(true, true, true, true); -// emit SessionKeyRemoved(address(account), tempOwner, TRANSFERFROM_SESSIONKEY_SELECTOR); -// modularSessionKeyPlugin.removeSessionKey(tempOwner, TRANSFERFROM_SESSIONKEY_SELECTOR); - -// vm.stopPrank(); - -// (uint48 _after, uint48 _until) = modularSessionKeyPlugin.getSessionDuration( -// address(account), tempOwner, TRANSFERFROM_SESSIONKEY_SELECTOR -// ); -// assertEq(_after, 0); -// assertEq(_until, 0); - -// // Check if tempOwner can still send user operations -// vm.startPrank(address(tempOwner)); - -// bytes memory revertReason = abi.encodeWithSelector(IModularSessionKeyPlugin.NotAuthorized.selector); -// vm.expectRevert( -// abi.encodeWithSelector( -// UpgradeableModularAccount.RuntimeValidationFunctionReverted.selector, -// address(modularSessionKeyPlugin), -// IModularSessionKeyPlugin.FunctionId.VALIDATION_TEMPORARY_OWNER, -// revertReason -// ) -// ); -// TokenSessionKeyPlugin(address(account)).transferFromSessionKey( -// address(mockERC20), address(account), target, 1 ether -// ); -// } - -// function test_sessionKey_invalidContractFails() public { -// address wrongERC20Contract = makeAddr("wrongERC20Contract"); -// (bytes32 userOpHash, PackedUserOperation memory userOp) = -// _constructUserOp(address(wrongERC20Contract), address(account), target, 1 ether); - -// PackedUserOperation[] memory userOps = new PackedUserOperation[](1); -// userOps[0] = userOp; - -// bytes memory revertCallData = abi.encodeWithSelector( -// tokenSessionKeyPlugin.TRANSFERFROM_SELECTOR(), address(account), target, 1 ether -// ); -// bytes memory revertReason = abi.encodeWithSelector( -// UpgradeableModularAccount.ExecFromPluginExternalNotPermitted.selector, -// address(tokenSessionKeyPlugin), -// address(wrongERC20Contract), -// 0, -// revertCallData -// ); -// vm.expectEmit(true, true, true, true); -// emit UserOperationRevertReason(userOpHash, address(account), 0, revertReason); - -// entryPoint.handleOps(userOps, beneficiary); -// } - -// function test_sessionKey_unregisteredTempOwnerFails() public { -// vm.prank(address(maliciousOwner)); -// bytes memory revertReason = abi.encodeWithSelector(IModularSessionKeyPlugin.NotAuthorized.selector); - -// vm.expectRevert( -// abi.encodeWithSelector( -// UpgradeableModularAccount.RuntimeValidationFunctionReverted.selector, -// address(modularSessionKeyPlugin), -// IModularSessionKeyPlugin.FunctionId.VALIDATION_TEMPORARY_OWNER, -// revertReason -// ) -// ); -// TokenSessionKeyPlugin(address(account)).transferFromSessionKey( -// address(mockERC20), address(account), target, 1 ether -// ); -// } - -// function test_sessionKey_invalidSessionDurationFails() public { -// // Move block.timestamp to 12345 -// vm.warp(12345); - -// vm.startPrank(address(tempOwner)); - -// bytes memory revertReason = -// abi.encodeWithSelector(IModularSessionKeyPlugin.WrongTimeRangeForSession.selector); - -// vm.expectRevert( -// abi.encodeWithSelector( -// UpgradeableModularAccount.RuntimeValidationFunctionReverted.selector, -// address(modularSessionKeyPlugin), -// IModularSessionKeyPlugin.FunctionId.VALIDATION_TEMPORARY_OWNER, -// revertReason -// ) -// ); -// TokenSessionKeyPlugin(address(account)).transferFromSessionKey( -// address(mockERC20), address(account), target, 1 ether -// ); -// } - -// function test_sessionKey_uninstallModularSessionKeyPlugin() public { -// address[] memory tempOwners = new address[](1); -// tempOwners[0] = address(tempOwner); - -// bytes4[] memory allowedSelectors = new bytes4[](1); -// allowedSelectors[0] = TRANSFERFROM_SESSIONKEY_SELECTOR; - -// vm.startPrank(owner); - -// vm.expectEmit(true, true, true, true); - -// emit PluginUninstalled(address(tokenSessionKeyPlugin), true); -// account.uninstallPlugin({ -// plugin: address(tokenSessionKeyPlugin), -// config: bytes(""), -// pluginUninstallData: "" -// }); - -// vm.expectEmit(true, true, true, true); -// emit PluginUninstalled(address(modularSessionKeyPlugin), true); -// account.uninstallPlugin({ -// plugin: address(modularSessionKeyPlugin), -// config: bytes(""), -// pluginUninstallData: "" -// }); - -// vm.stopPrank(); -// } - -// // Internal Function -// function _constructUserOp(address targetContract, address from, address to, uint256 amount) -// internal -// view -// returns (bytes32, PackedUserOperation memory) -// { -// bytes memory userOpCallData = -// abi.encodeCall(TokenSessionKeyPlugin.transferFromSessionKey, (targetContract, from, to, amount)); - -// PackedUserOperation memory userOp = PackedUserOperation({ -// sender: address(account), -// nonce: 0, -// initCode: "", -// callData: userOpCallData, -// callGasLimit: CALL_GAS_LIMIT, -// verificationGasLimit: VERIFICATION_GAS_LIMIT, -// preVerificationGas: 0, -// maxFeePerGas: 2, -// maxPriorityFeePerGas: 1, -// paymasterAndData: "", -// signature: "" -// }); - -// // Generate signature -// bytes32 userOpHash = entryPoint.getUserOpHash(userOp); -// (uint8 v, bytes32 r, bytes32 s) = vm.sign(tempOwnerKey, userOpHash.toEthSignedMessageHash()); -// userOp.signature = abi.encodePacked(r, s, v); - -// return (userOpHash, userOp); -// } -// }