Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
id: emergency-withdrawal
title: Emergency Withdrawal (guest requirements)
---

[Emergency withdrawal](../../development/foreclosure/overview.md) lets users recover their in-app balances directly from the base layer after an application is foreclosed. For that to work, the on-chain contracts need a way to read each account's balance from the settled machine state. This page describes what the **guest application** (the code running inside the Cartesi Machine) must do to support it.

## The accounts drive

The application keeps a dedicated region of machine memory called the **accounts drive**. It is the withdrawable-balance ledger: a list of account records, where each record holds an owner and that owner's balance. After foreclosure, the contracts prove this drive against the settled machine state and pay each account out from it.

An application supports emergency withdrawal only if:

1. it maintains an accounts drive, and
2. the drive's layout matches the [`WithdrawalConfig`](../contracts/withdrawal/withdrawal-config.md) the application was deployed with.

If the layout the guest writes and the config the contract was given disagree, proofs will not validate and funds cannot be withdrawn.

## Matching the layout

The [`WithdrawalConfig`](../contracts/withdrawal/withdrawal-config.md) describes the drive with three values, and the guest must write records that match them:

- `accountsDriveStartIndex` positions the drive in machine memory;
- `log2MaxNumOfAccounts` sets how many accounts fit (the tree depth);
- `log2LeavesPerAccount` sets each record's size, which is `2^(5 + log2LeavesPerAccount)` bytes.

For the single-token case (see [`UsdWithdrawalOutputBuilder`](../contracts/withdrawal/usd-withdrawal-output-builder.md)), each record is 32 bytes: an 8-byte little-endian balance, followed by the 20-byte owner address, followed by padding.

## Keeping the balances

You rarely need to write the drive by hand. A ledger library maintains the accounts drive for you: it credits deposits, debits withdrawals and transfers, and stores every balance in the drive so it stays provable from the machine state. See the [Asset Management Library](https://cartesi.github.io/docs/pr-preview/pr-303/cartesi-rollups/2.0/api-reference/asset-management/overview/) for how to store and manage balances this way.

## The account encoding must round-trip

The bytes the guest writes for an account must be the same bytes the on-chain [withdrawal output builder](../contracts/withdrawal/iwithdrawal-output-builder.md) decodes at withdrawal time. For the USD builder, that means the `(owner, balance)` encoding the guest produces must match what the builder reads back to build the transfer.

:::note
Emergency withdrawal relies on four descriptions of the accounts drive agreeing: the layout the **guest** writes, the **`WithdrawalConfig`** on-chain, the parameters used to **generate proofs** off-chain, and the account encoding the **output builder** decodes. Choose these together at deploy time. See [Withdrawal Contracts Overview](../contracts/withdrawal/overview.md#the-four-way-agreement).
:::
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
id: application-factory
title: ApplicationFactory
resources:
- url: https://github.com/cartesi/rollups-contracts/tree/v2.0.1/src/dapp/ApplicationFactory.sol
- url: https://github.com/cartesi/rollups-contracts/tree/v3.0.0-alpha.6/src/dapp/ApplicationFactory.sol
title: Application Factory contract
---

Expand All @@ -21,7 +21,8 @@ function newApplication(
IOutputsMerkleRootValidator outputsMerkleRootValidator,
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability
bytes calldata dataAvailability,
WithdrawalConfig calldata withdrawalConfig
) external override returns (IApplication)
```

Expand All @@ -35,6 +36,7 @@ Deploys a new Application contract without a salt value for address derivation.
| `appOwner` | `address` | Address of the owner of the application |
| `templateHash` | `bytes32` | Hash of the template for the application |
| `dataAvailability` | `bytes` | The data availability solution |
| `withdrawalConfig` | `WithdrawalConfig` | The withdrawal configuration (see [WithdrawalConfig](./withdrawal/withdrawal-config.md)). Pass a zero-valued config to deploy without emergency withdrawal |

**Return Values**

Expand All @@ -50,6 +52,7 @@ function newApplication(
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability,
WithdrawalConfig calldata withdrawalConfig,
bytes32 salt
) external override returns (IApplication)
```
Expand All @@ -64,6 +67,7 @@ Deploys a new `Application` contract with a specified salt value for address der
| `appOwner` | `address` | Address of the owner of the application |
| `templateHash` | `bytes32` | Hash of the template for the application |
| `dataAvailability` | `bytes` | The data availability solution |
| `withdrawalConfig` | `WithdrawalConfig` | The withdrawal configuration (see [WithdrawalConfig](./withdrawal/withdrawal-config.md)). Pass a zero-valued config to deploy without emergency withdrawal |
| `salt` | `bytes32` | Salt value for address derivation |

**Return Values**
Expand All @@ -80,6 +84,7 @@ function calculateApplicationAddress(
address appOwner,
bytes32 templateHash,
bytes calldata dataAvailability,
WithdrawalConfig calldata withdrawalConfig,
bytes32 salt
) external view override returns (address)
```
Expand All @@ -94,6 +99,7 @@ Calculates the address of a potential new Application contract based on input pa
| `appOwner` | `address` | Address of the owner of the application |
| `templateHash` | `bytes32` | Hash of the template for the application |
| `dataAvailability` | `bytes` | The data availability solution |
| `withdrawalConfig` | `WithdrawalConfig` | The withdrawal configuration (see [WithdrawalConfig](./withdrawal/withdrawal-config.md)). Pass a zero-valued config to deploy without emergency withdrawal |
| `salt` | `bytes32` | Salt value for address derivation |

**Return Values**
Expand All @@ -112,6 +118,7 @@ event ApplicationCreated(
address appOwner,
bytes32 templateHash,
bytes dataAvailability,
WithdrawalConfig withdrawalConfig,
IApplication appContract
)
```
Expand All @@ -126,4 +133,21 @@ A new Application contract was deployed.
| `appOwner` | `address` | The owner of the application |
| `templateHash` | `bytes32` | The template hash |
| `dataAvailability` | `bytes` | The data availability solution |
| `withdrawalConfig` | `WithdrawalConfig` | The withdrawal configuration (see [WithdrawalConfig](./withdrawal/withdrawal-config.md)). Pass a zero-valued config to deploy without emergency withdrawal |
| `appContract` | `IApplication` | The deployed Application contract |

## Errors

### `InvalidWithdrawalConfig()`

```solidity
error InvalidWithdrawalConfig(WithdrawalConfig withdrawalConfig)
```

Raised at deployment when the provided [`WithdrawalConfig`](./withdrawal/withdrawal-config.md) is invalid, meaning its accounts-drive layout does not fit inside the machine memory (see [`LibWithdrawalConfig.isValid`](./withdrawal/withdrawal-config.md#validation)). Checking the config in the factory means users and the node do not have to check it themselves.

**Parameters**

| Name | Type | Description |
|------|------|-------------|
| `withdrawalConfig` | `WithdrawalConfig` | The invalid withdrawal configuration |
Loading
Loading