Skip to content

Commit

Permalink
Superchain Proxies (#2849)
Browse files Browse the repository at this point in the history
  • Loading branch information
ravenac95 authored Jan 22, 2025
1 parent ca28b78 commit ddaddf4
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def factory_deployments(
on=exp.EQ(
this=traces_transaction_hash, expression=transactions_transaction_hash
),
join_type="inner",
)
.where(
exp.EQ(
Expand Down
102 changes: 102 additions & 0 deletions warehouse/metrics_mesh/macros/onchain/known_proxies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from metrics_tools.utils.glot import (
coerce_to_column,
coerce_to_table,
literal_or_expression,
)
from sqlglot import expressions as exp
from sqlmesh import macro
from sqlmesh.core.macros import MacroEvaluator


@macro()
def known_proxies(
evaluator: MacroEvaluator,
start: exp.Expression,
end: exp.Expression,
traces_table: exp.ExpOrStr,
*additional_column_defs: exp.ExpOrStr,
block_timestamp_column: exp.ExpOrStr = "traces.block_timestamp",
transaction_hash_column: exp.ExpOrStr = "traces.transaction_hash",
from_address_column: exp.ExpOrStr = "traces.from_address",
to_address_column: exp.ExpOrStr = "traces.to_address",
proxy_type_column: exp.ExpOrStr = "proxies.proxy_type",
status_column: exp.ExpOrStr = "traces.status",
trace_type_column: exp.ExpOrStr = "traces.trace_type",
call_type_column: exp.ExpOrStr = "traces.call_type",
trace_type_value: exp.ExpOrStr = "call",
call_type_value: exp.ExpOrStr = "staticcall",
factory_address_column: exp.ExpOrStr = "proxies.factory_address",
proxy_contracts_table: exp.ExpOrStr = "metrics.seed_known_proxy_contracts",
):
traces = coerce_to_table(traces_table)
block_timestamp = coerce_to_column(block_timestamp_column)
transaction_hash = coerce_to_column(transaction_hash_column)
from_address = coerce_to_column(from_address_column)
to_address = coerce_to_column(to_address_column)
proxy_type = coerce_to_column(proxy_type_column)
factory_address = coerce_to_column(factory_address_column)
proxy_contracts = coerce_to_table(proxy_contracts_table)
trace_type = coerce_to_column(trace_type_column)
call_type = coerce_to_column(call_type_column)
status = coerce_to_column(status_column)
trace_type_value_exp = literal_or_expression(trace_type_value)
call_type_value_exp = literal_or_expression(call_type_value)

proxy_address = exp.Case(
ifs=[
exp.If(
this=exp.EQ(
this=exp.Lower(this=from_address),
expression=exp.Lower(this=factory_address),
),
true=from_address,
),
exp.If(
this=exp.EQ(
this=exp.Lower(this=to_address),
expression=exp.Lower(this=factory_address),
),
true=to_address,
),
],
default=exp.Null(),
)

proxies = (
exp.select(
block_timestamp.as_("block_timestamp"),
transaction_hash.as_("transaction_hash"),
from_address.as_("from_address"),
to_address.as_("to_address"),
proxy_type.as_("proxy_type"),
proxy_address.as_("proxy_address"),
*additional_column_defs,
)
.from_(traces.as_("traces"))
.join(
proxy_contracts.as_("proxies"),
on=exp.Or(
this=exp.EQ(
this=exp.Lower(this=from_address),
expression=exp.Lower(this=factory_address),
),
expression=exp.EQ(
this=exp.Lower(this=to_address),
expression=exp.Lower(this=factory_address),
),
),
join_type="inner",
)
.where(exp.EQ(this=status, expression=exp.Literal(this="1", is_string=False)))
.where(exp.EQ(this=call_type, expression=call_type_value_exp))
.where(exp.EQ(this=trace_type, expression=trace_type_value_exp))
.where(exp.NEQ(this=from_address, expression=to_address))
.where(
exp.Between(
this=block_timestamp,
low=start,
high=end,
)
)
)
return proxies
14 changes: 14 additions & 0 deletions warehouse/metrics_mesh/models/seed/seed_known_proxy_contracts.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- Purpose: Seed data for known proxy contracts. To update this data, please
-- update the CSV file at the path specified below. This can be used for any evm
-- chain.
MODEL (
name metrics.seed_known_proxy_contracts,
kind SEED (
path '../../seeds/known_proxy_contracts.csv'
),
columns (
proxy_type VARCHAR,
version VARCHAR,
factory_address VARCHAR
)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
MODEL (
name metrics.stg_superchain__proxies,
kind INCREMENTAL_BY_TIME_RANGE (
time_column block_timestamp,
batch_size 90,
batch_concurrency 1,
lookback 7
),
start '2015-01-01',
cron '@daily',
partitioned_by (DAY("block_timestamp"), "chain_id"),
grain (
block_timestamp,
chain_id,
id,
transaction_hash,
from_address,
to_address,
proxy_type,
proxy_address
)
);

@known_proxies(
@start_dt,
@end_dt,
@oso_source('bigquery.optimism_superchain_raw_onchain_data.traces'),
traces.chain_id as chain_id,
block_timestamp_column := @from_unix_timestamp(traces.block_timestamp),
)
7 changes: 7 additions & 0 deletions warehouse/metrics_mesh/seeds/known_proxy_contracts.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
proxy_type,version,factory_address
"SAFE","1.4.1","0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67"
"SAFE","1.3.0","0xC22834581EbC8527d974F8a1c97E1bEA4EF910BC"
"SAFE","1.1.1","0x76E2cFc1F5Fa8F6a5b3fC4c8F4788F0116861F9B"
"SAFE","1.0.0","0x12302fE9c02ff50939BaAaaf415fc226C078613C"
"ENTRYPOINT","0.0.7","0x0000000071727De22E5E9d8BAf0edAc6f37da032"
"ENTRYPOINT","0.0.6","0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789"
29 changes: 28 additions & 1 deletion warehouse/metrics_tools/utils/glot.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import typing as t

from sqlglot import exp
from sqlmesh.core.dialect import parse
from sqlmesh.core.dialect import parse, parse_one


def coerce_to_column(column: str | exp.Expression) -> exp.Expression:
Expand All @@ -12,6 +12,33 @@ def coerce_to_column(column: str | exp.Expression) -> exp.Expression:
raise ValueError(f"Invalid column type: {column}")


def coerce_to_table(table: str | exp.Expression) -> exp.Expression:
if isinstance(table, str):
return exp.to_table(table)
elif isinstance(table, exp.Expression):
return table
raise ValueError(f"Invalid table type: {table}")


def coerce_to_expression(
val: exp.ExpOrStr, coerce_type: exp.IntoType, dialect: t.Optional[str] = None
) -> exp.Expression:
if isinstance(val, exp.Expression):
return val
elif isinstance(val, str):
return parse_one(val, dialect=dialect, into=coerce_type)
raise ValueError(f"Invalid value type: {val}")


def literal_or_expression(val: exp.ExpOrStr | int | float) -> exp.Expression:
if isinstance(val, exp.Expression):
return val
elif isinstance(val, str):
return exp.Literal(this=val, is_string=True)
else:
return exp.Literal(this=val, is_string=False)


def exp_literal_to_py_literal(glot_literal: exp.Expression) -> t.Any:
# Don't error by default let it pass
if not isinstance(glot_literal, exp.Literal):
Expand Down

0 comments on commit ddaddf4

Please sign in to comment.