Skip to content

Commit

Permalink
fix: don't use call handlers on unsupported networks (#12)
Browse files Browse the repository at this point in the history
* fix: don't use call handlers on unsupported networks

* return subgraph.yaml to mainnet
  • Loading branch information
devanoneth authored Nov 10, 2024
1 parent 32427a5 commit 50e3b02
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 4 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,14 @@ There are two commonly used deployments of the v1.3.0 factory. Both are indexed.

#### L2 Safes

On any L2, it's possible that there is both the original (in a sense that it is the same as the original contract deployed to L1) [Safe](https://github.com/safe-global/safe-smart-account/blob/main/contracts/Safe.sol) contract and the [SafeL2](https://github.com/safe-global/safe-smart-account/blob/main/contracts/SafeL2.sol#L10) contract. This subgraph supports both contracts, via the same instance, but with two different data sources. This means you can query `Safe` and `SafeL2` wallets in the same way with the same GraphQL queries against one endpoint, even though they are indexed differently in _The Graph_.
On any L2, it's possible that there is both the original (in a sense that it is the same as the original contract deployed to L1) [Safe](https://github.com/safe-global/safe-smart-account/blob/main/contracts/Safe.sol) contract and the [SafeL2](https://github.com/safe-global/safe-smart-account/blob/main/contracts/SafeL2.sol#L10) contract. This subgraph supports both contracts, via the same instance, but with two different data sources. This means you can query `Safe` and `SafeL2` wallets in the same way with the same GraphQL queries against one endpoint, even though they are indexed differently in _The Graph_.

The data sources are defined in [subgraph.yaml](subgraph.yaml) as `templates` and are named accordingly `Safe` and `SafeL2`. The `SafeL2` data source is more efficient because it reads the data from events emitted from the corresponding contract, whereas the `Safe` data source must rely on call handlers in lieu of the contract not emitting events. The subgraph will automatically detect whether the new safe is of a `Safe` or `SafeL2` instance based on the known `SafeL2` singleton deployment address. However, if a new `SafeL2` singleton is deployed that this subgraph does not know about, the subgraph will fall back to using `Safe` data source and its call handler to ensure it reads all the information from the safe, no matter whether it emits events or not. This is not a problem as `SafeL2` safes can still be indexed via the call handler rather than the event handler, it's just less efficient.

#### Call Handlers Unsupported Networks

Certain networks are not backed by RPC nodes which support `trace_filter` and therefore do not support call handlers. Namely, the following networks: `optimism`, `base`, `celo` and `avalanche`. For these networks, only event handlers are supported and therefore Safes which use the original `Safe` contract will not be indexed, only Safes which use the `SafeL2` contract.

## Prerequiste

- yarn
Expand Down
12 changes: 10 additions & 2 deletions src/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
Address,
ethereum,
} from "@graphprotocol/graph-ts";
import { isL2Wallet, zeroBigInt } from "./utils";
import { isL2Wallet, onlySupportsEventHandlers, zeroBigInt } from "./utils";

/**
* Get the singleton address from the proxy creation transaction input data
Expand Down Expand Up @@ -62,7 +62,15 @@ function handleProxyCreation(
if (isL2) {
SafeL2Contract.create(walletAddress);
} else {
SafeContract.create(walletAddress);
if (onlySupportsEventHandlers(dataSource.network())) {
// some networks don't support call handlers (due to no support for the trace_filter RPC method), so Safes using the original L1 contract cannot be indexed on that network
log.warning(
"handleProxyCreation::Wallet {} is a L1 Safe but this network only supports event handlers, so it will not be indexed (tx: {})",
[walletAddress.toHexString(), event.transaction.hash.toHexString()]
);
} else {
SafeContract.create(walletAddress);
}
}
} else {
// A wallet can be instantiated from the proxy with incorrect setup values
Expand Down
9 changes: 9 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ export function isL2Wallet(singleton: Address): bool {
return L2Singletons.includes(singleton);
}

export function onlySupportsEventHandlers(network: string): bool {
return (
network == "optimism" ||
network == "base" ||
network == "celo" ||
network == "avalanche"
);
}

/**
* An improved version of the CallResult type from the graph-ts library.
* This type allows for a reverted call to be distinguished from a call that
Expand Down
2 changes: 1 addition & 1 deletion tests/.latest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"version": "0.6.0",
"timestamp": 1729008721629
"timestamp": 1730650512807
}

0 comments on commit 50e3b02

Please sign in to comment.