Skip to content
This repository has been archived by the owner on Jan 5, 2024. It is now read-only.

Commit

Permalink
Smart Wallet Changes (#899)
Browse files Browse the repository at this point in the history
* add Krishang's table

* add tables to how it works

* add signers page

* add info on factory contracts & initializing accounts with an personal wallet key

* add account, key & wallet terms

* remove unused file
  • Loading branch information
ciaranightingale authored Sep 20, 2023
1 parent 6e1d2b0 commit 15caf06
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ thirdweb’s smart wallets have the following features by default:

Choose the right smart wallet setup for your app. thirdweb offers the following three different kinds of smart wallets:

| | [`Account`](/solidity/base-contracts/account) setup | [`DynamicAccount`](/solidity/base-contracts/dynamic-account) setup | [`ManagedAccount`](/solidity/base-contracts/managed-account) setup |
| | [`Simple`](/solidity/base-contracts/account) | [`Dynamic`](/solidity/base-contracts/dynamic-account) | [`Managed`](/solidity/base-contracts/managed-account) |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Upgradeability** | Non-upgradeable | Account upgrades controlled locally by account admin. | Account upgrades controlled centrally by account factory admin. |
| **Upgradeability** | Non-upgradeable | Account upgrades controlled locally by account admin. | Account upgrades controlled centrally by the parent account factory admin. |
| **User persona** | Developer wants to issue simple smart wallets to their users. They do not anticipate that users wallets will need any feature upgrades. | Developer wants to issue smart wallets to their users. They do anticipate feature upgrades to user wallets but do not want to push upgrades to user wallets without consent. | Developer wants to issue smart wallets to their users. They do anticipate feature upgrades to user wallets, and want to push upgrades to user wallets for seamless/invisible UX for upgrades. |

## Simple smart wallets
Expand Down
77 changes: 77 additions & 0 deletions docs/onboarding/23 Smart Wallet/1 How it Works.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,85 @@ To learn more about how smart wallets work, read our [smart contract deep dive](

![Smart Wallet Flow](/assets/smart-wallet-architecture.png)

## Account Factories

In order to issue smart wallet account contracts for users, an account factory contract must be deployed.
A factory contract is a contract which clones an implementation contract which defines the functions and logic on the clone.

To create accounts with the factory contract, the `createAccount` function is called. This function calls `_initializeAccount`
which initializes the account and sets the default admin on the account.

## One Account Per Personal Wallet

The thirdweb Account Factories are designed so that only one account can be created per personal wallet key.
This means that any one personal wallet can only be a default admin on one account per factory.

This is because, when the account contract is cloned by the factory, the account is craeted deterministically
via the `cloneDeterministic` function. This function takes a `salt` as a parameter to predict the deployment address. The `salt` is calculated using the
default admin address. Since the deployment address will be the same if the default admin is the same, if an account
already exists at that address, the transaction will revert.

```solidity
/// @notice Deploys a new Account for admin.
function createAccount(address _admin, bytes calldata _data) external virtual override returns (address) {
address impl = accountImplementation;
bytes32 salt = _generateSalt(_admin, _data);
address account = Clones.predictDeterministicAddress(impl, salt);
if (account.code.length > 0) {
return account;
}
account = Clones.cloneDeterministic(impl, salt);
if (msg.sender != entrypoint) {
require(allAccounts.add(account), "AccountFactory: account already registered");
}
_initializeAccount(account, _admin, _data);
emit AccountCreated(account, _admin);
return account;
}
```

## Types of Account and Account Factory

| | [`Simple`](https://thirdweb.com/thirdweb.eth/AccountFactory) | [`Dynamic`](https://thirdweb.com/thirdweb.eth/DynamicAccountFactory) | [`Managed`](https://thirdweb.com/thirdweb.eth/ManagedAccountFactory) |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Upgradeability** | Non-upgradeable | Account upgrades controlled locally by account admin. | Account upgrades controlled centrally by the parent account factory admin. |
| **Expected Usage** | Developer wants to issue simple smart wallets to their users. They do not anticipate that users wallets will need any feature upgrades. | Developer wants to issue smart wallets to their users. They do anticipate feature upgrades to user wallets but do not want to push upgrades to user wallets without consent. | Developer wants to issue smart wallets to their users. They do anticipate feature upgrades to user wallets, and want to push upgrades to user wallets for seamless/invisible UX for upgrades. |

### Account Type Feature Comparison

| | Simple | Dynamic | Managed |
| --------------------------------------------------- | -------------------------- | ---------------------------------------- | ---------------------------------------------- |
| Contracts | `AccountFactory` `Account` | `DynamicAccountFactory` `DynamicAccount` | `ManagedAccountFactory` `ManagedAccount` |
| ERC-4337 Compatible ||||
| Can hold native ERC-20, ERC-721 and ERC-1155 Tokens ||||
| Multi-signer ||||
| Execute transactions in Batches ||||
| Is the Account Upgradeable ||||
| Who controls upgrades (?) | n/a | Admin of the account. | Admin of the account’s parent account factory. |

## Terminology

### Personal Wallet/Key

This is the default admin on an account or the "key" to an account. It can be any wallet and is used to initialize the account.
Any one wallet can only be the "key" to one account per factory contract.

This wallet is the primary way to access and interact with the account.

### Account

In the context of smart wallets, the account is the ERC-4337 compatible smart contract which holds all of the assets.

### Smart Wallet

The smart wallet is the combination of your personal wallet "key" plus the account smart contract with all of it's assets.

### UserOperations

This is the data structure for the transaction that the user wants to perform. It contains the following fields:
Expand Down
81 changes: 81 additions & 0 deletions docs/onboarding/23 Smart Wallet/4 Permissions and Signers.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
slug: /smart-wallet/permissions
title: Permissions & Signers
---

All of the account contracts [[Simple](https://thirdweb.com/thirdweb.eth/AccountFactory), [Dynamic](https://thirdweb.com/thirdweb.eth/DynamicAccountFactory) and [Managed](https://thirdweb.com/thirdweb.eth/ManagedAccountFactory)] share the same permission model. In this section, we'll describe this permission model in detail.

## Account Permissions

An account recognizes only two types of actors:

### [1] Admins

Admins have **unrestricted access** to the account; call any functions on the contract, use the contract without going through the ERC-4337 infrastructure (bundlers, EntryPoint, etc.), withdraw the account's native token balance, and so on.

### Assigning Admin Permissions

Existing admins on the account can add new admins, remove existing admins or renounce their own admin status.

This is done by simply calling the `setAdmin` function:

```solidity
/// @notice Adds / removes an account as an admin.
function setAdmin(address account, bool isAdmin) external;
```

### [2] Non-admins with permissions (Signers)

Signers must go through ERC-4337 infrastructure (bundlers, EntryPoint, etc.) to use an account to execute transactions. Signers can use an account under certain restrictions.

### Assigning Signer Permissions

Each individual signer has their own permissions to use the account. Admins set the permissions for signers.

A signers on an account are managed by the account admin and signers can be restricted to:

- Only call specific wallets with the account.
- Transfer a specific native token amount out of account.
- Only use the account in a specific time window.

These restrictions are set in the `SignerPermissionsRequest` struct.
To set the permissions for a given signer, the `setPermissionsForSigner` function is called.

```Solidity
struct SignerPermissionRequest {
address signer;
address[] approvedTargets;
uint256 nativeTokenLimitPerTransaction;
uint128 permissionStartTimestamp;
uint128 permissionEndTimestamp;
uint128 reqValidityStartTimestamp;
uint128 reqValidityEndTimestamp;
bytes32 uid;
}
/// @notice Sets the permissions for a given signer.
function setPermissionsForSigner(SignerPermissionRequest calldata req, bytes calldata signature) external;
```

The function uses [EIP-712](https://eips.ethereum.org/EIPS/eip-712?ref=portal.thirdweb.com) typed data signatures. That means an admin must fill and sign the `SignerPermissionRequest` payload and pass the payload and produced signature to the function.
This is so that a bundler can be used to send the transaction while still being able to perform a permissions check.

#### Security note:

A signer cannot have 'catch-all' permissions where they can call any target contract, or transfer any amount of native tokens. This is an important security consideration, since it is common (unfortunately) for private keys to get lost or leaked. In this way, the account encourages usage through purposeful signer keys.

Even though an account may have 'recovery', having your admin keys leaked means whoever has your admin keys has unrestricted control over the smart wallet.

## Account Factory Permissions

For all three types of account factory (simple, dynamic and managed), the following role exists:

- `DEFAULT_ADMIN_ROLE`: Only a holder of this role is eligible to set the contract metadata of the account factory (i.e. name, description, image and any other metadata to associate with the contract).

**For Simple & Dynamic accounts, there is no permission control on the factory contract.**

For Managed Account Factories, an extra role exists:

- `EXTENSION_ROLE`: Only a holder of this role can perform upgrades to the children account contracts created by the managed account factory.

## SDK Usage

1 comment on commit 15caf06

@vercel
Copy link

@vercel vercel bot commented on 15caf06 Sep 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.