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
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ remappings = [
'@solady/=lib/optimism/packages/contracts-bedrock/lib/solady/src/',
'@lib-keccak/=lib/optimism/packages/contracts-bedrock/lib/lib-keccak/contracts/lib/',
'ds-test/=lib/optimism/packages/contracts-bedrock/lib/forge-std/lib/ds-test/src',
'forge-std/=lib/forge-std/src/',
'forge-std/=lib/forge-std/src/'
]

[profile.ci]
Expand Down
54 changes: 45 additions & 9 deletions src/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -70,28 +70,53 @@ simulate-stack NETWORK="" TASK="" CHILD_SAFE_NAME_DEPTH_1="" CHILD_SAFE_NAME_DEP
[ -z "{{NETWORK}}" ] && { echo -e "\n\033[31mError: No network specified\033[0m"; show_usage; exit 1; }

ETH_RPC_URL=$("$root_dir"/src/script/get-rpc-url.sh "{{NETWORK}}")

# Load FORK_BLOCK_NUMBER from the task's .env file if available
if [ -n "{{TASK}}" ]; then
task_env_file="${root_dir}/src/tasks/{{NETWORK}}/{{TASK}}/.env"
if [ -f "$task_env_file" ]; then
set -a
source "$task_env_file"
set +a
fi
else
# For full stack simulations, find the first .env file that contains FORK_BLOCK_NUMBER
# Search through .env files in numerical order by task number
for env_file in $(find "${root_dir}/src/tasks/{{NETWORK}}" -name ".env" -type f | sort -V); do
if grep -q "FORK_BLOCK_NUMBER" "$env_file" 2>/dev/null; then
set -a
source "$env_file"
set +a
break
fi
done
fi

# Get fork block arguments - will be used for all tasks in the stack
fork_block_args=$(just --justfile "$root_just_file" _get-fork-block-args)

echo -e "\n⏳ Stacked Task simulation in progress..."

if [ -z "{{TASK}}" ]; then
echo -e "⏳ You are simulating all tasks for network: {{NETWORK}}\n"
just list-stack {{NETWORK}}
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string)" {{NETWORK}} --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}}
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string)" {{NETWORK}} --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}} ${fork_block_args}
elif [ -z "{{CHILD_SAFE_NAME_DEPTH_1}}" ] && [ -z "{{CHILD_SAFE_NAME_DEPTH_2}}" ]; then
echo -e "⏳ You are simulating the task: {{TASK}} for network: '{{NETWORK}}' on the root safe\n"
just list-stack {{NETWORK}} {{TASK}}
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string)" "{{NETWORK}}" "{{TASK}}" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}}
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string)" "{{NETWORK}}" "{{TASK}}" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}} ${fork_block_args}
else
task_dir_path="${root_dir}/src/tasks/{{NETWORK}}/{{TASK}}"
child_safe_depth_1=$(just --justfile "$root_just_file" _fetch-safe "$task_dir_path" "{{CHILD_SAFE_NAME_DEPTH_1}}")
child_safe_depth_2=$(just --justfile "$root_just_file" _fetch-safe "$task_dir_path" "{{CHILD_SAFE_NAME_DEPTH_2}}")
just list-stack {{NETWORK}} {{TASK}}

if [ "$child_safe_depth_2" != "$ZERO_ADDRESS" ]; then
echo -e "⏳ You are simulating the task: {{TASK}} for network: '{{NETWORK}}' on the nested safe: $child_safe_depth_2\n"
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string,address,address)" "{{NETWORK}}" "{{TASK}}" "$child_safe_depth_2" "$child_safe_depth_1" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}}
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string,address,address)" "{{NETWORK}}" "{{TASK}}" "$child_safe_depth_2" "$child_safe_depth_1" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}} ${fork_block_args}
else
echo -e "⏳ You are simulating the task: {{TASK}} for network: '{{NETWORK}}' on the nested safe: $child_safe_depth_1\n"
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string,address)" "{{NETWORK}}" "{{TASK}}" "$child_safe_depth_1" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}}
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string,address)" "{{NETWORK}}" "{{TASK}}" "$child_safe_depth_1" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}} ${fork_block_args}
fi
fi
echo -e "\n⚠️ Please note: Some Tenderly links may not work when running a stacked simulation. Check out Tenderly's Virtual TestNets as a workaround.⚠️"
Expand Down Expand Up @@ -119,27 +144,38 @@ sign-stack NETWORK="" TASK="" CHILD_SAFE_NAME_DEPTH_1="" CHILD_SAFE_NAME_DEPTH_2
child_safe_depth_1=$(just --justfile "$root_just_file" _fetch-safe "$task_dir_path" "{{CHILD_SAFE_NAME_DEPTH_1}}")
child_safe_depth_2=$(just --justfile "$root_just_file" _fetch-safe "$task_dir_path" "{{CHILD_SAFE_NAME_DEPTH_2}}")

# Load FORK_BLOCK_NUMBER from the task's .env file if available
task_env_file="$task_dir_path/.env"
if [ -f "$task_env_file" ]; then
set -a
source "$task_env_file"
set +a
fi

# Get fork block arguments
fork_block_args=$(just --justfile "$root_just_file" _get-fork-block-args)

HD_PATH=${HD_PATH:-0}
USE_KEYSTORE=${USE_KEYSTORE:-}
signer_info=$(just --justfile "$root_just_file" _get-signer-args "$HD_PATH" "$USE_KEYSTORE")
signer_args=$(echo "$signer_info" | sed -n '2p')

export SIGNING_MODE_IN_PROGRESS=true
export STACKED_SIGNING_MODE=true

if [ "$child_safe_depth_2" != "$ZERO_ADDRESS" ]; then
echo -e "⏳ You are signing the task: {{TASK}} for network: '{{NETWORK}}' on the nested safe: $child_safe_depth_2\n"
${root_dir}/bin/eip712sign ${signer_args} -- \
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string,address,address)" "{{NETWORK}}" "{{TASK}}" "$child_safe_depth_2" "$child_safe_depth_1" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}}
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string,address,address)" "{{NETWORK}}" "{{TASK}}" "$child_safe_depth_2" "$child_safe_depth_1" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}} ${fork_block_args}
elif [ -z "{{CHILD_SAFE_NAME_DEPTH_1}}" ] && [ -z "{{CHILD_SAFE_NAME_DEPTH_2}}" ]; then
echo -e "⏳ You are signing the task: {{TASK}} for network: '{{NETWORK}}' on the root safe\n"
just list-stack {{NETWORK}} {{TASK}}
${root_dir}/bin/eip712sign ${signer_args} -- \
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string)" "{{NETWORK}}" "{{TASK}}" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}}
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string)" "{{NETWORK}}" "{{TASK}}" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}} ${fork_block_args}
else
echo -e "⏳ You are signing the task: {{TASK}} for network: '{{NETWORK}}' on the nested safe: $child_safe_depth_1\n"
${root_dir}/bin/eip712sign ${signer_args} -- \
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string,address)" "{{NETWORK}}" "{{TASK}}" "$child_safe_depth_1" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}}
forge script ${root_dir}/src/tasks/StackedSimulator.sol:StackedSimulator --sig "simulateStack(string,string,address)" "{{NETWORK}}" "{{TASK}}" "$child_safe_depth_1" --ffi --fork-url $ETH_RPC_URL --fork-retries {{forge_fork_retries}} --fork-retry-backoff {{forge_fork_retry_backoff}} ${fork_block_args}
fi
echo -e "\n⚠️ Please note: Some Tenderly links may not work when running a stacked simulation. Check out Tenderly's Virtual TestNets as a workaround.⚠️"

Expand Down
27 changes: 18 additions & 9 deletions src/tasks/TaskManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ contract TaskManager is Script {

string memory formattedRootSafe = vm.toString(config.rootSafe).green().bold();

setTenderlyGasEnv(config.basePath);
setEnv(config.basePath);

string[] memory parts = vm.split(config.basePath, "/");
string memory taskName = parts[parts.length - 1];
Expand Down Expand Up @@ -234,25 +234,34 @@ contract TaskManager is Script {
);
}

/// @notice Sets the TENDERLY_GAS environment variable for the task if it exists.
function setTenderlyGasEnv(string memory basePath) public {
/// @notice Sets environment variables from the task's .env file if it exists.
function setEnv(string memory basePath) public {
string memory envFile = string.concat(basePath, "/", ".env");
if (vm.isFile(envFile)) {
string memory envContent = vm.readFile(envFile);
string[] memory lines = vm.split(envContent, "\n");

for (uint256 i = 0; i < lines.length; i++) {
if (lines[i].contains("TENDERLY_GAS=")) {
// Skip empty lines and comments
if (bytes(lines[i]).length == 0 || lines[i].startsWith("#")) {
continue;
}

// Parse key=value pairs
if (lines[i].contains("=")) {
string[] memory keyValue = vm.split(lines[i], "=");
if (keyValue.length == 2) {
vm.setEnv("TENDERLY_GAS", keyValue[1]);
return;
if (keyValue.length >= 2) {
// Trim whitespace from key and value, then set the environment variable
string memory key = vm.trim(keyValue[0]);
string memory value = vm.trim(keyValue[1]);
vm.setEnv(key, value);
}
}
}
} else {
// If no .env file exists, set TENDERLY_GAS to empty for backwards compatibility
vm.setEnv("TENDERLY_GAS", "");
}
// If no TENDERLY_GAS is found, set it as empty.
vm.setEnv("TENDERLY_GAS", "");
}

/// @notice Useful function to tell if a task is nested or not based on the task config.
Expand Down
1 change: 1 addition & 0 deletions src/tasks/eth/022-U16a-opcm-upgrade-v410-base/.env
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
TENDERLY_GAS=15000000
FORK_BLOCK_NUMBER=23491327
36 changes: 18 additions & 18 deletions src/tasks/eth/022-U16a-opcm-upgrade-v410-base/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ cd superchain-ops
git pull
```

## Step 3. Install & Configure Mise
## Step 3. Install & Configure Mise

Install Mise by executing the following commands. When the Bash script runs, follow the instructions in the log output to activate mise in your shell.

Expand Down Expand Up @@ -57,12 +57,12 @@ Base has a doubly-nested safe architecture which is supported by superchain-ops.
```bash
#
# ┌─────────────────────────────────────────────┐ ┌─────────────────────────────────────────────┐ ┌─────────────────────────────────────────────┐
# │ Base Council │ │ Base Operations │ │ Foundation Operations (FOS) │
# │ Base Council │ │ Base Operations │ │ Foundation Operations (FOS) │
# │ (7 of 10) │ │ (3 of 6) │ │ (5 of 7) │
# │ 0x20AcF55A3DCfe07fC4cecaCFa1628F788EC8A4Dd │ │ 0x9C4a57Feb77e294Fd7BF5EBE9AB01CAA0a90A110 │ │ 0x9BA6e03D8B90dE867373Db8cF1A58d2F7F006b3A │
# └─────────────────────┬───────────────────────┘ └─────────────────────┬───────────────────────┘ └─────────────────────┬───────────────────────┘
# │ │ │
# └─────────────────┬───────────────────────────────────┘ │
# └─────────────────┬───────────────────────────────────┘ │
# ▼ │
# ┌─────────────────────────────────────────────┐ │
# │ Base Nested │ │
Expand All @@ -87,48 +87,48 @@ First, simulate the upgrade transaction using the command below corresponding to
cd tasks/eth/022-U16a-opcm-upgrade-v410-base

# Base Council: 0x20AcF55A3DCfe07fC4cecaCFa1628F788EC8A4Dd
# ┌────────────────────┐
# ┌────────────────────┐
# │ Child Safe Depth 2 │
# │ 'base-council' │
# └────────────────────┘
# │
# └────────────────────┘
# │
# └─────────────────┬
# ▼
# ▼
# ┌────────────────────┐
# │ Child Safe Depth 1 │
# │ 'base-nested' │
# └────────────────────┘
# │
# │
# └──────────┬
# ▼
# ┌─────────────────┐
# │ ProxyAdminOwner │
# └─────────────────┘
SIMULATE_WITHOUT_LEDGER=1 just --dotenv-path $(pwd)/.env simulate base-nested base-council
SIMULATE_WITHOUT_LEDGER=1 SKIP_DECODE_AND_PRINT=1 just --dotenv-path $(pwd)/.env simulate base-nested base-council
# Expected Hashes
# Domain Hash: 0x1fbfdc61ceb715f63cb17c56922b88c3a980f1d83873df2b9325a579753e8aa3
# Message Hash: 0x520aeeb85997f9db884ae07d1da74b5251550f49ab662b9ada3fa34572ece772
# Normalized Hash: 0x1040a2a57a0fc30a1ff18d3c0e35898dbf98c89dc172945b99a0f3b65508c659

# Base Operations: 0x9C4a57Feb77e294Fd7BF5EBE9AB01CAA0a90A110
# ┌────────────────────┐
# ┌────────────────────┐
# │ Child Safe Depth 2 │
# │ 'base-operations' │
# └────────────────────┘
# │
# └────────────────────┘
# │
# └─────────────────┬
# ▼
# ▼
# ┌────────────────────┐
# │ Child Safe Depth 1 │
# │ 'base-nested' │
# └────────────────────┘
# │
# │
# └──────────┬
# ▼
# ┌─────────────────┐
# │ ProxyAdminOwner │
# └─────────────────┘
SIMULATE_WITHOUT_LEDGER=1 just --dotenv-path $(pwd)/.env simulate base-nested base-operations
SIMULATE_WITHOUT_LEDGER=1 SKIP_DECODE_AND_PRINT=1 just --dotenv-path $(pwd)/.env simulate base-nested base-operations
# Expected Hashes
# Domain Hash: 0xfb308368b8deca582e84a807d31c1bfcec6fda754061e2801b4d6be5cb52a8ac
# Message Hash: 0x5ae6e3b8fe66bd6cbe5fae6374222b43a874c13ca850745926ecc430cafdb21a
Expand All @@ -140,13 +140,13 @@ SIMULATE_WITHOUT_LEDGER=1 just --dotenv-path $(pwd)/.env simulate base-nested ba
# │ Child Safe Depth 1 │
# │ 'FOS' │
# └────────────────────┘
# │
# │
# └──────────┬
# ▼
# ┌─────────────────┐
# │ ProxyAdminOwner │
# └─────────────────┘
SIMULATE_WITHOUT_LEDGER=1 just --dotenv-path $(pwd)/.env simulate foundation-operations
SIMULATE_WITHOUT_LEDGER=1 SKIP_DECODE_AND_PRINT=1 just --dotenv-path $(pwd)/.env simulate foundation-operations
# Expected Hashes
# Domain Hash: 0x4e6a6554de0308f5ece8ff736beed8a1b876d16f5c27cac8e466d7de0c703890
# Message Hash: 0x2b7f17c0100e6766aaac289acba0122860a51bdd64810626948b0f986f88efa5
Expand Down Expand Up @@ -217,7 +217,7 @@ Now, perform the signing for whichever of the safes you are a member of:
```bash
cd src/tasks/eth/022-U16a-opcm-upgrade-v410-base

just --dotenv-path $(pwd)/.env sign base-nested base-council
just --dotenv-path $(pwd)/.env sign base-nested base-council
# Expected Hashes
# Domain Hash: 0x1fbfdc61ceb715f63cb17c56922b88c3a980f1d83873df2b9325a579753e8aa3
# Message Hash: 0x520aeeb85997f9db884ae07d1da74b5251550f49ab662b9ada3fa34572ece772
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
TENDERLY_GAS=32000000
FORK_BLOCK_NUMBER=23491327
Loading