Skip to content

Commit

Permalink
Merge pull request #4 from alfheimrShiven/account-social-recovery
Browse files Browse the repository at this point in the history
Account Lock request creation, signature evaluation and execution
  • Loading branch information
alfheimrShiven authored Nov 8, 2023
2 parents a8ca25f + 9c15308 commit 493001e
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 158 deletions.
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

0 comments on commit 493001e

Please sign in to comment.