Skip to content

Commit

Permalink
index modules (#6)
Browse files Browse the repository at this point in the history
  • Loading branch information
devanoneth authored Oct 9, 2024
1 parent 8dc3dad commit f9ff807
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 21 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ $ ./script/build.sh [--reset] [--code-gen] [--network (from above list)]
Requires [Docker](https://docs.docker.com/get-docker/) to be installed.

```
$ graph test -d
$ yarn test
```

## Deployment
Expand Down
3 changes: 3 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ type Transaction @entity {
"Amount paid as fee to refundReceiver"
payment : BigInt

"Present if the transaction is from a Safe module (in this case some other fields won't be available as not all fields are used in the Safe module context)"
module : Bytes

"Wallet parent"
wallet : Wallet! @derivedFrom(field: "transactions")
}
Expand Down
139 changes: 120 additions & 19 deletions src/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ import {
ExecutionSuccess,
ExecutionFailure,
ExecTransactionCall,
ExecutionFromModuleSuccess,
ExecutionFromModuleFailure,
ExecTransactionFromModuleCall,
} from "../generated/templates/Safe/GnosisSafe";
import { SafeMultiSigTransaction } from "../generated/templates/Safe/GnosisSafeL2";
import {
SafeModuleTransaction,
SafeMultiSigTransaction,
} from "../generated/templates/Safe/GnosisSafeL2";
import { ChangedMasterCopy } from "../generated/templates/SafeMigraton/SafeMigration";
import { Wallet, Transaction } from "../generated/schema";
import {
Expand All @@ -27,6 +33,26 @@ import {
ethereum,
} from "@graphprotocol/graph-ts";

export function handleChangedMasterCopy(event: ChangedMasterCopy): void {
let walletAddr = event.address;
let safeInstance = GnosisSafe.bind(walletAddr);
let wallet = Wallet.load(walletAddr.toHex());

if (wallet != null) {
wallet.singleton = event.params.singleton;

// it would be nice if we could change the data source for the wallet at this point from Safe to SafeL2 but it doesn't seem to be possible
let maybeL2 = isL2Wallet(event.params.singleton) ? "+L2" : "";
wallet.version = safeInstance.VERSION() + maybeL2;

wallet.save();
} else {
log.warning("handleChangedMasterCopy::Wallet {} not found", [
walletAddr.toHexString(),
]);
}
}

export function handleAddedOwner(event: AddedOwner): void {
let walletAddr = event.address;
let wallet = Wallet.load(walletAddr.toHex());
Expand Down Expand Up @@ -76,67 +102,142 @@ export function handleChangedThreshold(event: ChangedThreshold): void {
}
}

export function handleExecutionSuccess(event: ExecutionSuccess): void {
export function handleExecutionFromModuleSuccess(
event: ExecutionFromModuleSuccess
): void {
let walletAddr = event.address;
let wallet = Wallet.load(walletAddr.toHex());

if (wallet != null) {
let transaction = getTransaction(walletAddr, event.params.txHash);
let transaction = getTransaction(walletAddr, event.transaction.hash);
transaction.module = event.params.module;
transaction.status = "EXECUTED";
transaction.block = event.block.number;
transaction.hash = event.transaction.hash;
transaction.timestamp = event.block.timestamp;
transaction.txHash = event.params.txHash;
transaction.payment = event.params.payment;
transaction.save();

wallet = addTransactionToWallet(<Wallet>wallet, transaction);
wallet.save();
} else {
log.warning("handleExecutionSuccess::Wallet {} not found", [
log.warning("handleExecutionFromModuleSuccess::Wallet {} not found", [
walletAddr.toHexString(),
]);
}
}

export function handleExecutionFailure(event: ExecutionFailure): void {
export function handleExecutionFromModuleFailure(
event: ExecutionFromModuleFailure
): void {
let walletAddr = event.address;
let wallet = Wallet.load(walletAddr.toHex());

if (wallet != null) {
let transaction = getTransaction(walletAddr, event.params.txHash);
let transaction = getTransaction(walletAddr, event.transaction.hash);
transaction.module = event.params.module;
transaction.status = "FAILED";
transaction.block = event.block.number;
transaction.hash = event.transaction.hash;
transaction.timestamp = event.block.timestamp;
transaction.save();
} else {
log.warning("handleExecutionFromModuleFailure::Wallet {} not found", [
walletAddr.toHexString(),
]);
}
}

export function handleExecTransactionFromModule(
call: ExecTransactionFromModuleCall
): void {
let walletAddr = call.to;
let wallet = Wallet.load(walletAddr.toHex());

if (wallet != null) {
let transaction = getTransaction(walletAddr, call.transaction.hash);
transaction.module = call.from;
transaction.to = call.inputs.to;
transaction.value = call.inputs.value;
transaction.data = call.inputs.data;
transaction.operation =
call.inputs.operation == 0 ? "CALL" : "DELEGATE_CALL";
transaction.save();

wallet = addTransactionToWallet(<Wallet>wallet, transaction);
wallet.save();
} else {
log.warning("handleExecTransactionFromModule::Wallet {} not found", [
walletAddr.toHexString(),
]);
}
}

export function handleSafeModuleTransaction(
event: SafeModuleTransaction
): void {
let walletAddr = event.address;
let wallet = Wallet.load(walletAddr.toHex());

if (wallet != null) {
let transaction = getTransaction(walletAddr, event.transaction.hash);
transaction.module = event.params.module;
transaction.to = event.params.to;
transaction.value = event.params.value;
transaction.data = event.params.data;
transaction.operation =
event.params.operation == 0 ? "CALL" : "DELEGATE_CALL";
transaction.save();

wallet = addTransactionToWallet(<Wallet>wallet, transaction);
wallet.save();
} else {
log.warning("handleSafeModuleTransaction::Wallet {} not found", [
walletAddr.toHexString(),
]);
}
}

export function handleExecutionSuccess(event: ExecutionSuccess): void {
let walletAddr = event.address;
let wallet = Wallet.load(walletAddr.toHex());

if (wallet != null) {
let transaction = getTransaction(walletAddr, event.params.txHash);
transaction.status = "EXECUTED";
transaction.block = event.block.number;
transaction.hash = event.transaction.hash;
transaction.timestamp = event.block.timestamp;
transaction.txHash = event.params.txHash;
transaction.payment = event.params.payment;
transaction.save();

wallet = addTransactionToWallet(<Wallet>wallet, transaction);
wallet.save();
} else {
log.warning("handleExecutionFailure::Wallet {} not found", [
log.warning("handleExecutionSuccess::Wallet {} not found", [
walletAddr.toHexString(),
]);
}
}

export function handleChangedMasterCopy(event: ChangedMasterCopy): void {
export function handleExecutionFailure(event: ExecutionFailure): void {
let walletAddr = event.address;
let safeInstance = GnosisSafe.bind(walletAddr);
let wallet = Wallet.load(walletAddr.toHex());

if (wallet != null) {
wallet.singleton = event.params.singleton;

// it would be nice if we could change the data source for the wallet at this point from Safe to SafeL2 but it doesn't seem to be possible
let maybeL2 = isL2Wallet(event.params.singleton) ? "+L2" : "";
wallet.version = safeInstance.VERSION() + maybeL2;
let transaction = getTransaction(walletAddr, event.params.txHash);
transaction.status = "FAILED";
transaction.block = event.block.number;
transaction.hash = event.transaction.hash;
transaction.timestamp = event.block.timestamp;
transaction.txHash = event.params.txHash;
transaction.payment = event.params.payment;
transaction.save();

wallet = addTransactionToWallet(<Wallet>wallet, transaction);
wallet.save();
} else {
log.warning("handleChangedMasterCopy::Wallet {} not found", [
log.warning("handleExecutionFailure::Wallet {} not found", [
walletAddr.toHexString(),
]);
}
Expand Down Expand Up @@ -199,7 +300,7 @@ function addTransactionToWallet(
): Wallet {
let transactions = wallet.transactions;

if (transactions.indexOf(transaction.id, 0) == -1) {
if (transactions.indexOf(transaction.id) == -1) {
transactions.push(transaction.id);
wallet.transactions = transactions;
}
Expand Down Expand Up @@ -236,7 +337,7 @@ function improved_try_nonce(
return ImprovedCallResult.fromValue(value[0].toBigInt());
}

export function handleTransaction(
function handleTransaction(
walletAddr: Address,
hash: Bytes,
to: Address,
Expand Down
12 changes: 12 additions & 0 deletions subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,19 @@ templates:
handler: handleRemovedOwner
- event: ChangedThreshold(uint256)
handler: handleChangedThreshold
- event: ExecutionFromModuleSuccess(indexed address)
handler: handleExecutionFromModuleSuccess
- event: ExecutionFromModuleFailure(indexed address)
handler: handleExecutionFromModuleFailure
- event: ExecutionSuccess(bytes32,uint256)
handler: handleExecutionSuccess
- event: ExecutionFailure(bytes32,uint256)
handler: handleExecutionFailure
callHandlers:
- function: execTransaction(address,uint256,bytes,uint8,uint256,uint256,uint256,address,address,bytes)
handler: handleExecTransaction
- function: execTransactionFromModule(address,uint256,bytes,uint8)
handler: handleExecTransactionFromModule
- kind: ethereum/contract
name: SafeL2
network: mainnet
Expand All @@ -165,6 +171,12 @@ templates:
handler: handleRemovedOwner
- event: ChangedThreshold(uint256)
handler: handleChangedThreshold
- event: ExecutionFromModuleSuccess(indexed address)
handler: handleExecutionFromModuleSuccess
- event: ExecutionFromModuleFailure(indexed address)
handler: handleExecutionFromModuleFailure
- event: SafeModuleTransaction(address,address,uint256,bytes,uint8)
handler: handleSafeModuleTransaction
- event: ExecutionSuccess(bytes32,uint256)
handler: handleExecutionSuccess
- event: ExecutionFailure(bytes32,uint256)
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": 1728342251221
"timestamp": 1728470472830
}

0 comments on commit f9ff807

Please sign in to comment.