From a68d90014909ee2e9eace4831f815c8c1d0ebd21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= <93934272+Stefan-Ethernal@users.noreply.github.com> Date: Fri, 20 Sep 2024 21:22:00 +0200 Subject: [PATCH] test: Custom native gas token transfer E2E test (#79) --- test/access-list-e2e.bats | 33 ++--- test/basic-e2e.bats | 15 +- test/bridge-e2e.bats | 143 ++++++++++++++------ test/helpers/common-setup.bash | 17 ++- test/helpers/common.bash | 111 +++++++++++---- test/helpers/lxly-bridge-test.bash | 46 +++++-- test/scripts/env.sh | 5 +- test/scripts/kurtosis_prepare_params_yml.sh | 1 + 8 files changed, 255 insertions(+), 116 deletions(-) diff --git a/test/access-list-e2e.bats b/test/access-list-e2e.bats index c47b004a..cdcccc6a 100644 --- a/test/access-list-e2e.bats +++ b/test/access-list-e2e.bats @@ -3,14 +3,11 @@ setup() { load 'helpers/common' _common_setup - readonly enclave=${ENCLAVE:-cdk-v1} - readonly sequencer=${KURTOSIS_NODE:-cdk-erigon-sequencer-001} - readonly node=${KURTOSIS_NODE:-cdk-erigon-node-001} - readonly rpc_url=${RPC_URL:-$(kurtosis port print "$enclave" "$node" http-rpc)} + readonly erigon_sequencer_node=${KURTOSIS_ERIGON_SEQUENCER:-cdk-erigon-sequencer-001} + readonly kurtosis_sequencer_wrapper=${KURTOSIS_SEQUENCER_WRAPPER:-"kurtosis service exec $enclave $erigon_sequencer_node"} readonly key=${SENDER_key:-"12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625"} readonly receiver=${RECEIVER:-"0x85dA99c8a7C2C95964c8EfD687E95E632Fc533D6"} readonly data_dir=${ACL_DATA_DIR:-"/home/erigon/data/dynamic-kurtosis-sequencer/txpool/acls"} - readonly kurtosis_sequencer_wrapper=${KURTOSIS_WRAPPER:-"kurtosis service exec $enclave $sequencer"} } teardown() { @@ -36,7 +33,7 @@ set_acl_mode() { @test "Test Block List - Sending regular transaction when address not in block list" { local value="10ether" run set_acl_mode "blocklist" - run sendTx $key $receiver $value + run sendTx $l2_rpc_url $key $receiver $value assert_success assert_output --regexp "Transaction successful \(transaction hash: 0x[a-fA-F0-9]{64}\)" @@ -45,7 +42,7 @@ set_acl_mode() { @test "Test Block List - Sending contracts deploy transaction when address not in block list" { local contract_artifact="./contracts/erc20mock/ERC20Mock.json" run set_acl_mode "blocklist" - run deployContract $key $contract_artifact + run deployContract $l2_rpc_url $key $contract_artifact assert_success @@ -59,7 +56,7 @@ set_acl_mode() { run set_acl_mode "blocklist" run add_to_access_list "blocklist" "sendTx" - run sendTx $key $receiver $value + run sendTx $l2_rpc_url $key $receiver $value assert_failure assert_output --partial "sender disallowed to send tx by ACL policy" @@ -70,7 +67,7 @@ set_acl_mode() { run set_acl_mode "blocklist" run add_to_access_list "blocklist" "deploy" - run deployContract $key $contract_artifact + run deployContract $l2_rpc_url $key $contract_artifact assert_failure assert_output --partial "sender disallowed to deploy contract by ACL policy" @@ -80,7 +77,7 @@ set_acl_mode() { local value="10ether" run set_acl_mode "allowlist" - run sendTx $key $receiver $value + run sendTx $l2_rpc_url $key $receiver $value assert_failure assert_output --partial "sender disallowed to send tx by ACL policy" @@ -90,7 +87,7 @@ set_acl_mode() { local contract_artifact="./contracts/erc20mock/ERC20Mock.json" run set_acl_mode "allowlist" - run deployContract $key $contract_artifact + run deployContract $l2_rpc_url $key $contract_artifact assert_failure assert_output --partial "sender disallowed to deploy contract by ACL policy" @@ -99,10 +96,10 @@ set_acl_mode() { @test "Test Allow List - Sending regular transaction when address is in allow list" { local value="10ether" - run set_acl_mode "allowlist" - run add_to_access_list "allowlist" "sendTx" - run sendTx $key $receiver $value - + run set_acl_mode "allowlist" + run add_to_access_list "allowlist" "sendTx" + run sendTx $l2_rpc_url $key $receiver $value + assert_success assert_output --regexp "Transaction successful \(transaction hash: 0x[a-fA-F0-9]{64}\)" } @@ -110,9 +107,9 @@ set_acl_mode() { @test "Test Allow List - Sending contracts deploy transaction when address is in allow list" { local contract_artifact="./contracts/erc20mock/ERC20Mock.json" - run set_acl_mode "allowlist" - run add_to_access_list "allowlist" "deploy" - run deployContract $key $contract_artifact + run set_acl_mode "allowlist" + run add_to_access_list "allowlist" "deploy" + run deployContract $l2_rpc_url $key $contract_artifact assert_success diff --git a/test/basic-e2e.bats b/test/basic-e2e.bats index 7124dcc2..a3fb4982 100644 --- a/test/basic-e2e.bats +++ b/test/basic-e2e.bats @@ -3,10 +3,7 @@ setup() { load 'helpers/common' _common_setup - readonly enclave=${ENCLAVE:-cdk-v1} - readonly node=${KURTOSIS_NODE:-cdk-erigon-node-001} - readonly rpc_url=${RPC_URL:-$(kurtosis port print "$enclave" "$node" http-rpc)} - readonly private_key=${SENDER_PRIVATE_KEY:-"12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625"} + readonly sender_private_key=${SENDER_PRIVATE_KEY:-"12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625"} readonly receiver=${RECEIVER:-"0x85dA99c8a7C2C95964c8EfD687E95E632Fc533D6"} } @@ -16,7 +13,7 @@ setup() { local value="10ether" # case 1: Transaction successful sender has sufficient balance - run sendTx "$private_key" "$receiver" "$value" + run sendTx "$l2_rpc_url" "$sender_private_key" "$receiver" "$value" assert_success assert_output --regexp "Transaction successful \(transaction hash: 0x[a-fA-F0-9]{64}\)" @@ -37,21 +34,19 @@ setup() { local contract_artifact="./contracts/erc20mock/ERC20Mock.json" # Deploy ERC20Mock - run deployContract "$private_key" "$contract_artifact" + run deployContract "$l2_rpc_url" "$sender_private_key" "$contract_artifact" assert_success contract_addr=$(echo "$output" | tail -n 1) # Mint ERC20 tokens - local mintFnSig="function mint(address receiver, uint256 amount)" local amount="5" - run sendTx "$private_key" "$contract_addr" "$mintFnSig" "$receiver" "$amount" + run sendTx "$l2_rpc_url" "$sender_private_key" "$contract_addr" "$mint_fn_sig" "$receiver" "$amount" assert_success assert_output --regexp "Transaction successful \(transaction hash: 0x[a-fA-F0-9]{64}\)" # Assert that balance is correct - local balanceOfFnSig="function balanceOf(address) (uint256)" - run queryContract "$contract_addr" "$balanceOfFnSig" "$receiver" + run queryContract "$l2_rpc_url" "$contract_addr" "$balance_of_fn_sig" "$receiver" assert_success receiverBalance=$(echo "$output" | tail -n 1) diff --git a/test/bridge-e2e.bats b/test/bridge-e2e.bats index 98443b3b..c392e647 100644 --- a/test/bridge-e2e.bats +++ b/test/bridge-e2e.bats @@ -1,43 +1,45 @@ setup() { load 'helpers/common-setup' _common_setup + load 'helpers/common' + load 'helpers/lxly-bridge-test' readonly data_availability_mode=${DATA_AVAILABILITY_MODE:-"cdk-validium"} $PROJECT_ROOT/test/scripts/kurtosis_prepare_params_yml.sh ../kurtosis-cdk $data_availability_mode [ $? -ne 0 ] && echo "Error preparing params.yml" && exit 1 - # Check if the genesis file is already downloaded - if [ ! -f "./tmp/cdk/genesis/genesis.json" ]; then - mkdir -p ./tmp/cdk - kurtosis files download cdk-v1 genesis ./tmp/cdk/genesis - [ $? -ne 0 ] && echo "Error downloading genesis file" && exit 1 + if [ -z "$BRIDGE_ADDRESS" ]; then + local combined_json_file="/opt/zkevm/combined.json" + echo "BRIDGE_ADDRESS env variable is not provided, resolving the bridge address from the Kurtosis CDK '$combined_json_file'" >&3 + + # Fetching the combined JSON output and filtering to get polygonZkEVMBridgeAddress + combined_json_output=$($contracts_service_wrapper "cat $combined_json_file" | tail -n +2) + bridge_default_address=$(echo "$combined_json_output" | jq -r .polygonZkEVMBridgeAddress) + BRIDGE_ADDRESS=$bridge_default_address fi - # Download the genesis file - readonly bridge_default_address=$(jq -r ".genesis[] | select(.contractName == \"PolygonZkEVMBridge proxy\") | .address" ./tmp/cdk/genesis/genesis.json) - - readonly skey=${SENDER_PRIVATE_KEY:-"12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625"} - readonly destination_net=${DESTINATION_NET:-"1"} - readonly destination_addr=${DESTINATION_ADDRESS:-"0x0bb7AA0b4FdC2D2862c088424260e99ed6299148"} - readonly ether_value=${ETHER_VALUE:-"0.0200000054"} - readonly token_addr=${TOKEN_ADDRESS:-"0x0000000000000000000000000000000000000000"} + + echo "Bridge address=$BRIDGE_ADDRESS" >&3 + + readonly sender_private_key=${SENDER_PRIVATE_KEY:-"12d7de8621a77640c9241b2595ba78ce443d05e94090365ab3bb5e19df82c625"} + destination_net=${DESTINATION_NET:-"1"} + destination_addr=${DESTINATION_ADDRESS:-"0x0bb7AA0b4FdC2D2862c088424260e99ed6299148"} + ether_value=${ETHER_VALUE:-"0.0200000054"} + amount=$(cast to-wei $ether_value ether) + token_addr=${TOKEN_ADDRESS:-"0x0000000000000000000000000000000000000000"} readonly is_forced=${IS_FORCED:-"true"} - readonly bridge_addr=${BRIDGE_ADDRESS:-$bridge_default_address} + readonly bridge_addr=$BRIDGE_ADDRESS readonly meta_bytes=${META_BYTES:-"0x"} - readonly l1_rpc_url=${L1_ETH_RPC_URL:-"$(kurtosis port print cdk-v1 el-1-geth-lighthouse rpc)"} - readonly l2_rpc_url=${L2_ETH_RPC_URL:-"$(kurtosis port print cdk-v1 cdk-erigon-node-001 http-rpc)"} - readonly bridge_api_url=${BRIDGE_API_URL:-"$(kurtosis port print cdk-v1 zkevm-bridge-service-001 rpc)"} + readonly l1_rpc_url=${L1_ETH_RPC_URL:-"$(kurtosis port print $enclave el-1-geth-lighthouse rpc)"} + readonly bridge_api_url=${BRIDGE_API_URL:-"$(kurtosis port print $enclave zkevm-bridge-service-001 rpc)"} readonly dry_run=${DRY_RUN:-"false"} - - readonly amount=$(cast to-wei $ether_value ether) - readonly current_addr="$(cast wallet address --private-key $skey)" - readonly l1_rpc_network_id=$(cast call --rpc-url $l1_rpc_url $bridge_addr 'networkID()(uint32)') - readonly l2_rpc_network_id=$(cast call --rpc-url $l2_rpc_url $bridge_addr 'networkID()(uint32)') + readonly sender_addr="$(cast wallet address --private-key $sender_private_key)" + readonly l1_rpc_network_id=$(cast call --rpc-url $l1_rpc_url $bridge_addr 'networkID() (uint32)') + readonly l2_rpc_network_id=$(cast call --rpc-url $l2_rpc_url $bridge_addr 'networkID() (uint32)') } @test "Run deposit" { - load 'helpers/lxly-bridge-test' echo "Running LxLy deposit" >&3 run deposit assert_success @@ -45,27 +47,82 @@ setup() { } @test "Run claim" { - load 'helpers/lxly-bridge-test' - echo "Running LxLy claim" + echo "Running LxLy claim" >&3 - # The script timeout (in seconds). timeout="120" - start_time=$(date +%s) - end_time=$((start_time + timeout)) - - while true; do - current_time=$(date +%s) - if ((current_time > end_time)); then - echo "[$(date '+%Y-%m-%d %H:%M:%S')] ❌ Exiting... Timeout reached!" - exit 1 - fi - - run claim - if [ $status -eq 0 ]; then - break - fi - sleep 10 - done - + claim_frequency="10" + run wait_for_claim "$timeout" "$claim_frequency" + assert_success +} + +@test "Custom native token transfer" { + # Use GAS_TOKEN_ADDR if provided, otherwise retrieve from file + if [[ -n "$GAS_TOKEN_ADDR" ]]; then + echo "Using provided GAS_TOKEN_ADDR: $GAS_TOKEN_ADDR" >&3 + local gas_token_addr="$GAS_TOKEN_ADDR" + else + echo "GAS_TOKEN_ADDR not provided, retrieving from rollup parameters file." >&3 + readonly rollup_params_file=/opt/zkevm/create_rollup_parameters.json + run bash -c "$contracts_service_wrapper 'cat $rollup_params_file' | tail -n +2 | jq -r '.gasTokenAddress'" + assert_success + assert_output --regexp "0x[a-fA-F0-9]{40}" + local gas_token_addr=$output + fi + + echo "Gas token addr $gas_token_addr, L1 RPC: $l1_rpc_url" >&3 + + # Set receiver address and query for its initial native token balance on the L2 + receiver=${RECEIVER:-"0x85dA99c8a7C2C95964c8EfD687E95E632Fc533D6"} + local initial_receiver_balance=$(cast balance --ether "$receiver" --rpc-url "$l2_rpc_url") + echo "Initial receiver balance of native token on L2 $initial_receiver_balance" >&3 + + # Query for initial sender balance + run queryContract "$l1_rpc_url" "$gas_token_addr" "$balance_of_fn_sig" "$sender_addr" + assert_success + local gas_token_init_sender_balance=$(echo "$output" | tail -n 1 | awk '{print $1}') + echo "Initial sender balance $gas_token_init_sender_balance" of gas token on L1 >&3 + + # Mint gas token on L1 + local tokens_amount="0.1ether" + local wei_amount=$(cast --to-unit $tokens_amount wei) + local minter_key=${MINTER_KEY:-"42b6e34dc21598a807dc19d7784c71b2a7a01f6480dc6f58258f78e539f1a1fa"} + run mint_erc20_tokens "$l1_rpc_url" "$gas_token_addr" "$minter_key" "$sender_addr" "$tokens_amount" + assert_success + + # Assert that balance of gas token (on the L1) is correct + run queryContract "$l1_rpc_url" "$gas_token_addr" "$balance_of_fn_sig" "$sender_addr" + assert_success + local gas_token_final_sender_balance=$(echo "$output" | + tail -n 1 | + awk '{print $1}') + local expected_balance=$(echo "$gas_token_init_sender_balance + $wei_amount" | + bc | + awk '{print $1}') + + echo "Sender balance ($sender_addr) (gas token L1): $gas_token_final_sender_balance" >&3 + assert_equal "$gas_token_final_sender_balance" "$expected_balance" + + # Send approve transaction to the gas token on L1 + deposit_ether_value="0.1ether" + run sendTx "$l1_rpc_url" "$sender_private_key" "$gas_token_addr" "$approve_fn_sig" "$bridge_addr" "$deposit_ether_value" + assert_success + assert_output --regexp "Transaction successful \(transaction hash: 0x[a-fA-F0-9]{64}\)" + + # Deposit + token_addr=$gas_token_addr + destination_addr=$receiver + destination_net=$l2_rpc_network_id + amount=$wei_amount + run deposit + assert_success + + # Claim deposits (settle them on the L2) + timeout="120" + claim_frequency="10" + run wait_for_claim "$timeout" "$claim_frequency" + assert_success + + # Validate that the native token of receiver on L2 has increased by the bridge tokens amount + run verify_native_token_balance "$l2_rpc_url" "$receiver" "$initial_receiver_balance" "$tokens_amount" assert_success } diff --git a/test/helpers/common-setup.bash b/test/helpers/common-setup.bash index b7691366..7cb4dec7 100644 --- a/test/helpers/common-setup.bash +++ b/test/helpers/common-setup.bash @@ -3,11 +3,24 @@ _common_setup() { bats_load_library 'bats-support' bats_load_library 'bats-assert' - + # get the containing directory of this file # use $BATS_TEST_FILENAME instead of ${BASH_SOURCE[0]} or $0, # as those will point to the bats executable's location or the preprocessed file respectively - PROJECT_ROOT="$( cd "$( dirname "$BATS_TEST_FILENAME" )/.." >/dev/null 2>&1 && pwd )" + PROJECT_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." >/dev/null 2>&1 && pwd)" # make executables in src/ visible to PATH PATH="$PROJECT_ROOT/src:$PATH" + + # ERC20 contracts function signatures + readonly mint_fn_sig="function mint(address,uint256)" + readonly balance_of_fn_sig="function balanceOf(address) (uint256)" + readonly approve_fn_sig="function approve(address,uint256)" + + + # Kurtosis enclave and service identifiers + readonly enclave=${KURTOSIS_ENCLAVE:-cdk-v1} + readonly contracts_container=${KURTOSIS_CONTRACTS:-contracts-001} + readonly contracts_service_wrapper=${KURTOSIS_CONTRACTS_WRAPPER:-"kurtosis service exec $enclave $contracts_container"} + readonly erigon_rpc_node=${KURTOSIS_ERIGON_RPC:-cdk-erigon-node-001} + readonly l2_rpc_url=${L2_ETH_RPC_URL:-"$(kurtosis port print $enclave $erigon_rpc_node http-rpc)"} } diff --git a/test/helpers/common.bash b/test/helpers/common.bash index aabae0b6..4857a677 100644 --- a/test/helpers/common.bash +++ b/test/helpers/common.bash @@ -1,12 +1,13 @@ #!/usr/bin/env bash function deployContract() { - local private_key="$1" - local contract_artifact="$2" + local rpc_url="$1" + local private_key="$2" + local contract_artifact="$3" # Check if rpc_url is available if [[ -z "$rpc_url" ]]; then - echo "Error: rpc_url environment variable is not set." + echo "Error: rpc_url parameter is not set." return 1 fi @@ -16,13 +17,13 @@ function deployContract() { fi # Get the sender address - local sender_addr=$(cast wallet address "$private_key") + local sender=$(cast wallet address "$private_key") if [[ $? -ne 0 ]]; then echo "Error: Failed to retrieve sender address." return 1 fi - echo "Attempting to deploy contract artifact '$contract_artifact' to $rpc_url (sender: $sender_addr)" >&3 + echo "Attempting to deploy contract artifact '$contract_artifact' to $rpc_url (sender: $sender)" >&3 # Get bytecode from the contract artifact local bytecode=$(jq -r .bytecode "$contract_artifact") @@ -70,15 +71,16 @@ function deployContract() { } function sendTx() { - # Check if at least 3 arguments are provided - if [[ $# -lt 3 ]]; then - echo "Usage: sendTx [ ...]" + # Check if at least 4 arguments are provided + if [[ $# -lt 4 ]]; then + echo "Usage: sendTx [ ...]" return 1 fi - local private_key="$1" # Sender private key - local receiver_addr="$2" # Receiver address - local value_or_function_sig="$3" # Value or function signature + local rpc_url="$1" # RPC URL + local private_key="$2" # Sender private key + local receiver_addr="$3" # Receiver address + local value_or_function_sig="$4" # Value or function signature # Error handling: Ensure the receiver is a valid Ethereum address if [[ ! "$receiver_addr" =~ ^0x[a-fA-F0-9]{40}$ ]]; then @@ -86,28 +88,28 @@ function sendTx() { return 1 fi - shift 3 # Shift the first 3 arguments (private_key, receiver_addr, value_or_function_sig) + shift 4 # Shift the first 4 arguments (rpc_url, private_key, receiver_addr, value_or_function_sig) local params=("$@") # Collect all remaining arguments as function parameters # Get sender address from private key - local sender_addr - sender_addr=$(cast wallet address "$private_key") || { + local sender + sender=$(cast wallet address "$private_key") || { echo "Error: Failed to extract the sender address." return 1 } # Get initial ether balances of sender and receiver local sender_initial_balance receiver_initial_balance - sender_initial_balance=$(cast balance "$sender_addr" --ether --rpc-url "$rpc_url") || return 1 + sender_initial_balance=$(cast balance "$sender" --ether --rpc-url "$rpc_url") || return 1 receiver_initial_balance=$(cast balance "$receiver_addr" --ether --rpc-url "$rpc_url") || return 1 # Check if the value_or_function_sig is a numeric value (Ether to be transferred) if [[ "$value_or_function_sig" =~ ^[0-9]+(\.[0-9]+)?(ether)?$ ]]; then # Case: Ether transfer (EOA transaction) - send_eoa_transaction "$private_key" "$receiver_addr" "$value_or_function_sig" "$sender_addr" "$sender_initial_balance" "$receiver_initial_balance" + send_eoa_transaction "$private_key" "$receiver_addr" "$value_or_function_sig" "$sender" "$sender_initial_balance" "$receiver_initial_balance" else # Case: Smart contract interaction (contract interaction with function signature and parameters) - send_smart_contract_transaction "$private_key" "$receiver_addr" "$value_or_function_sig" "$sender_addr" "${params[@]}" + send_smart_contract_transaction "$private_key" "$receiver_addr" "$value_or_function_sig" "$sender" "${params[@]}" fi } @@ -115,7 +117,7 @@ function send_eoa_transaction() { local private_key="$1" local receiver_addr="$2" local value="$3" - local sender_addr="$4" + local sender="$4" local sender_initial_balance="$5" local receiver_initial_balance="$6" @@ -136,7 +138,7 @@ function send_eoa_transaction() { return 1 } - checkBalances "$sender_addr" "$receiver_addr" "$value" "$tx_hash" "$sender_initial_balance" "$receiver_initial_balance" + check_balances "$sender" "$receiver_addr" "$value" "$tx_hash" "$sender_initial_balance" "$receiver_initial_balance" if [[ $? -ne 0 ]]; then echo "Error: Balance not updated correctly." return 1 @@ -149,7 +151,7 @@ function send_smart_contract_transaction() { local private_key="$1" local receiver_addr="$2" local function_sig="$3" - local sender_addr="$4" + local sender="$4" shift 4 local params=("$@") @@ -185,16 +187,17 @@ function extract_tx_hash() { } function queryContract() { - local addr="$1" # Contract address - local funcSignature="$2" # Function signature - shift 2 # Shift past the first two arguments + local rpc_url="$1" # RPC URL + local addr="$2" # Contract address + local funcSignature="$3" # Function signature + shift 3 # Shift past the first 3 arguments local params=("$@") # Collect remaining arguments as parameters array echo "Querying state of $addr account (RPC URL: $rpc_url) with function signature: '$funcSignature' and params: ${params[*]}" >&3 - # Check if rpc_url is available + # Check if rpc url is available if [[ -z "$rpc_url" ]]; then - echo "Error: rpc_url environment variable is not set." + echo "Error: rpc_url parameter is not provided." return 1 fi @@ -221,7 +224,7 @@ function queryContract() { return 0 } -function checkBalances() { +function check_balances() { local sender="$1" local receiver="$2" local amount="$3" @@ -247,8 +250,9 @@ function checkBalances() { fi local sender_final_balance=$(cast balance "$sender" --ether --rpc-url "$rpc_url") || return 1 - local gas_used=$(cast tx "$tx_hash" --rpc-url "$rpc_url" | grep '^gas ' | awk '{print $2}') - local gas_price=$(cast tx "$tx_hash" --rpc-url "$rpc_url" | grep '^gasPrice' | awk '{print $2}') + local tx_output=$(cast tx "$tx_hash" --rpc-url "$rpc_url") + local gas_used=$(tx_output | grep '^gas ' | awk '{print $2}') + local gas_price=$(tx_output | grep '^gasPrice' | awk '{print $2}') local gas_fee=$(echo "$gas_used * $gas_price" | bc) local gas_fee_in_ether=$(cast to-unit "$gas_fee" ether) @@ -275,3 +279,54 @@ function checkBalances() { return 1 fi } + +function verify_native_token_balance() { + local rpc_url="$1" # RPC URL + local account="$2" # account address + local initial_balance="$3" # initial balance in Ether (decimal) + local ether_amount="$4" # amount to be added (in Ether, decimal) + + # Convert initial balance and amount to wei (no decimals) + local initial_balance_wei=$(cast --to-wei "$initial_balance") + + # Trim 'ether' from ether_amount if it exists + ether_amount=$(echo "$ether_amount" | sed 's/ether//') + local amount_wei=$(cast --to-wei "$ether_amount") + + # Get final balance in wei (after the operation) + local final_balance_wei=$(cast balance "$account" --rpc-url "$rpc_url" | awk '{print $1}') + + # Calculate expected final balance (initial_balance + amount) + local expected_final_balance_wei=$(echo "$initial_balance_wei + $amount_wei" | bc) + + # Check if final_balance matches the expected final balance + if [ "$(echo "$final_balance_wei == $expected_final_balance_wei" | bc)" -eq 1 ]; then + echo "✅ Balance verification successful: final balance is correct." + else + echo "❌ Balance verification failed: expected $expected_final_balance_wei but got $final_balance_wei." + exit 1 + fi +} + +function mint_erc20_tokens() { + local rpc_url="$1" # The L1 RPC URL + local erc20_token_addr="$2" # The gas token contract address + local minter_private_key="$3" # The minter private key + local receiver="$4" # The receiver address (for minted tokens) + local tokens_amount="$5" # The amount of tokens to transfer (e.g., "0.1ether") + + # Query the erc20 token balance of the sender + run queryContract "$rpc_url" "$erc20_token_addr" "$balance_of_fn_sig" "$sender_addr" + assert_success + local erc20_token_balance=$(echo "$output" | tail -n 1) + + # Log the account's current gas token balance + echo "Initial account balance: $erc20_token_balance wei" >&3 + + # Convert tokens_amount to Wei for comparison + local wei_amount=$(cast --to-unit "$tokens_amount" wei) + + # Mint the required tokens by sending a transaction + run sendTx "$rpc_url" "$minter_private_key" "$erc20_token_addr" "$mint_fn_sig" "$receiver" "$tokens_amount" + assert_success +} diff --git a/test/helpers/lxly-bridge-test.bash b/test/helpers/lxly-bridge-test.bash index bbaf45e1..c1b43533 100644 --- a/test/helpers/lxly-bridge-test.bash +++ b/test/helpers/lxly-bridge-test.bash @@ -1,25 +1,26 @@ #!/usr/bin/env bash # Error code reference https://hackmd.io/WwahVBZERJKdfK3BbKxzQQ -function deposit () { +function deposit() { readonly deposit_sig='bridgeAsset(uint32,address,uint256,address,bool,bytes)' if [[ $token_addr == "0x0000000000000000000000000000000000000000" ]]; then - echo "Checking the current ETH balance: " >&3 - cast balance -e --rpc-url $l1_rpc_url $current_addr >&3 + echo "The ETH balance for sender "$sender_addr":" >&3 + cast balance -e --rpc-url $l1_rpc_url $sender_addr >&3 else - echo "Checking the current token balance for token at $token_addr: " >&3 - cast call --rpc-url $l1_rpc_url $token_addr 'balanceOf(address)(uint256)' $current_addr >&3 + echo "The "$token_addr" token balance for sender "$sender_addr":" >&3 + balance_wei=$(cast call --rpc-url "$l1_rpc_url" "$token_addr" "$balance_of_fn_sig" "$sender_addr") + echo "$(cast --from-wei "$balance_wei")" >&3 fi - echo "Attempting to deposit $amount wei to net $destination_net for token $token_addr" >&3 + echo "Attempting to deposit $amount [wei] to $destination_addr, token $token_addr (sender=$sender_addr, network id=$destination_net, rpc url=$l1_rpc_url)" >&3 if [[ $dry_run == "true" ]]; then cast calldata $deposit_sig $destination_net $destination_addr $amount $token_addr $is_forced $meta_bytes else if [[ $token_addr == "0x0000000000000000000000000000000000000000" ]]; then - cast send --legacy --private-key $skey --value $amount --rpc-url $l1_rpc_url $bridge_addr $deposit_sig $destination_net $destination_addr $amount $token_addr $is_forced $meta_bytes + cast send --legacy --private-key $sender_private_key --value $amount --rpc-url $l1_rpc_url $bridge_addr $deposit_sig $destination_net $destination_addr $amount $token_addr $is_forced $meta_bytes else - cast send --legacy --private-key $skey --rpc-url $l1_rpc_url $bridge_addr $deposit_sig $destination_net $destination_addr $amount $token_addr $is_forced $meta_bytes + cast send --legacy --private-key $sender_private_key --rpc-url $l1_rpc_url $bridge_addr $deposit_sig $destination_net $destination_addr $amount $token_addr $is_forced $meta_bytes fi fi } @@ -30,7 +31,7 @@ function claim() { readonly claimable_deposit_file=$(mktemp) echo "Getting full list of deposits" >&3 curl -s "$bridge_api_url/bridges/$destination_addr?limit=100&offset=0" | jq '.' | tee $bridge_deposit_file - + echo "Looking for claimable deposits" >&3 jq '[.deposits[] | select(.ready_for_claim == true and .claim_tx_hash == "" and .dest_net == '$destination_net')]' $bridge_deposit_file | tee $claimable_deposit_file readonly claimable_count=$(jq '. | length' $claimable_deposit_file) @@ -40,7 +41,7 @@ function claim() { echo "We have no claimable deposits at this time" >&3 exit 1 fi - + echo "We have $claimable_count claimable deposits on network $destination_net. Let's get this party started." >&3 readonly current_deposit=$(mktemp) readonly current_proof=$(mktemp) @@ -69,9 +70,30 @@ function claim() { cast calldata $claim_sig "$in_merkle_proof" "$in_rollup_merkle_proof" $in_global_index $in_main_exit_root $in_rollup_exit_root $in_orig_net $in_orig_addr $in_dest_net $in_dest_addr $in_amount $in_metadata cast call --rpc-url $l2_rpc_url $bridge_addr $claim_sig "$in_merkle_proof" "$in_rollup_merkle_proof" $in_global_index $in_main_exit_root $in_rollup_exit_root $in_orig_net $in_orig_addr $in_dest_net $in_dest_addr $in_amount $in_metadata else - cast send --legacy --rpc-url $l2_rpc_url --private-key $skey $bridge_addr $claim_sig "$in_merkle_proof" "$in_rollup_merkle_proof" $in_global_index $in_main_exit_root $in_rollup_exit_root $in_orig_net $in_orig_addr $in_dest_net $in_dest_addr $in_amount $in_metadata + cast send --legacy --rpc-url $l2_rpc_url --private-key $sender_private_key $bridge_addr $claim_sig "$in_merkle_proof" "$in_rollup_merkle_proof" $in_global_index $in_main_exit_root $in_rollup_exit_root $in_orig_net $in_orig_addr $in_dest_net $in_dest_addr $in_amount $in_metadata + fi + + done < <(seq 0 $((claimable_count - 1))) +} + +function wait_for_claim() { + local timeout="$1" # timeout (in seconds) + local claim_frequency="$2" # claim frequency (in seconds) + local start_time=$(date +%s) + local end_time=$((start_time + timeout)) + + while true; do + local current_time=$(date +%s) + if ((current_time > end_time)); then + echo "[$(date '+%Y-%m-%d %H:%M:%S')] ❌ Exiting... Timeout reached!" + exit 1 fi + run claim + if [ $status -eq 0 ]; then + break + fi - done < <(seq 0 $((claimable_count - 1)) ) + sleep "$claim_frequency" + done } diff --git a/test/scripts/env.sh b/test/scripts/env.sh index b81c18a4..2afb2af4 100644 --- a/test/scripts/env.sh +++ b/test/scripts/env.sh @@ -1,8 +1,7 @@ #!/bin/bash ### Common variables -ENCLAVE=cdk-v1 -CDK_ERIGON_NODE_NAME=cdk-erigon-node-001 +KURTOSIS_ENCLAVE=cdk-v1 TMP_CDK_FOLDER=tmp/cdk DEST_KURTOSIS_PARAMS_YML=../$TMP_CDK_FOLDER/e2e-params.yml -KURTOSIS_VERSION=develop KURTOSIS_FOLDER=../kurtosis-cdk +USE_L1_GAS_TOKEN_CONTRACT=true diff --git a/test/scripts/kurtosis_prepare_params_yml.sh b/test/scripts/kurtosis_prepare_params_yml.sh index aa57e272..38f44d51 100755 --- a/test/scripts/kurtosis_prepare_params_yml.sh +++ b/test/scripts/kurtosis_prepare_params_yml.sh @@ -28,3 +28,4 @@ mkdir -p $(dirname $DEST_KURTOSIS_PARAMS_YML) cp $KURTOSIS_FOLDER/params.yml $DEST_KURTOSIS_PARAMS_YML yq -Y --in-place ".args.cdk_node_image = \"cdk\"" $DEST_KURTOSIS_PARAMS_YML yq -Y --in-place ".args.data_availability_mode = \"$DATA_AVAILABILITY_MODE\"" $DEST_KURTOSIS_PARAMS_YML +yq -Y --in-place ".args.zkevm_use_gas_token_contract = $USE_L1_GAS_TOKEN_CONTRACT" $DEST_KURTOSIS_PARAMS_YML