Skip to content

Commit

Permalink
Contract Internals section (#28)
Browse files Browse the repository at this point in the history
* Internals section

* Add v2 wallet configuration

* Spell fixes
  • Loading branch information
Agusx1211 authored Apr 10, 2024
1 parent b85ff9b commit 4dbe1af
Show file tree
Hide file tree
Showing 15 changed files with 263 additions and 89 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Callout } from "vocs/components";

# Contract Deployment

Sequence contract wallets are fully deterministic; a wallet will map to the same address on any network that is EVM compatible.

This means that when a wallet is created, its address can be derived in advance, and it will be the same on networks like Ethereum, Arbitrum, Polygon, and others.

<Callout type="warning">
**Limitations**<br />
Sequence wallets **may not** receive the same address on chains that aren't 100% EVM compatible.

**Double-check your addresses** before sending any assets to them.
</Callout>

To achieve this, Sequence uses variations of [Nick's method](https://weka.medium.com/how-to-send-ether-to-11-440-people-187e332566b7), which allows for the deployment of the same contract on multiple chains in a fully trustless way.

Nick's method is used to deploy a "deployer" contract, which is then used to deploy the core Sequence contracts.

These contracts are:

#### Factory Contract

Creates new Sequence wallets, with an initial configuration.

#### MainModule (v1 and v2)

The main module implements the core logic of the wallet, with a fixed configuration.

#### MainModuleUpgradable (v1 and v2)

Similar to the MainModule, but with the ability to upgrade the configuration of the wallet.

#### Auxiliary Contracts

Both v1 and v2 have auxiliary contracts that are used by the SDK to interact with the wallet; these contracts are not critical for the wallet to function, but they are required for the SDK to work.

See the v1 and v2 documentation for more information on the contracts.

<Callout type="info">
Notice<br/>A complete script for deployment can be found in the [Sequence Live Contracts repository](https://github.com/0xsequence/live-contracts).
</Callout>

## Detailed Deployment Steps

- v1: [Deploy v1 Contracts](/solutions/technical-references/internals/v1/01-deploy)
- v2: [Deploy v2 Contracts](/solutions/technical-references/internals/v2/01-deploy)
Original file line number Diff line number Diff line change
@@ -1,85 +1,14 @@
import { Callout } from "vocs/components";

# Universal Deployer
# Deploy Process V1

The Sequence contract wallets use [Nick's method](https://weka.medium.com/how-to-send-ether-to-11-440-people-187e332566b7) to deploy the contracts that compose the smart contract wallet.
This method has been chosen because it allows each wallet to take the same address on multiple chains, making it easier to use and less prone to mistakes.

<Callout type="danger">
Limitations <br />
Sequence wallets **may not** receive the same address on all EVM compatible chains.
</Callout>

Networks that implement only a subset of the EVM opcodes, or alternative virtual
machines, will result in a different address for each chain.

**Double-check your addresses** before sending any assets to them.

<Callout type="info">
Notice <br />A complete script for deployment can be found in the [Sequence
Live Contracts repository](https://github.com/0xsequence/live-contracts).
</Callout>

## Deploy Process V2

The following steps are required to deploy the [Sequence Wallet Context](/solutions/technical-references/wallet-contracts/02-universal-deployer#3---deploy-wallet-context) on a new network.

<Callout type="info">
Notice <br />
For most popular networks this process **is not** required; due to the wallet contracts
being already deployed.
To see if a configuration already exists for a given chain go to [Networks](/solutions/technical-references/chain-support).

</Callout>

### 1 - Deploy Singleton Factory

The Singleton Factory is a contract that allows the deployment of a single contract instance per address. Unlike the
[Universal Deployer](#universal-deployer), the Singleton Factory requires a salt to manage deployment instances. More information about the
Singleton Factory can be found in the [EIP-2470 specification](https://eips.ethereum.org/EIPS/eip-2470).

The Pre-fund the Singleton Factory's deployer with the required funds to deploy the contract.

```
Address: 0xBb6e024b9cFFACB947A71991E386681B1Cd1477D
Funds: 0.0247
```

**Do not send additional funds to the address, as funds can't be refunded.**

Once the address is funded, you can deploy the Singleton Factory by executing the following pre-signed transaction:

```
0xf9016c8085174876e8008303c4d88080b90154608060405234801561001057600080fd5b50610134806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80634af63f0214602d575b600080fd5b60cf60048036036040811015604157600080fd5b810190602081018135640100000000811115605b57600080fd5b820183602082011115606c57600080fd5b80359060200191846001830284011164010000000083111715608d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550509135925060eb915050565b604080516001600160a01b039092168252519081900360200190f35b6000818351602085016000f5939250505056fea26469706673582212206b44f8a82cb6b156bfcc3dc6aadd6df4eefd204bc928a4397fd15dacf6d5320564736f6c634300060200331b83247000822470
```

After the transaction is confirmed, you should see the address of the Singleton Factory:

```
Singleton Deployer: 0xce0042B868300000d44A59004Da54A005ffdcf9f
```

### 2 - Deploy Wallet Context

Deploy each of the contracts in the [Sequence Wallet Context](/solutions/technical-references/wallet-contracts/02-universal-deployer/#) using the Singleton Factory.

A script can be found in the [Sequence Wallet Contracts repository](https://github.com/0xsequence/wallet-contracts/).

Clone the repository, configure the environment variables and run the script with:

```
yarn deploy <network>
```

## Deploy Process V1

The following steps are required to deploy the [Sequence Wallet V1 Context](/solutions/technical-references/wallet-contracts/02-universal-deployer#3---deploy-wallet-context) on a new network.
The following steps are required to deploy the [Sequence Wallet V1 Context](#3---deploy-wallet-context) on a new network.

<Callout type="info">
Notice <br />
For most popular networks this process **is not** required; due to the wallet contracts
being already deployed. To see if a configuration already exists for a given chain
go to [Networks](solutions/technical-references/chain-support).
go to [Networks](../../solutions/technical-references/chain-support).
</Callout>

A complete code example of this deployment flow can be found in the [0xSequence.js test suite](https://github.com/0xsequence/sequence.js/blob/91ed0df67fc5ddc47abf727ae8b94a8ca4f66912/packages/0xsequence/tests/browser/testutils/deploy-wallet-context.ts)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TabGroup, Tab, TabPanel } from "../../../../components/TabGroup.tsx";
import { TabGroup, Tab, TabPanel } from "../../../../../components/TabGroup.tsx";

# Wallet Configuration

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Callout } from "vocs/components";

# Deploy Process V2

The following steps are required to deploy the [Sequence Wallet Context](/solutions/technical-references/wallet-contracts/02-universal-deployer#3---deploy-wallet-context) on a new network.

<Callout type="info">
Notice <br />
For most popular networks this process **is not** required; due to the wallet contracts
being already deployed.
To see if a configuration already exists for a given chain go to [Networks](/solutions/technical-references/chain-support).

</Callout>

### 1 - Deploy Singleton Factory

The Singleton Factory is a contract that allows the deployment of a single contract instance per address. Unlike the
[Universal Deployer](#universal-deployer), the Singleton Factory requires a salt to manage deployment instances. More information about the
Singleton Factory can be found in the [EIP-2470 specification](https://eips.ethereum.org/EIPS/eip-2470).

The Pre-fund the Singleton Factory's deployer with the required funds to deploy the contract.

```
Address: 0xBb6e024b9cFFACB947A71991E386681B1Cd1477D
Funds: 0.0247
```

**Do not send additional funds to the address, as funds can't be refunded.**

Once the address is funded, you can deploy the Singleton Factory by executing the following pre-signed transaction:

```
0xf9016c8085174876e8008303c4d88080b90154608060405234801561001057600080fd5b50610134806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80634af63f0214602d575b600080fd5b60cf60048036036040811015604157600080fd5b810190602081018135640100000000811115605b57600080fd5b820183602082011115606c57600080fd5b80359060200191846001830284011164010000000083111715608d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550509135925060eb915050565b604080516001600160a01b039092168252519081900360200190f35b6000818351602085016000f5939250505056fea26469706673582212206b44f8a82cb6b156bfcc3dc6aadd6df4eefd204bc928a4397fd15dacf6d5320564736f6c634300060200331b83247000822470
```

After the transaction is confirmed, you should see the address of the Singleton Factory:

```
Singleton Deployer: 0xce0042B868300000d44A59004Da54A005ffdcf9f
```

### 2 - Deploy Wallet Context

Deploy each of the contracts in the [Sequence Wallet Context](/solutions/technical-references/wallet-contracts/02-universal-deployer/#) using the Singleton Factory.

A script can be found in the [Sequence Wallet Contracts repository](https://github.com/0xsequence/wallet-contracts/).

Clone the repository, configure the environment variables and run the script with:

```
yarn deploy <network>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Wallet Configuration

In the context of Sequence Wallets, the "Wallet Configuration" is a set of parameters that defines the behavior of the wallet, primarily used to define the access control of the wallet, meaning who can sign transactions and how many signatures are needed.

## Top level properties

Sequence v2 configurations contain the following 3 properties:

- `threshold` - The required "weight sum" needed for a signature to be considered valid.
- `checkpoint` - Used as a salt and ordering mechanism for wallet updates.
- `tree` - Determines the signers and their weights for the wallet.

### Threshold

The `threshold` is a `uint16`; it can have any value between 0 and 65535. Signatures are only considered valid or invalid if the sum of the weights of the signers that signed the transaction is greater or equal to the threshold.

### Checkpoint

The `checkpoint` is a `uint32`. During wallet creation, a semi-random value can be provided to generate independent wallets with the same initial configuration. Then, during normal operation, the `checkpoint` is used by Light State Sync to ensure that wallet updates are applied in the correct order.

### Tree

The `tree` is an unbalanced binary Merkle tree, where each leaf may contain a signer, a static signature, or a subtree. The tree can represent any combination of signers and weights and can be used to create complex multi-signature wallets.

The possible leaf types are:

#### Signer

Signers are represented by a signer `address` and a `uint8` weight. The weight is how much the signer contributes to the threshold.
The address can belong to either an `ERC1271` compliant contract or an `EOA` wallet.

The leaf hash is calculated as follows:

```solidity
bytes32(uint256(weight) << 160 | uint256(uint160(addr)))
```

#### Subdigest

This represents a static subdigest for which any signature is valid. If a signature for this subdigest is provided, the total weight of the signature is automatically set to `Infinity`.

Notice static subdigests that exist within nested trees will have their "Infinity" weight reduced to the weight of the nested tree.

The leaf hash is calculated as follows:

```solidity
keccak256(abi.encodePacked('Sequence static digest:\n', subdigest));
```

#### Subtree (nested configuration)

This represents a whole new wallet configuration, this "nested configuration" has its own:

- External `weight` (`uint8`)
- Internal `threshold` (`uint16`)
- Internal `tree`

The way it works is that if a signature reaches the `internal threshold` within the subtree it is considered valid, and the `external weight` is added to the parent tree. Any number of nested configurations can be created, and it is possible to create multiple nesting levels.

This pattern can be used, among other things, to express the following scenarios:
- Non-linear weight distribution, A and B signers can provide 1 weight each, but together they can provide 3 weight.
- Limited total weight contribution, A, B, and C signers can provide 1 weight each, but together they can only provide 2 weight.
- "Department configurations", N departments are required to sign, and each department has its own inner configuration.

The leaf hash is calculated as follows:

```solidity
keccak256(abi.encodePacked(
'Sequence nested config:\n',
imageHash(tree),
threshold,
weight
))
```

:::warning
The wallet contracts have no way of validating the correctness of the configuration, the responsibility of ensuring the configuration is correct is on the SDKs interacting with the contracts.

Things like `threshold == 0` or `threshold > total weight` will result in fully unauthenticated wallets or inaccessible wallets respectively.
:::

## ImageHash

The `configuration` is never stored as a whole; instead, the Merkle tree is hashed into a single `bytes32` value, this is internally called the `imageHash` of the configuration.

The `imageHash` is calculated as follows:

```solidity
imageHash := keccak256(abi.encode(
keccak256(abi.encode(
hashTree(tree),
threshold
)),
checkpoint
))
```

The `hashTree` function is a recursive function that hashes the tree into a single `bytes32` value, pseudo code for the `hashTree` function is as follows:

```typescript
export function hashTree(node: Node | Leaf): string {
if (isSignerLeaf(node)) {
return ethers.utils.solidityPack(
['uint96', 'address'],
[node.weight, node.address]
)
}

if (isSubdigestLeaf(node)) {
return ethers.utils.solidityKeccak256(
['string', 'bytes32'],
['Sequence static digest:\n', node.subdigest]
)
}

if (isNestedLeaf(node)) {
const nested = hashTree(node.tree)
return ethers.utils.solidityKeccak256(
['string', 'bytes32', 'uint256', 'uint256'],
['Sequence nested config:\n', nested, node.threshold, node.weight]
)
}

return ethers.utils.solidityKeccak256(
['bytes32', 'bytes32'],
[hashTree(node.left), hashTree(node.right)]
)
}
```

## Initial Configuration

All Sequence Wallets have an "initial configuration", implemented by using the `imageHash` of the initial configuration as the SALT during the `CREATE2` deployment of the wallet.

Wallets are deployed by calling the `deploy` function of the `Factory` contract, which takes the following parameters:
- `mainModule`: The address of the initial code implementation of the wallet.
- `salt`: The `imageHash` of the initial configuration.

:::info
The `MainModule` should always be used as the initial code implementation of the wallet. The `MainModule` validates the `imageHash` (during signature validation) by re-computing the counterfactual address of the wallet, hence it does not require any storage initialization.

If the `imageHash` is ever changed, `MainModule` will automatically replace the wallet code implementation with `MainModuleUpgradeable`, while handling the storage initialization.
:::

This file was deleted.

29 changes: 17 additions & 12 deletions nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,18 +174,23 @@ export const sidebar = {
// { text: 'EIP5189 vs. 4337', link: '/solutions/technical-references/5189-4337' },
{ text: 'Smart Contract Wallets', collapsed: true, items: [
{ text: 'Why smart contract wallets?', link: '/solutions/technical-references/wallet-contracts/01-why' },
{ text: 'Universal Deployer', link: '/solutions/technical-references/wallet-contracts/02-universal-deployer' },
{text: 'Wallet Factory', link: '/solutions/technical-references/wallet-contracts/03-wallet-factory'},
{text: 'Wallet Configuration', link: '/solutions/technical-references/wallet-contracts/04-wallet-configuration'},
// {text: 'Modules & Wallet update', link: 'solutions/technical-references/wallet-contracts/05-modules-and-updates'},
// {text: 'MainModuleUpgradeable & configuration migration', link: 'solutions/technical-references/wallet-contracts/06-main-module-upgradeable'},
{text: 'Transaction Encoding', link: '/solutions/technical-references/wallet-contracts/07-transaction-encoding'},
{text: 'Signature Encoding', link: '/solutions/technical-references/wallet-contracts/08-signature-encoding'},
// {text: 'Nested Transaction Batching', link: 'solutions/technical-references/wallet-contracts/09-nested-transaction-batching'},
// {text: 'GuestModule and on-demand deployment', link: 'solutions/technical-references/wallet-contracts/10-guest-module'},
{text: 'Wallet Context', link: '/solutions/technical-references/wallet-contracts/11-wallet-context'},
{text: 'Contract Audits', link: '/solutions/technical-references/wallet-contracts/12-contract-audits'},
] }
] },
{ text: 'Contract Internals', collapsed: true, items: [
{text: 'Deployment', link: '/solutions/technical-references/internals/01-deployment'},
{ text: 'Sequence v1', collapsed: true, items: [
{text: 'Deploy', link: '/solutions/technical-references/internals/v1/01-deploy'},
{text: 'Wallet Factory', link: '/solutions/technical-references/internals/v1/03-wallet-factory'},
{text: 'Wallet Configuration', link: '/solutions/technical-references/internals/v1/04-wallet-configuration'},
// {text: 'Transaction Encoding', link: '/solutions/technical-references/internals/v1/07-transaction-encoding'},
{text: 'Signature Encoding', link: '/solutions/technical-references/internals/v1/08-signature-encoding'},
{text: 'Wallet Context', link: '/solutions/technical-references/internals/v1/11-wallet-context'},
{text: 'Contract Audits', link: '/solutions/technical-references/internals/v1/12-contract-audits'},
]},
{ text: 'Sequence v2', collapsed: true, items: [
{text: 'Deploy', link: '/solutions/technical-references/internals/v2/01-deploy'},
{text: 'Wallet Configuration', link: "/solutions/technical-references/internals/v2/04-configuration"},
]}
]}
]
},

Expand Down

0 comments on commit 4dbe1af

Please sign in to comment.