Skip to content
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
192 changes: 192 additions & 0 deletions src/doc/simulate-l2-deposit-transactions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
# Simulating L2 Deposit Transactions with Integration Tests

The following steps describe how to automatically simulate L2 deposit transactions prior to L1 task execution using integration tests. This approach is similar to the [manual Tenderly simulation approach](./simulate-l2-ownership-transfer.md), with the key difference being that it uses a local supersim instance and automated transaction replay instead of manual Tenderly simulation.

## Overview

When executing L1 transactions that trigger L2 deposit transactions (via the OptimismPortal), we can gain additional confidence by automatically replaying these deposit transactions on a local L2 fork, simulating what op-node does. The `IntegrationBase` contract provides a `_relayAllMessages` function that:

1. Extracts all `TransactionDeposited` events from the L1 execution
2. Decodes the deposit transaction parameters
3. Executes each transaction on the L2 fork with the correct aliased sender
4. Generates Tenderly simulation links for each transaction
5. Asserts that all transactions succeed

This automated approach is particularly useful for complex tasks that emit multiple deposit transactions, such as the revenue share upgrade path which can emit 12+ deposit transactions per execution.

## Prerequisites

### Supersim Setup

You'll need to run supersim with forked chains to test against real network state. Supersim is a lightweight tool that runs local L1 and L2 nodes with forking capabilities.

Install supersim if you haven't already:
```bash
# Installation instructions: https://github.com/ethereum-optimism/supersim
```

Start supersim with forked chains:
```bash
supersim fork --chains=op --interop.enabled
```

**Note:** You can use any L2 chain supported by supersim (e.g., `op`, `base`, `mode`, etc.). The default ports are:
- L1 (Ethereum): `http://127.0.0.1:8545`
- L2 (OP Mainnet): `http://127.0.0.1:9545`

For different L2 chains, adjust the RPC URLs and network IDs accordingly.

## Creating an Integration Test

### Step 1: Inherit from IntegrationBase

Create a test contract that inherits from `IntegrationBase`:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import {IntegrationBase} from "test/integration/IntegrationBase.t.sol";
import {YourTemplate} from "src/template/YourTemplate.sol";

contract YourIntegrationTest is IntegrationBase {
YourTemplate public template;

// Fork IDs
uint256 internal _mainnetForkId;
uint256 internal _l2ForkId;

function setUp() public {
// Create forks pointing to supersim instances
_mainnetForkId = vm.createFork("http://127.0.0.1:8545");
_l2ForkId = vm.createFork("http://127.0.0.1:9545");

// Deploy template on L1 fork
vm.selectFork(_mainnetForkId);
template = new YourTemplate();
}
}
```

### Step 2: Execute L1 Transaction and Relay Messages

In your test function, execute the L1 transaction while recording logs, then relay all deposit messages to L2:

```solidity
function test_yourTask_integration() public {
string memory _configPath = "path/to/your/config.toml";

// Step 1: Execute L1 transaction recording logs
vm.recordLogs();
template.simulate(_configPath, new address[](0));

// Step 2: Relay messages from L1 to L2
// Pass true for _isSimulate since simulate() emits events twice
// (once during dry-run validation, once during actual simulation)
_relayAllMessages(_l2ForkId, true);

// Step 3: Assert the state of the L2 contracts
string memory _config = vm.readFile(_configPath);

// Add your L2 state assertions here...
}
```

### Step 3: Add State Assertions

After relaying messages, assert that the L2 state matches expectations:

```solidity
// Example: Checking a contract's owner
assertEq(
OwnableUpgradeable(l2Contract).owner(),
vm.parseTomlAddress(_config, ".newOwner")
);

// Example: Checking a configuration value
assertEq(
IYourContract(l2Contract).someValue(),
vm.parseTomlUint(_config, ".expectedValue")
);
```

## Example: Revenue Share Integration Test

See [RevenueShareIntegration.t.sol](../../test/integration/RevenueShareIntegration.t.sol) for a complete example that:

- Tests both opt-in and opt-out scenarios
- Tests late opt-in scenarios
- Validates multiple L2 contracts (L1Withdrawer, RevShareCalculator, FeeSplitter, FeeVaults)
- Asserts complex state relationships between contracts

Key test structure:
```solidity
function test_optInRevenueShare_integration() public {
// 1. Execute L1 transaction
vm.recordLogs();
revenueShareTemplate.simulate(_configPath, new address[](0));

// 2. Relay messages to L2
_relayAllMessages(_l2ForkId, true);

// 3. Assert L2 state
assertEq(IL1Withdrawer(L1_WITHDRAWER).minWithdrawalAmount(), expectedValue);
assertEq(IFeeSplitter(FEE_SPLITTER).sharesCalculator(), REV_SHARE_CALCULATOR);
// ... more assertions
}
```

## Understanding the Output

When you run an integration test, `_relayAllMessages` will output:

```
================================================================================
=== Replaying Deposit Transactions on L2 ===
=== Each transaction includes Tenderly simulation link ===
=== Network is set to 10 (OP Mainnet) - adjust if testing on different L2 ===
================================================================================

Tenderly Simulation Link for transaction #1
https://dashboard.tenderly.co/TENDERLY_USERNAME/TENDERLY_PROJECT/simulator/new?network=10&contractAddress=0x...&from=0x...&gas=656536&value=0&rawFunctionInput=0x...

Tenderly Simulation Link for transaction #2
...

=== Summary ===
Total transactions: 12
Successful transactions: 12
Failed transactions: 0
```

## Manual Tenderly Simulation

While integration tests provide automated validation, you can also manually simulate individual transactions in Tenderly by:

1. Copying a Tenderly link from the integration test output
2. Opening the link in your browser
3. Inspecting the transaction details, state changes, and gas usage

For detailed manual simulation steps, see [simulate-l2-ownership-transfer.md](./simulate-l2-ownership-transfer.md).

## Recording Simulation Results

After running integration tests and generating Tenderly simulations, document the results in your task's validation file. See [RevenueShareSimulations.md](../../test/integration/tenderly/RevenueShareSimulations.md) for an example format:

```markdown
# Your Task Simulations

### Scenario 1
1. [Contract Deploy](https://www.tdly.co/shared/simulation/...) Gas: 558,056/656,536 (85%)
2. [Contract Upgrade](https://www.tdly.co/shared/simulation/...) Gas: 65,138/150,000 (43%)
...
```

## Troubleshooting

### Failed Tenderly Transactions but working in the Supersim integration
Something that sucks on the Tenderly simulations is that it is very hard (actually I don't know how) to keep the state changes of previously simulated transactions. So if you are testing the transactions of a task that first -> upgrades a contract to have setters and then -> calls that setter, when simulating the setter transaction, it will revert. This is the reason why the rev share late opt in transactions don't have tenderly simulations linked


### Fork Issues
When first running the fork test against supersim, do it with a `--match-test` that does only one fork for caching the network states. If you try to run more than one at the same time by, for example, using `--match-contract`, you might get timeout issues
26 changes: 12 additions & 14 deletions src/libraries/RevShareGasLimits.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,26 @@ pragma solidity 0.8.15;

/// @notice Library for storing the gas limits for the calls done in the Revenue Share templates
library RevShareGasLimits {
/// @notice Based on deployment tests, these are the average gas costs for each of the L2 operations:
/// - L1Withdrawer deployment: 497,812
/// - SC Rev Share Calculator deployment: 518,168
/// - Fee Vaults deployment: 757,214
/// - Fee Splitter deployment: 1,027,359
/// - upgradeAndCall: 73,015
/// - upgrade: 6,202
/// - setters: TODO: add this after simulating in tenderly
/// A buffer of ~20% is applied to each value to have enough margin. While leaving the upgrade call
/// to a fixed 150,000 gas limit.
/// @notice Based on Tenderly simulations, these are the actual gas costs for each of the L2 operations:
/// - L1Withdrawer deployment: 558,056
/// - SC Rev Share Calculator deployment: 579,688
/// - Fee Vaults deployment: ~831,000
/// - Fee Splitter deployment: 1,121,747
/// - upgrade: ~48,000
/// - setters: ~50,000
/// The gas limits below include a buffer to ensure successful execution.

/// @notice The gas limit for the SC Rev Share Calculator deployment.
uint64 internal constant SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT = 625_000;
uint64 internal constant SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT = 681_986;

/// @notice The gas limit for the L1 Withdrawer deployment.
uint64 internal constant L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT = 625_000;
uint64 internal constant L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT = 656_536;

/// @notice The gas limit for the Fee Vaults deployment.
uint64 internal constant FEE_VAULTS_DEPLOYMENT_GAS_LIMIT = 910_000;
uint64 internal constant FEE_VAULTS_DEPLOYMENT_GAS_LIMIT = 1_200_000;

/// @notice The gas limit for the Fee Splitter deployment.
uint64 internal constant FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT = 1_235_000;
uint64 internal constant FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT = 1_319_702;

/// @notice The gas limit for the upgrade calls on L2.
uint64 internal constant UPGRADE_GAS_LIMIT = 150_000;
Expand Down
49 changes: 27 additions & 22 deletions test/integration/tenderly/RevenueShareSimulations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,32 @@
A list of tenderly simulations are provided based on the formatting of the `TransactionDeposited` events emitted in L1 and its execution in the target L2, in this case, OP Mainnet. For details, check the [Simulating Portal Deposit Transactions](todo) document

### Revenue Share Upgrade Opt In
1. [L1Withdrawer Deploy](https://www.tdly.co/shared/simulation/2de00980-0c73-4cf8-834f-c9210ba738d2) Gas: 558,056/625,000 (89%)
2. [Rev Share Calculator Deploy](https://dashboard.tenderly.co/0xchin/project/simulator/c2970c09-7df7-4f97-bd2c-fd74caf1f2b0) Gas: 579,688/625,000 (93%)
3. [Fee Splitter Deploy](https://dashboard.tenderly.co/0xchin/project/simulator/6b084159-75ed-41b1-993c-a0a6953616c5) Gas: 1.121.747/1,235,000 (91%)
4. [Fee Splitter Upgrade](https://www.tdly.co/shared/simulation/3e224c10-f2e9-4346-8ea4-ddb031d37894) Gas: 65,378/150,000 (44%)
5. [Operator Fee Vault Deploy](https://www.tdly.co/shared/simulation/c78942e2-6008-475d-a049-f07866586ef6) Gas: 831,558/910,000 (91%)
6. [Operator Fee Vault Upgrade](https://www.tdly.co/shared/simulation/ff2a2b2b-992b-46f7-9355-743df1cffd96) Gas: 42,886/150,000 (29%)
7. [Sequencer Fee Vault Deploy](https://www.tdly.co/shared/simulation/19e79c8e-4461-48dc-8477-e2bc5e1160eb) Gas: 841,784/910,000 (93%)
8. [Sequencer Fee Vault Upgrade](https://www.tdly.co/shared/simulation/d857f412-b3b3-456a-b2f8-5ecfc064d193) Gas: 40,386/150,000 (27%)
9. [Base Fee Vault Deploy](https://www.tdly.co/shared/simulation/db7e5826-deab-4e22-82e1-20c862ccb195) Gas: 831,546/910,000 (91%)
10. [Base Fee Vault Upgrade](https://www.tdly.co/shared/simulation/e16884f7-0905-4723-bca3-febf65c523b4) Gas: 42,886/150,000 (29%)
11. [L1 Fee Vault Deploy](https://www.tdly.co/shared/simulation/c372faa5-72e2-45a5-97a7-28b3c4826869) Gas: 831,558/910,000 (91%)
12. [L1 Fee Vault Upgrade](https://www.tdly.co/shared/simulation/37d55586-306a-40bd-a80d-954fe2373751) Gas: 42,886/150,000 (29%)
1. [L1Withdrawer Deploy](https://www.tdly.co/shared/simulation/cfb6f065-1f37-47ee-96e1-9a32ea80f540) Gas: 558,056/656,536 (85%)
2. [Rev Share Calculator Deploy](https://www.tdly.co/shared/simulation/5c813d81-9fa7-45e5-ac61-bbe89b917be8) Gas: 579,688/681,986 (85%)
3. [Fee Splitter Deploy](https://www.tdly.co/shared/simulation/93b43e8d-e64c-4ce5-ad2c-7047e91e4a4c) Gas: 1,121,747/1,319,702 (85%)
4. [Fee Splitter Upgrade](https://www.tdly.co/shared/simulation/ac7c91dc-9c1b-4b56-bfd4-bad52fd0b2aa) Gas: 65,138/150,000 (43%)
5. [Operator Fee Vault Deploy](https://www.tdly.co/shared/simulation/4c95b834-89b4-4f2e-8bca-8df9ed0cc885) Gas: 893,030/1,200,000 (74%)
6. [Operator Fee Vault Upgrade](https://www.tdly.co/shared/simulation/45662e37-ab84-4ad9-96ee-46144eb0ec49) Gas: 48,770/150,000 (33%)
7. [Sequencer Fee Vault Deploy](https://www.tdly.co/shared/simulation/4e24dd89-f601-4a54-a72d-3ac4a4c1e7c8) Gas: 890,692/1,200,000 (74%)
8. [Sequencer Fee Vault Upgrade](https://www.tdly.co/shared/simulation/29051fa4-0687-4a58-9ea5-6a09497e3846) Gas: 46,270/150,000 (31%)
9. [Base Fee Vault Deploy](https://www.tdly.co/shared/simulation/515d5554-1f3e-4061-be24-6d3e888ed4d9) Gas: 890,692/1,200,000 (74%)
10. [Base Fee Vault Upgrade](https://www.tdly.co/shared/simulation/04d8de5e-89bc-419d-bbcf-ee0448d0e813) Gas: 48,782/150,000 (33%)
11. [L1 Fee Vault Deploy](https://www.tdly.co/shared/simulation/bcee51db-b549-4c05-811f-be831e6a1aa0) Gas: 890,704/1,200,000 (74%)
12. [L1 Fee Vault Upgrade](https://www.tdly.co/shared/simulation/20dbe19b-cea7-4542-a73b-71934394153e) Gas: 48,782/150,000 (33%)

**Disclaimer**: The contracts addresses sent in the implementation contracts when calling upgrades, do not match with the addresses deployed in the transaction before. This is because given the simulations are done in an isolated environment (instead of being bundled), the nonce of the POA isn't the expected. To verify that it is working propertly, the integration tests with Supersim *do* work.

### Revenue Share Upgrade Opt Out
1. [Fee Splitter Deploy](https://dashboard.tenderly.co/0xchin/project/simulator/6b084159-75ed-41b1-993c-a0a6953616c5) Gas: 1.121.747/1,235,000 (91%)
2. [Fee Splitter Upgrade](https://www.tdly.co/shared/simulation/3e224c10-f2e9-4346-8ea4-ddb031d37894) Gas: 65,378/150,000 (44%)
3. [Operator Fee Vault Deploy](https://www.tdly.co/shared/simulation/c78942e2-6008-475d-a049-f07866586ef6) Gas: 831,558/910,000 (91%)
4. [Operator Fee Vault Upgrade](https://www.tdly.co/shared/simulation/ff2a2b2b-992b-46f7-9355-743df1cffd96) Gas: 42,886/150,000 (29%)
5. [Sequencer Fee Vault Deploy](https://www.tdly.co/shared/simulation/19e79c8e-4461-48dc-8477-e2bc5e1160eb) Gas: 841,784/910,000 (93%)
6. [Sequencer Fee Vault Upgrade](https://www.tdly.co/shared/simulation/d857f412-b3b3-456a-b2f8-5ecfc064d193) Gas: 40,386/150,000 (27%)
7. [Base Fee Vault Deploy](https://www.tdly.co/shared/simulation/db7e5826-deab-4e22-82e1-20c862ccb195) Gas: 831,546/910,000 (91%)
8. [Base Fee Vault Upgrade](https://www.tdly.co/shared/simulation/e16884f7-0905-4723-bca3-febf65c523b4) Gas: 42,886/150,000 (29%)
9. [L1 Fee Vault Deploy](https://www.tdly.co/shared/simulation/c372faa5-72e2-45a5-97a7-28b3c4826869) Gas: 831,558/910,000 (91%)
10. [L1 Fee Vault Upgrade](https://www.tdly.co/shared/simulation/37d55586-306a-40bd-a80d-954fe2373751) Gas: 42,886/150,000 (29%)
1. [Fee Splitter Deploy](https://www.tdly.co/shared/simulation/93b43e8d-e64c-4ce5-ad2c-7047e91e4a4c) Gas: 1,121,747/1,319,702 (85%)
2. [Fee Splitter Upgrade](https://www.tdly.co/shared/simulation/ac7c91dc-9c1b-4b56-bfd4-bad52fd0b2aa) Gas: 65,138/150,000 (43%)
3. [Operator Fee Vault Deploy](https://www.tdly.co/shared/simulation/4c95b834-89b4-4f2e-8bca-8df9ed0cc885) Gas: Gas: 893,030/1,200,000 (74%)
4. [Operator Fee Vault Upgrade](https://www.tdly.co/shared/simulation/45662e37-ab84-4ad9-96ee-46144eb0ec49) Gas: 48,770/150,000 (33%)
5. [Sequencer Fee Vault Deploy](https://www.tdly.co/shared/simulation/4e24dd89-f601-4a54-a72d-3ac4a4c1e7c8) Gas: 890,692/1,200,000 (74%)
6. [Sequencer Fee Vault Upgrade](https://www.tdly.co/shared/simulation/29051fa4-0687-4a58-9ea5-6a09497e3846) Gas: 46,270/150,000 (31%)
7. [Base Fee Vault Deploy](https://www.tdly.co/shared/simulation/515d5554-1f3e-4061-be24-6d3e888ed4d9) Gas: 890,692/1,200,000 (74%)
8. [Base Fee Vault Upgrade](https://www.tdly.co/shared/simulation/04d8de5e-89bc-419d-bbcf-ee0448d0e813) Gas: 48,782/150,000 (33%)
9. [L1 Fee Vault Deploy](https://www.tdly.co/shared/simulation/bcee51db-b549-4c05-811f-be831e6a1aa0) Gas: 890,704/1,200,000 (74%)
10. [L1 Fee Vault Upgrade](https://www.tdly.co/shared/simulation/20dbe19b-cea7-4542-a73b-71934394153e) Gas: 48,782/150,000 (33%)

### Revenue Share Late Opt In
Given that this transactions depend on the Fee Vault upgrades to after that call the Fee Vault setters, and that Tenderly simulations can't keep the state of previously simulated transactions. No simulations are provided for this flow, for more info check the [Simulate L2 Deposit Transactions](src/doc/simulate-l2-deposit-transactions.md) doc
26 changes: 13 additions & 13 deletions test/tasks/Regression.t.sol

Large diffs are not rendered by default.

Loading