You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on May 29, 2024. It is now read-only.
A heuristic should exist that monitors for discrepancies between the locked ETH amount on the L1 OptimismPortal and the unlocked amount on L2. This allows for deep introspection into the safety of the native bridge and allows chain operators to detect real-time anomalies.
Consideration(s)
ETH can be burnt arbitrarily on L2 by either sending it to the 0x000 blackhole address or immobilizing it via SELFDESTRUCT operations that specify the calling contract as the beneficiary. This could result in potential discrepancies between the circulating supply on L2 and the locked supply on L1. Burns can also be trigged by anyone on the L2ToL1MessagePasser contract to delete initiated withdrawal funds.
This implementation requires having access to all historical L1/L2 bridge events from genesis of the L2 chain (first L2 block, first deposit transaction block on L1). Unfortunately, Pessimism has no way to persist this data nor does it have efficient backfilling capabilities. Integrating with the OP Indexer is required for seamless unblocking.
There are a few ways to calculate variations of the l1 supply: prospective - Compute using initialized withdrawals from L2 Intermittent - Compute using proven withdrawals on L1 literal - Compute using accredited withdrawals on L1
Each of these can be subtracted by either the deposit sum or the OptimismPortal contract ETH value to represent an L1 supply.
Pseudocode
The following pseudocode demonstrates a high level implementation for how to compute different native bridge supplies on both L1 and L2. Additionally, it showcases a lightweight heuristic analysis example.
# Get L1 deposit supply by traversing all op_portal deposit eventsdefget_l1_deposit_supply() ->int:
deposit_events=get_deposit_events(op_portal)
# We use mint as it indicates funds being introduced to L2 circulationreturnsum([ eforevent.mintindeposit_events])
# Get L2 deposit supply via summating all deposit tx type valuesdefget_l2_deposit_supply() ->int:
all_deposits=get_deposit_txs()
deposit_sum=sum([efore.mintinall_deposits])
returndeposit_sumdefget_l2_withdrawal_supply() ->int:
initiated_withdrawals=get_initiated_withdrawals()
amt=0forwithdrawalininitiated_withdrawals:
amt+=withdrawal.valuereturnamt# Get L1 withdrawal supply via iterating through proven_withdrawals# on L1 and finding the associated message event on L1 that holds the# the ETH value, summate when founddefget_l1_withdrawal_supply() ->int:
proven_withdrawals=get_l1_proven_withdrawals()
amt=0forwithdrawalinproven_withdrawals:
amt+=withdrawal.valuereturnamt# Gets the total amount of ETH burnt via the L2ToL1MessagePasser on L2 defget_l2_burn_supply(message_passer) ->int:
amt=0burns=get_burn_events(message_passer)
foreventinburns:
amt+=event.value# lets assume any ETH locked in the contract will inevitably be burntamt+=message_passer.value()
returnamt# Compute L1 supply by subtracting the amount burnt from the total amount deposited# Note - there will be a slight discrepancy given that the l2_withdrawal_supply will likely# have withdrawals that haven't been accredited/proven on L1 yetprospective_l1_supply=get_l1_deposit_supply() -get_l2_withdrawal_supply()
# Compute L1 supply by subtracting the amount in proven withdrawals from the total amount# Note - This will require correlating a withdrawal hash on L1 to a sentMessage on L2l1_supply_waiting=get_l1_deposit_supply() -get_l1_proven_withdrawal_amount()
# Get the actual L1 supply by getting the ETH amount for the op_portalactual_l1_supply=optimism_portal.balance()
# Compute L2 supply by subtracting the amount deposited from the amount burnt# by the L2ToL1MessagePasser contractl2_supply=get_l2_deposit_supply() -get_l2_burn_supply()
## Run invariant analysis# NOTE - Assume x is a set of user defined float inputs per each invariant# I0 ifpercent_diff(actual_l1_supply, l1_supply_waiting) >x0:
ALERT()
#I1ifpercent_diff(actual_l1_supply, prospective_l1_supply) >x1:
ALERT()
#I2ifpercent_diff(prospective_l1_supply, l2_supply) >x2:
ALERT()
Heuristic Description
A heuristic should exist that monitors for discrepancies between the locked ETH amount on the L1
OptimismPortaland the unlocked amount on L2. This allows for deep introspection into the safety of the native bridge and allows chain operators to detect real-time anomalies.Consideration(s)
0x000blackhole address or immobilizing it viaSELFDESTRUCToperations that specify the calling contract as the beneficiary. This could result in potential discrepancies between the circulating supply on L2 and the locked supply on L1. Burns can also be trigged by anyone on theL2ToL1MessagePassercontract to delete initiated withdrawal funds.There are a few ways to calculate variations of the l1 supply:
prospective - Compute using initialized withdrawals from L2
Intermittent - Compute using proven withdrawals on L1
literal - Compute using accredited withdrawals on L1
Each of these can be subtracted by either the deposit sum or the OptimismPortal contract ETH value to represent an L1 supply.
Pseudocode
The following pseudocode demonstrates a high level implementation for how to compute different native bridge supplies on both L1 and L2. Additionally, it showcases a lightweight heuristic analysis example.