Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Account Lock request creation, signature evaluation and execution #4

Merged
merged 3 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions contracts/prebuilts/account/non-upgradeable/Account.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import "../utils/BaseAccountFactory.sol";

import { Guardian } from "../utils/Guardian.sol";
import { AccountLock } from "../utils/AccountLock.sol";
import { AccountGuardian } from "../utils/AccountGuardian.sol";

// $$\ $$\ $$\ $$\ $$\
// $$ | $$ | \__| $$ | $$ |
Expand All @@ -38,16 +37,17 @@ contract Account is AccountCore, ContractMetadata, ERC1271, ERC721Holder, ERC115
using EnumerableSet for EnumerableSet.AddressSet;
bool public paused;
Guardian guardian;
AccountLock accountLock;
AccountGuardian accountGuardian;
address accountLock;

error NotAuthorizedToLock(address locker);

/*///////////////////////////////////////////////////////////////
Constructor, Initializer, Modifiers
//////////////////////////////////////////////////////////////*/

constructor(IEntryPoint _entrypoint, address _factory, Guardian _guardian) AccountCore(_entrypoint, _factory) {
constructor(IEntryPoint _entrypoint, address _factory, address _accountLock) AccountCore(_entrypoint, _factory) {
paused = false;
guardian = _guardian;
accountLock = _accountLock;
}

/// @notice Checks whether the caller is the EntryPoint contract or the admin.
Expand All @@ -56,6 +56,14 @@ contract Account is AccountCore, ContractMetadata, ERC1271, ERC721Holder, ERC115
_;
}

/// @notice The account can be paused only by the AccountLock contract
modifier onlyAccountLock(address locker) {
if (locker != accountLock) {
revert NotAuthorizedToLock(locker);
}
_;
}

/// @notice Will check if the Account transactions has been paused by the guardians. If paused, it will not allow the `execute(..)` or the `executeBatch(..)` function to run.
modifier whenNotPaused() {
require(!paused, "Smart account has been paused.");
Expand Down Expand Up @@ -129,17 +137,10 @@ contract Account is AccountCore, ContractMetadata, ERC1271, ERC721Holder, ERC115
}
}

function setPaused(bool pauseStatus) external {
function setPaused(bool pauseStatus) external onlyAccountLock(msg.sender) {
paused = pauseStatus;
}

function deployAccountGuardian(address accountClone, AccountLock _accountLock) public override {
accountLock = _accountLock;

accountGuardian = new AccountGuardian(guardian, accountLock, accountClone);
guardian.linkAccountToAccountGuardian(accountClone, address(accountGuardian));
}

/*///////////////////////////////////////////////////////////////
Internal functions
//////////////////////////////////////////////////////////////*/
Expand Down
13 changes: 3 additions & 10 deletions contracts/prebuilts/account/non-upgradeable/AccountFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,13 @@ import { Guardian } from "../utils/Guardian.sol";
// \____/ \__| \__|\__|\__| \_______| \_____\____/ \_______|\_______/

contract AccountFactory is BaseAccountFactory, ContractMetadata, PermissionsEnumerable {
Guardian guardian = new Guardian();

/*///////////////////////////////////////////////////////////////
Constructor
//////////////////////////////////////////////////////////////*/

constructor(
IEntryPoint _entrypoint
) BaseAccountFactory(address(new Account(_entrypoint, address(this), guardian)), address(_entrypoint), guardian) {
) BaseAccountFactory(address(new Account(_entrypoint, address(this), address(accountLock))), address(_entrypoint)) {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
}

Expand All @@ -44,13 +42,8 @@ contract AccountFactory is BaseAccountFactory, ContractMetadata, PermissionsEnum
//////////////////////////////////////////////////////////////*/

/// @dev Called in `createAccount`. Initializes the account contract created in `createAccount`.
function _initializeAccount(
address _account,
address _admin,
bytes calldata _data,
AccountLock _accountLock
) internal override {
Account(payable(_account)).initialize(_admin, _data, _account, _accountLock);
function _initializeAccount(address _account, address _admin, bytes calldata _data) internal override {
Account(payable(_account)).initialize(_admin, _data);
}

/// @dev Returns whether contract metadata can be set in the given execution context.
Expand Down
9 changes: 2 additions & 7 deletions contracts/prebuilts/account/utils/AccountCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,12 @@ contract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, Acc
}

/// @notice Initializes the smart contract wallet.
function initialize(
address _defaultAdmin,
bytes calldata,
address _accountClone,
AccountLock _accountLock
) public virtual initializer {
function initialize(address _defaultAdmin, bytes calldata) public virtual initializer {
// This is passed as data in the `_registerOnFactory()` call in `AccountExtension` / `Account`.
AccountCoreStorage.data().firstAdmin = _defaultAdmin;
_setAdmin(_defaultAdmin, true);

deployAccountGuardian(_accountClone, _accountLock);
// deployAccountGuardian(_accountClone, _accountLock);
}

/*///////////////////////////////////////////////////////////////
Expand Down
9 changes: 5 additions & 4 deletions contracts/prebuilts/account/utils/AccountLock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
pragma solidity ^0.8.12;

import { IAccountLock } from "../interface/IAccountLock.sol";
import { Account } from "contracts/prebuilts/account/non-upgradeable/Account.sol";
import { Guardian } from "contracts/prebuilts/account/utils/Guardian.sol";
import { AccountGuardian } from "contracts/prebuilts/account/utils/AccountGuardian.sol";
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
Expand Down Expand Up @@ -103,7 +102,7 @@ contract AccountLock is IAccountLock, AutomationCompatibleInterface {
revert ActiveLockRequestFound();
}

bytes32 lockRequestHash = keccak256(abi.encodePacked("_lockRequest(address account)", account));
bytes32 lockRequestHash = keccak256(abi.encodePacked("_lockAccount(address account)", account));

accountToLockRequest[account] = lockRequestHash;
lockRequestToCreationTime[lockRequestHash] = block.timestamp;
Expand Down Expand Up @@ -229,13 +228,15 @@ contract AccountLock is IAccountLock, AutomationCompatibleInterface {
* @param account The account to be locked
*/
function _lockAccount(address payable account) internal {
Account(account).setPaused(true);
(bool success, ) = account.call(abi.encodeWithSignature("setPaused(bool)", true));

require(success, "Locking account failed");
}

function _verifyLockRequestSignature(
bytes32 lockRequest,
bytes memory guardianSignature
) internal returns (address) {
) internal pure returns (address) {
// verify
address recoveredGuardian = ECDSA.recover(lockRequest, guardianSignature);

Expand Down
19 changes: 10 additions & 9 deletions contracts/prebuilts/account/utils/BaseAccountFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ abstract contract BaseAccountFactory is IAccountFactory, Multicall {

address public immutable accountImplementation;
address public immutable entrypoint;
Guardian public guardian;
AccountLock public accountLock;

EnumerableSet.AddressSet private allAccounts;
Expand All @@ -44,10 +45,11 @@ abstract contract BaseAccountFactory is IAccountFactory, Multicall {
Constructor
//////////////////////////////////////////////////////////////*/

constructor(address _accountImpl, address _entrypoint, Guardian _guardian) {
constructor(address _accountImpl, address _entrypoint) {
accountImplementation = _accountImpl;
entrypoint = _entrypoint;
accountLock = new AccountLock(_guardian);
guardian = new Guardian();
accountLock = new AccountLock(guardian);
}

/*///////////////////////////////////////////////////////////////
Expand All @@ -70,8 +72,12 @@ abstract contract BaseAccountFactory is IAccountFactory, Multicall {
require(allAccounts.add(account), "AccountFactory: account already registered");
}

_initializeAccount(account, _admin, _data, accountLock);
_initializeAccount(account, _admin, _data);
emit AccountCreated(account, _admin);

AccountGuardian accountGuardian = new AccountGuardian(guardian, accountLock, account);
guardian.linkAccountToAccountGuardian(account, address(accountGuardian));

return account;
}

Expand Down Expand Up @@ -157,10 +163,5 @@ abstract contract BaseAccountFactory is IAccountFactory, Multicall {
}

/// @dev Called in `createAccount`. Initializes the account contract created in `createAccount`.
function _initializeAccount(
address _account,
address _admin,
bytes calldata _data,
AccountLock _accountLock
) internal virtual;
function _initializeAccount(address _account, address _admin, bytes calldata _data) internal virtual;
}
Loading