From a5e0d15ff6394d7f38f097521985f1fad55dc278 Mon Sep 17 00:00:00 2001
From: Kyle <kyletrusler@gmail.com>
Date: Thu, 25 Apr 2024 15:15:49 -0400
Subject: [PATCH] ggp vault

---
 src/actions-local/ggpvault.spec.ts            |  51 ++-----
 .../payload-ggpvault-distribute-rewards.json  | 134 ++++++++++++++++++
 src/actions/ggpvault.ts                       |  33 ++++-
 src/actions/logParsing.ts                     |   5 +-
 src/actions/templates.ts                      | 128 ++++++++++-------
 tenderly.yaml                                 |  43 ++++++
 6 files changed, 301 insertions(+), 93 deletions(-)
 create mode 100644 src/actions-local/payload/payload-ggpvault-distribute-rewards.json

diff --git a/src/actions-local/ggpvault.spec.ts b/src/actions-local/ggpvault.spec.ts
index 896520b..57512f7 100644
--- a/src/actions-local/ggpvault.spec.ts
+++ b/src/actions-local/ggpvault.spec.ts
@@ -3,47 +3,16 @@ import { TestRuntime } from "@tenderly/actions-test";
 
 import { beforeAll, describe, test } from "vitest";
 
-import { depositOrWithdraw, stakingTransactions, stateVariablesUpdated } from "../actions/ggpvault";
+import {
+  depositOrWithdraw,
+  rewardsDistributed,
+  stakingTransactions,
+  stateVariablesUpdated,
+} from "../actions/ggpvault";
+import { getRewardsDistributedEvent } from "../actions/logParsing";
 
 config();
-/*
 
-export interface XGGPDeposit extends Event {
-  sender: string;
-  owner: string;
-  assets: BigNumber;
-  shares: BigNumber;
-}
-
-export interface XGGPWithdraw extends Event {
-  sender: string;
-  receiver: string;
-  owner: string;
-  assets: BigNumber;
-  shares: BigNumber;
-}
-
-export interface GGPCapUpdated extends Event {
-  newMax: BigNumber;
-}
-
-export interface TargetAPRUpdated extends Event {
-  newTargetAPR: BigNumber;
-}
-
-export interface WithdrawnForStaking extends Event {
-  caller: string;
-  assets: BigNumber;
-}
-
-export interface DepositedFromStaking extends Event {
-  caller: string;
-  amount: BigNumber;
-}
-
-export interface RewardsDistributed extends Event {
-  amount: BigNumber;
-}*/
 describe("GGP Vault", () => {
   const testRuntime = new TestRuntime();
   beforeAll(() => {
@@ -100,11 +69,11 @@ describe("GGP Vault", () => {
       );
     });
   });
-  describe.skip("rewards", () => {
+  describe("rewards", () => {
     test.concurrent("distributed", async () => {
       await testRuntime.execute(
-        depositOrWithdraw,
-        require("./payload/payload-ggpvault-rewards.json")
+        rewardsDistributed,
+        require("./payload/payload-ggpvault-distribute-rewards.json")
       );
     });
   });
diff --git a/src/actions-local/payload/payload-ggpvault-distribute-rewards.json b/src/actions-local/payload/payload-ggpvault-distribute-rewards.json
new file mode 100644
index 0000000..11fd56e
--- /dev/null
+++ b/src/actions-local/payload/payload-ggpvault-distribute-rewards.json
@@ -0,0 +1,134 @@
+{
+  "transactionHash": "0xb8622cee02bb97f1f116872b4cdccb90c3eb493bbb28282fa7b15db5cef8c487",
+  "transactionIndex": "0x3",
+  "blockHash": "0x3710adeed0ad8f214c8d53f1519b31c453524ef4c5a57c2ed0d6da95acab3df3",
+  "blockNumber": "0x2a7c04d",
+  "from": "0x2ff60357027861f25c7a6650564c2a606d23369d",
+  "to": "0xdf34022e8a280fc79499ca560439bb6f9797ebd8",
+  "cumulativeGasUsed": "0x4d583",
+  "gasUsed": "0x31c28",
+  "contractAddress": null,
+  "logs": [
+    {
+      "address": "0x69260b9483f9871ca57f81a90d91e2f96c2cd11d",
+      "topics": [
+        "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925",
+        "0x000000000000000000000000df34022e8a280fc79499ca560439bb6f9797ebd8",
+        "0x000000000000000000000000b6ddbf75e2f0c7fc363b47b84b5c03959526aecb"
+      ],
+      "data": "0x000000000000000000000000000000000000000000000000032af52def715997",
+      "blockHash": "0x3710adeed0ad8f214c8d53f1519b31c453524ef4c5a57c2ed0d6da95acab3df3",
+      "blockNumber": "0x2a7c04d",
+      "transactionHash": "0xb8622cee02bb97f1f116872b4cdccb90c3eb493bbb28282fa7b15db5cef8c487",
+      "transactionIndex": "0x3",
+      "logIndex": "0x2",
+      "removed": false
+    },
+    {
+      "address": "0x69260b9483f9871ca57f81a90d91e2f96c2cd11d",
+      "topics": [
+        "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
+        "0x000000000000000000000000df34022e8a280fc79499ca560439bb6f9797ebd8",
+        "0x000000000000000000000000b6ddbf75e2f0c7fc363b47b84b5c03959526aecb"
+      ],
+      "data": "0x000000000000000000000000000000000000000000000000032af52def715997",
+      "blockHash": "0x3710adeed0ad8f214c8d53f1519b31c453524ef4c5a57c2ed0d6da95acab3df3",
+      "blockNumber": "0x2a7c04d",
+      "transactionHash": "0xb8622cee02bb97f1f116872b4cdccb90c3eb493bbb28282fa7b15db5cef8c487",
+      "transactionIndex": "0x3",
+      "logIndex": "0x3",
+      "removed": false
+    },
+    {
+      "address": "0xb6ddbf75e2f0c7fc363b47b84b5c03959526aecb",
+      "topics": [
+        "0x3cd32fbc628a7c1c5a309e823125e5a4b8d98b9b31ad71d8338cc5f05829b199",
+        "0x0000000000000000000000002ff60357027861f25c7a6650564c2a606d23369d"
+      ],
+      "data": "0x000000000000000000000000000000000000000000000000032af52def715997",
+      "blockHash": "0x3710adeed0ad8f214c8d53f1519b31c453524ef4c5a57c2ed0d6da95acab3df3",
+      "blockNumber": "0x2a7c04d",
+      "transactionHash": "0xb8622cee02bb97f1f116872b4cdccb90c3eb493bbb28282fa7b15db5cef8c487",
+      "transactionIndex": "0x3",
+      "logIndex": "0x4",
+      "removed": false
+    },
+    {
+      "address": "0x69260b9483f9871ca57f81a90d91e2f96c2cd11d",
+      "topics": [
+        "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925",
+        "0x000000000000000000000000b6ddbf75e2f0c7fc363b47b84b5c03959526aecb",
+        "0x000000000000000000000000d45cb6f5aca41afaaaebdbe4efba49c1bc41e6ba"
+      ],
+      "data": "0x000000000000000000000000000000000000000000000000032af52def715997",
+      "blockHash": "0x3710adeed0ad8f214c8d53f1519b31c453524ef4c5a57c2ed0d6da95acab3df3",
+      "blockNumber": "0x2a7c04d",
+      "transactionHash": "0xb8622cee02bb97f1f116872b4cdccb90c3eb493bbb28282fa7b15db5cef8c487",
+      "transactionIndex": "0x3",
+      "logIndex": "0x5",
+      "removed": false
+    },
+    {
+      "address": "0xd45cb6f5aca41afaaaebdbe4efba49c1bc41e6ba",
+      "topics": [
+        "0xc4c24354aa86aa3532ebd9da7ff92230de931c78c77fcdf84544f11bf8fae753",
+        "0xbea235ff677e781f981db3b8d8193dd2280c06e039b6f51dbfdad43fc6338e17",
+        "0x00000000000000000000000069260b9483f9871ca57f81a90d91e2f96c2cd11d"
+      ],
+      "data": "0x000000000000000000000000000000000000000000000000032af52def715997",
+      "blockHash": "0x3710adeed0ad8f214c8d53f1519b31c453524ef4c5a57c2ed0d6da95acab3df3",
+      "blockNumber": "0x2a7c04d",
+      "transactionHash": "0xb8622cee02bb97f1f116872b4cdccb90c3eb493bbb28282fa7b15db5cef8c487",
+      "transactionIndex": "0x3",
+      "logIndex": "0x6",
+      "removed": false
+    },
+    {
+      "address": "0x69260b9483f9871ca57f81a90d91e2f96c2cd11d",
+      "topics": [
+        "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
+        "0x000000000000000000000000b6ddbf75e2f0c7fc363b47b84b5c03959526aecb",
+        "0x000000000000000000000000d45cb6f5aca41afaaaebdbe4efba49c1bc41e6ba"
+      ],
+      "data": "0x000000000000000000000000000000000000000000000000032af52def715997",
+      "blockHash": "0x3710adeed0ad8f214c8d53f1519b31c453524ef4c5a57c2ed0d6da95acab3df3",
+      "blockNumber": "0x2a7c04d",
+      "transactionHash": "0xb8622cee02bb97f1f116872b4cdccb90c3eb493bbb28282fa7b15db5cef8c487",
+      "transactionIndex": "0x3",
+      "logIndex": "0x7",
+      "removed": false
+    },
+    {
+      "address": "0xdf34022e8a280fc79499ca560439bb6f9797ebd8",
+      "topics": [
+        "0x14438a8606c512fda07a1e9dfefc371418ed542946338bfa1c87788e903b4d68",
+        "0x0000000000000000000000002ff60357027861f25c7a6650564c2a606d23369d"
+      ],
+      "data": "0x000000000000000000000000000000000000000000000000032af52def715997",
+      "blockHash": "0x3710adeed0ad8f214c8d53f1519b31c453524ef4c5a57c2ed0d6da95acab3df3",
+      "blockNumber": "0x2a7c04d",
+      "transactionHash": "0xb8622cee02bb97f1f116872b4cdccb90c3eb493bbb28282fa7b15db5cef8c487",
+      "transactionIndex": "0x3",
+      "logIndex": "0x8",
+      "removed": false
+    },
+    {
+      "address": "0xdf34022e8a280fc79499ca560439bb6f9797ebd8",
+      "topics": [
+        "0x6d1c76d614228b523baa4dcd9539e2c713b54ff4ab3ff2d1627e7f6cd32be442"
+      ],
+      "data": "0x000000000000000000000000000000000000000000000004b54f66bb299cad17",
+      "blockHash": "0x3710adeed0ad8f214c8d53f1519b31c453524ef4c5a57c2ed0d6da95acab3df3",
+      "blockNumber": "0x2a7c04d",
+      "transactionHash": "0xb8622cee02bb97f1f116872b4cdccb90c3eb493bbb28282fa7b15db5cef8c487",
+      "transactionIndex": "0x3",
+      "logIndex": "0x9",
+      "removed": false
+    }
+  ],
+  "status": "0x1",
+  "logsBloom": "0x00020001100000020000001000000000000000000000000000008000000080000000000000000000000400200000000000000000000000000004000000222000018000100c04000000000008080000000000080000000010000000000004000000000000040000000000400000000000000000000000008000000010001000000020000000000080000000800000000000000000000100000000080000000002020000800000000000008000000000000000000000000000000000000000000004000002000000000000000000000008000800000000010000000000000002000010000000000000000000000000000000000000080000000000000000010008",
+  "type": "0x2",
+  "effectiveGasPrice": "0x62b85e900",
+  "deposit_nonce": null
+}
\ No newline at end of file
diff --git a/src/actions/ggpvault.ts b/src/actions/ggpvault.ts
index d9419da..c1b4d79 100644
--- a/src/actions/ggpvault.ts
+++ b/src/actions/ggpvault.ts
@@ -1,6 +1,7 @@
 import { Context, Event, TransactionEvent } from "@tenderly/actions";
 import {
   getDepositedFromStakingEvent,
+  getRewardsDistributedEvent,
   getTargetAPRUpdatedEvent,
   getWithdrawnForStakingEvent,
   getXggpCapUpdatedEvent,
@@ -11,6 +12,7 @@ import {
   XGGP_DEPOSIT_DISPLAY_TEMPLATE,
   XGGP_GGP_CAP_UPDATED_TEMPLATE,
   XGGP_STAKING_DEPOSIT_TEMPLATE,
+  XGGP_STAKING_REWARD_TEMPLATE,
   XGGP_STAKING_WITHDRAW_TEMPLATE,
   XGGP_TARGET_APR_UPDATED_TEMPLATE,
   XGGP_WITHDRAW_DISPLAY_TEMPLATE,
@@ -18,6 +20,7 @@ import {
 import {
   DepositedFromStaking,
   GGPCapUpdated,
+  RewardsDistributed,
   TargetAPRUpdated,
   WithdrawnForStaking,
   XGGPDeposit,
@@ -39,8 +42,10 @@ const handleXggpWithdrawEvent = async (
   transactionEvent: TransactionEvent,
   ggpWithdrawnEvent: XGGPWithdraw
 ) => {
-  const { assets } = ggpWithdrawnEvent;
-  await emitter.emit(XGGP_WITHDRAW_DISPLAY_TEMPLATE(transactionEvent, assets));
+  const { assets, address } = ggpWithdrawnEvent;
+  await emitter.emit(
+    XGGP_WITHDRAW_DISPLAY_TEMPLATE(transactionEvent, assets, address)
+  );
 };
 
 const handleXggpCapUpdatedEvent = async (capUpdatedEvent: GGPCapUpdated) => {
@@ -69,6 +74,16 @@ const handleXggpStakingWithdrawEvent = async (
   await emitter.emit(XGGP_STAKING_WITHDRAW_TEMPLATE(assets, caller));
 };
 
+const handleXggpRewardsDistributedEvent = async (
+  transactionEvent: TransactionEvent,
+  rewardsDistributedEvent: RewardsDistributed
+) => {
+  const { amount } = rewardsDistributedEvent;
+  await emitter.emit(
+    XGGP_STAKING_REWARD_TEMPLATE(transactionEvent, amount)
+  );
+};
+
 export const depositOrWithdraw = async (context: Context, event: Event) => {
   await initServices(context);
   const transactionEvent = event as TransactionEvent;
@@ -102,6 +117,20 @@ export const stateVariablesUpdated = async (context: Context, event: Event) => {
     await handleXggpTargetAprUpdatedEvent(targetAprUpdatedEvent);
   }
 };
+export const rewardsDistributed = async (context: Context, event: Event) => {
+  await initServices(context);
+  const transactionEvent = event as TransactionEvent;
+
+  const rewardsDistributedEvent = await getRewardsDistributedEvent(
+    transactionEvent
+  );
+  if (rewardsDistributedEvent) {
+    await handleXggpRewardsDistributedEvent(
+      transactionEvent,
+      rewardsDistributedEvent
+    );
+  }
+};
 
 export const stakingTransactions = async (context: Context, event: Event) => {
   await initServices(context);
diff --git a/src/actions/logParsing.ts b/src/actions/logParsing.ts
index e37b790..4602fbc 100644
--- a/src/actions/logParsing.ts
+++ b/src/actions/logParsing.ts
@@ -12,6 +12,7 @@ import {
   GGPCapUpdated,
   GGPStaked,
   GGPWithdrawn,
+  RewardsDistributed,
   TargetAPRUpdated,
   WithdrawnForStaking,
   XGGPDeposit,
@@ -235,9 +236,9 @@ export const getWithdrawnForStakingEvent = async (
 
 export const getRewardsDistributedEvent = async (
   transactionEvent: TransactionEvent
-): Promise<{ amount: string } | undefined> => {
+): Promise<RewardsDistributed | undefined> => {
   try {
-    return await getMatchingEvent<{ amount: string }>(
+    return await getMatchingEvent<RewardsDistributed>(
       transactionEvent,
       GGP_VAULT_INTERFACE,
       "RewardsDistributed"
diff --git a/src/actions/templates.ts b/src/actions/templates.ts
index 3cf112f..054c2dd 100644
--- a/src/actions/templates.ts
+++ b/src/actions/templates.ts
@@ -26,7 +26,7 @@ const pilotComponent = (owner: string) => {
   return new ButtonBuilder()
     .setEmoji("🧑‍✈️")
     .setLabel("Pilot")
-    .setURL(`https://snowtrace.io/address/${owner}`)
+    .setURL(`https://snowscan.xyz/address/${owner}`)
     .setStyle(ButtonStyle.Link);
 };
 
@@ -42,15 +42,15 @@ const liquidStakerComponent = (owner: string) => {
   return new ButtonBuilder()
     .setEmoji("🌊")
     .setLabel("Liquid Staker")
-    .setURL(`https://snowtrace.io/address/${owner}`)
+    .setURL(`https://snowscan.xyz/address/${owner}`)
     .setStyle(ButtonStyle.Link);
 };
 
-const transactionComponent = (transactionHash: string) => {
+const transactionComponent = (hash: string) => {
   return new ButtonBuilder()
     .setEmoji("📝")
     .setLabel("Transaction")
-    .setURL(`https://snowtrace.io/tx/${transactionHash}`)
+    .setURL(`https://snowscan.xyz/tx/${hash}`)
     .setStyle(ButtonStyle.Link);
 };
 
@@ -140,14 +140,14 @@ const differenceField = (
   };
 };
 
-const ggpDifferenceField = (
-  difference: BigNumber,
-  total: BigNumber,
-  subtraction?: boolean,
-  options?: Partial<APIEmbedField>
-) => {
-  return differenceField("GGP", difference, total, subtraction, options);
-};
+// const ggpDifferenceField = (
+//   difference: BigNumber,
+//   total: BigNumber,
+//   subtraction?: boolean,
+//   options?: Partial<APIEmbedField>
+// ) => {
+//   return differenceField("GGP", difference, total, subtraction, options);
+// };
 
 const avaxDifferenceField = (
   difference: BigNumber,
@@ -219,7 +219,7 @@ const liquidStakerField = (
 const liquidStakerDisplay = (owner: string): string =>
   `[${getEmojiAddress(
     utils.getAddress(owner)
-  )}](https://snowtrace.io/address/${owner})`;
+  )}](https://snowscan.xyz/address/${owner})`;
 
 const rewardsCycleStartTimeField = (
   time: BigNumber,
@@ -295,7 +295,7 @@ export const MINIPOOL_PRELAUNCH_TEMPLATE = (
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         pilotComponent(owner),
         balloonComponent(nodeId),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -330,7 +330,7 @@ export const MINIPOOL_STREAMLINE_TEMPLATE = (
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         pilotComponent(owner),
         balloonComponent(nodeId),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -363,7 +363,7 @@ export const MINIPOOL_LAUNCH_TEMPLATE = (
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         pilotComponent(owner),
         balloonComponent(nodeId),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -397,7 +397,7 @@ export const MINIPOOL_STAKING_TEMPLATE = (
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         pilotComponent(owner),
         balloonComponent(nodeId),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -432,7 +432,7 @@ export const MINIPOOL_WITHDRAWABLE_TEMPLATE = (
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         pilotComponent(owner),
         balloonComponent(nodeId),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -466,7 +466,7 @@ export const MINIPOOL_FINISHED_TEMPLATE = (
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         pilotComponent(owner),
         balloonComponent(nodeId),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -501,7 +501,7 @@ export const MINIPOOL_CANCELED_TEMPLATE = (
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         pilotComponent(owner),
         balloonComponent(nodeId),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -536,7 +536,7 @@ export const MINIPOOL_ERROR_TEMPLATE = (
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         pilotComponent(owner),
         balloonComponent(nodeId),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -572,7 +572,7 @@ export const MINIPOOL_RESTAKE_TEMPLATE = (
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         pilotComponent(owner),
         balloonComponent(nodeId),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -611,7 +611,7 @@ export const GGP_STAKING_STAKE_TEMPLATE = (
     components: [
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         pilotComponent(owner),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -652,7 +652,7 @@ export const GGP_STAKING_WITHDRAW_TEMPLATE = (
     components: [
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         pilotComponent(owner),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -688,7 +688,7 @@ export const GGAVAX_DEPOSIT_TEMPLATE = (
     components: [
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         liquidStakerComponent(transactionEvent.from),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -729,8 +729,8 @@ export const GGAVAX_DEPOSIT_DISPLAY_TEMPLATE = (
     embeds: [
       new EmbedBuilder()
         .setDescription(
-          `${title}\n\n[⛓️ transaction](https://snowtrace.io/tx/${
-            transactionEvent.transactionHash
+          `${title}\n\n[⛓️ transaction](https://snowscan.xyz/tx/${
+            transactionEvent.hash
           }) [📄 liquid staking](https://docs.gogopool.com/design/how-liquid-staking-works) ${liquidStakerDisplay(
             transactionEvent.from
           )}`
@@ -750,7 +750,7 @@ export const GGAVAX_WITHDRAW_TEMPLATE = (
     components: [
       new ActionRowBuilder<ButtonBuilder>().addComponents(
         liquidStakerComponent(transactionEvent.from),
-        transactionComponent(transactionEvent.transactionHash)
+        transactionComponent(transactionEvent.hash)
       ),
     ],
     embeds: [
@@ -791,8 +791,8 @@ export const GGAVAX_WITHDRAW_DISPLAY_TEMPLATE = (
     embeds: [
       new EmbedBuilder()
         .setDescription(
-          `${title}\n\n[⛓️ transaction](https://snowtrace.io/tx/${
-            transactionEvent.transactionHash
+          `${title}\n\n[⛓️ transaction](https://snowscan.xyz/tx/${
+            transactionEvent.hash
           }) [📄 liquid staking](https://docs.gogopool.com/design/how-liquid-staking-works) ${liquidStakerDisplay(
             transactionEvent.from
           )}`
@@ -806,41 +806,44 @@ export const XGGP_DEPOSIT_DISPLAY_TEMPLATE = (
   transactionEvent: TransactionEvent,
   { assets, owner, sender, shares }: XGGPDeposit
 ) => {
-  const title = `⬆️ ${ggpAmountDisplay(assets)} Added to the Vault.`;
+  const title = `📥 ${ggpAmountDisplay(
+    assets
+  )} Deposited into the [SeaFi Vault](https://seafi.app)`;
 
   return {
     embeds: [
       new EmbedBuilder()
         .setDescription(
-          `${title}\n\n[⛓️ transaction](https://snowtrace.io/tx/${
-            transactionEvent.transactionHash
+          `${title}\n\n[⛓️ transaction](https://snowscan.xyz/tx/${
+            transactionEvent.hash
           }) [📄 vault deposit](https://docs.seafi.app/overview/depositors) ${liquidStakerDisplay(
             transactionEvent.from
           )}`
         )
-        .setColor(0xaa5566)
-        .setFooter({ text: "[vault] • deposit" }),
+        .setColor(0xaa5566),
     ],
   };
 };
 
 export const XGGP_WITHDRAW_DISPLAY_TEMPLATE = (
   transactionEvent: TransactionEvent,
-  assets: BigNumber
+  assets: BigNumber,
+  address: string
 ) => {
-  const title = `⬇️ ${ggpAmountDisplay(assets)} Drained from the Vault.`;
+  const title = `📤 ${ggpAmountDisplay(
+    assets
+  )} Redeemed from the [SeaFi Vault](https://seafi.app)`;
   return {
     embeds: [
       new EmbedBuilder()
         .setDescription(
-          `${title}\n\n[⛓️ transaction](https://snowtrace.io/tx/${
-            transactionEvent.transactionHash
+          `${title}\n\n[⛓️ transaction](https://snowscan.xyz/tx/${
+            transactionEvent.hash
           }) [📄 vault withdraw](https://docs.seafi.app/overview/depositors) ${liquidStakerDisplay(
             transactionEvent.from
           )}`
         )
-        .setColor(0xaa4950)
-        .setFooter({ text: "[vault] • withdraw" }),
+        .setColor(0xaa4950),
     ],
   };
 };
@@ -871,33 +874,62 @@ export const XGGP_TARGET_APR_UPDATED_TEMPLATE = (
   };
 };
 
-export const XGGP_STAKING_DEPOSIT_TEMPLATE = (assets: BigNumber) => {
+export const XGGP_STAKING_DEPOSIT_TEMPLATE = (
+  assets: BigNumber,
+  caller: string
+) => {
   return {
     embeds: [
       new EmbedBuilder()
-        .setTitle(`⬆️ ${ggpAmountDisplay(assets)} tokens added.`)
+        .setTitle(`⬆️ ${ggpAmountDisplay(assets)} tokens added by ${caller}.`)
         .setDescription(
           `Liquidity in the vault has decreased as GGP was delegated to a GoGoPool staker.\n[📄 vault strategy](https://docs.seafi.app/overview/vault-strategy-node-operation)`
         )
-        .setColor(0xaa5566)
-        .setFooter({ text: "[vault] • deposit" }),
+        .setColor(0xaa5566),
     ],
   };
 };
 
-export const XGGP_STAKING_WITHDRAW_TEMPLATE = (amount: BigNumber) => {
+export const XGGP_STAKING_WITHDRAW_TEMPLATE = (
+  amount: BigNumber,
+  caller: string
+) => {
   return {
     embeds: [
       new EmbedBuilder()
-        .setTitle(`⬇️ ${ggpAmountDisplay(amount)} tokens withdrawn.`)
+        .setTitle(
+          `⬇️ ${ggpAmountDisplay(amount)} tokens withdrawn by ${caller}.`
+        )
         .setDescription(
           `Liquidity in the vault has increased as GGP was withdrawn from a GoGoPool staker.\n[📄 vault strategy](https://docs.seafi.app/overview/vault-strategy-node-operation)`
         )
+        .setColor(0xaa4950),
+    ],
+  };
+};
+
+export const XGGP_STAKING_REWARD_TEMPLATE = (
+  transactionEvent: TransactionEvent,
+  amount: BigNumber
+) => {
+  return {
+    components: [
+      new ActionRowBuilder<ButtonBuilder>().addComponents(
+        transactionComponent(transactionEvent.hash)
+      ),
+    ],
+    embeds: [
+      new EmbedBuilder()
+        .setTitle(`🎉 ${ggpAmountDisplay(amount)} Rewarded to the Vault`)
+        .setDescription(
+          `Rewards have been claimed and distributed to the [SeaFi Vault](https://seafi.app), increasing the value of xGGP.\n[📄 vault strategy](https://docs.seafi.app/overview/vault-strategy-node-operation)`
+        )
         .setColor(0xaa4950)
-        .setFooter({ text: "[vault] • withdraw" }),
+        .setFooter({ text: "[vault] • rewards" }),
     ],
   };
 };
+
 export const REWARDS_NEW_CYCLE_TEMPLATE = ({
   rewardsCycleStartTime,
   rewardsEligibilityTime,
diff --git a/tenderly.yaml b/tenderly.yaml
index 7dbcf94..681d095 100644
--- a/tenderly.yaml
+++ b/tenderly.yaml
@@ -61,6 +61,49 @@ actions:
                 status: success
             status:
               - mined
+      vault:
+        description: vault changed.
+        function: vault:depositOrWithdraw
+        trigger:
+          type: transaction
+          transaction:
+            filters:
+              - network: 43114
+                eventEmitted:
+                  contract:
+                    address: 0xdF34022e8a280fc79499cA560439Bb6f9797EbD8
+                  name: Deposit
+                status: success
+              - network: 43114
+                eventEmitted:
+                  contract:
+                    address: 0xdF34022e8a280fc79499cA560439Bb6f9797EbD8
+                  name: Withdraw
+                status: success
+              - network: 43114
+                eventEmitted:
+                  contract:
+                    address: 0xdF34022e8a280fc79499cA560439Bb6f9797EbD8
+                  name: RewardsDistributed
+                status: success
+            status:
+              - mined
+
+      vaultRewards:
+        description: vault rewards.
+        function: vault:rewardsDistributed
+        trigger:
+          type: transaction
+          transaction:
+            filters:
+              - network: 43114
+                eventEmitted:
+                  contract:
+                    address: 0xdF34022e8a280fc79499cA560439Bb6f9797EbD8
+                  name: RewardsDistributed
+                status: success
+            status:
+              - mined
       rewards:
         description: rewards.
         function: rewards:checkRewardsPeriodic