diff --git a/src/actions-local/ggavax.spec.ts b/src/actions-local/ggavax.speca.ts similarity index 100% rename from src/actions-local/ggavax.spec.ts rename to src/actions-local/ggavax.speca.ts diff --git a/src/actions-local/ggpvault.spec.ts b/src/actions-local/ggpvault.spec.ts new file mode 100644 index 0000000..896520b --- /dev/null +++ b/src/actions-local/ggpvault.spec.ts @@ -0,0 +1,111 @@ +import { config } from "dotenv"; +import { TestRuntime } from "@tenderly/actions-test"; + +import { beforeAll, describe, test } from "vitest"; + +import { depositOrWithdraw, stakingTransactions, stateVariablesUpdated } from "../actions/ggpvault"; + +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(() => { + /* + --> Shove all of the .env variables into the test runtime. + ---> Is there a problem shoving all of them in? + -> I hope not. + */ + for (const [key, value] of Object.entries(process.env)) { + if (value) { + testRuntime.context.secrets.put(key, value); + } + } + }); + describe("deposit or withdraw", () => { + test.concurrent("withdraw", async () => { + await testRuntime.execute( + depositOrWithdraw, + require("./payload/payload-ggpvault-redeem.json") + ); + }); + test.concurrent("deposit", async () => { + await testRuntime.execute( + depositOrWithdraw, + require("./payload/payload-ggpvault-deposit.json") + ); + }); + }); + describe.skip("state variables updated", () => { + test.concurrent("GGP Cap", async () => { + await testRuntime.execute( + stateVariablesUpdated, + require("./payload/payload-ggpvault-ggpcap.json") + ); + }); + test.concurrent("Target APR", async () => { + await testRuntime.execute( + stateVariablesUpdated, + require("./payload/payload-ggpvault-targetapr.json") + ); + }); + }); + describe("staking", () => { + test.concurrent("withdrawn for staking", async () => { + await testRuntime.execute( + stakingTransactions, + require("./payload/payload-ggpvault-staking-withdraw.json") + ); + }); + test.concurrent("deposited from staking", async () => { + await testRuntime.execute( + stakingTransactions, + require("./payload/payload-ggpvault-staking-deposit.json") + ); + }); + }); + describe.skip("rewards", () => { + test.concurrent("distributed", async () => { + await testRuntime.execute( + depositOrWithdraw, + require("./payload/payload-ggpvault-rewards.json") + ); + }); + }); +}); diff --git a/src/actions-local/minipool.spec.ts b/src/actions-local/minipool.speca.ts similarity index 100% rename from src/actions-local/minipool.spec.ts rename to src/actions-local/minipool.speca.ts diff --git a/src/actions-local/payload/payload-ggpvault-deposit.json b/src/actions-local/payload/payload-ggpvault-deposit.json new file mode 100644 index 0000000..314951a --- /dev/null +++ b/src/actions-local/payload/payload-ggpvault-deposit.json @@ -0,0 +1,47 @@ +{ + "network": "43114", + "blockHash": "0xdd35896e61e31566fdd39ac8d54726d5ddd66f7906ce1a84ec6313d7df7a0cd2", + "blockNumber": 41815737, + "hash": "0xfb40ba9b9a0f7e00a269eb03fc212f2652d309ee31150bf3bc0312bad881ceec", + "from": "0xcafea1A2c9F4Af0Aaf1d5C4913cb8BA4bf0F9842", + "to": "0xdF34022e8a280fc79499cA560439Bb6f9797EbD8", + "logs": [ + { + "address": "0x69260B9483F9871ca57f81A90D91E2F96c2Cd11d", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842", + "0x000000000000000000000000df34022e8a280fc79499ca560439bb6f9797ebd8" + ], + "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000" + }, + { + "address": "0xdF34022e8a280fc79499cA560439Bb6f9797EbD8", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842" + ], + "data": "0x0000000000000000000000000000000000000000000000008ac7230489e80000" + }, + { + "address": "0xdF34022e8a280fc79499cA560439Bb6f9797EbD8", + "topics": [ + "0xdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7", + "0x000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842", + "0x000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842" + ], + "data": "0x0000000000000000000000000000000000000000000000008ac7230489e800000000000000000000000000000000000000000000000000008ac7230489e80000" + } + ], + "input": "0x6e553f650000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842", + "value": "0x0", + "nonce": "0x5", + "gas": "0x1ee34", + "gasUsed": "0x1e843", + "cumulativeGasUsed": "0x5e95e", + "gasPrice": "0x62b85e900", + "gasTipCap": "0x59682f00", + "gasFeeCap": "0x835105080", + "alertId": null +} \ No newline at end of file diff --git a/src/actions-local/payload/payload-ggpvault-redeem.json b/src/actions-local/payload/payload-ggpvault-redeem.json new file mode 100644 index 0000000..d76815a --- /dev/null +++ b/src/actions-local/payload/payload-ggpvault-redeem.json @@ -0,0 +1,48 @@ +{ + "network": "43114", + "blockHash": "0xaadc72ac18530c08c6b08d2b7cab5260bb198e3c782dca33c87ec64af1abab27", + "blockNumber": 41815748, + "hash": "0x5ca76c6e29cf2a941cc08df11b97e5e47b65ffb174b4b863718c3edb786a01dd", + "from": "0xcafea1A2c9F4Af0Aaf1d5C4913cb8BA4bf0F9842", + "to": "0xdF34022e8a280fc79499cA560439Bb6f9797EbD8", + "logs": [ + { + "address": "0xdF34022e8a280fc79499cA560439Bb6f9797EbD8", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f40000" + }, + { + "address": "0x69260B9483F9871ca57f81A90D91E2F96c2Cd11d", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000df34022e8a280fc79499ca560439bb6f9797ebd8", + "0x000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f40000" + }, + { + "address": "0xdF34022e8a280fc79499cA560439Bb6f9797EbD8", + "topics": [ + "0xfbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db", + "0x000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842", + "0x000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842", + "0x000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f400000000000000000000000000000000000000000000000000004563918244f40000" + } + ], + "input": "0xba0876520000000000000000000000000000000000000000000000004563918244f40000000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842000000000000000000000000cafea1a2c9f4af0aaf1d5c4913cb8ba4bf0f9842", + "value": "0x0", + "nonce": "0x6", + "gas": "0x15d66", + "gasUsed": "0x159be", + "cumulativeGasUsed": "0x6f8db", + "gasPrice": "0x62b85e900", + "gasTipCap": "0x59682f00", + "gasFeeCap": "0x835105080", + "alertId": null +} \ No newline at end of file diff --git a/src/actions-local/payload/payload-ggpvault-staking-deposit.json b/src/actions-local/payload/payload-ggpvault-staking-deposit.json new file mode 100644 index 0000000..fa046f4 --- /dev/null +++ b/src/actions-local/payload/payload-ggpvault-staking-deposit.json @@ -0,0 +1,81 @@ +{ + "network": "43114", + "blockHash": "0xeda985f30fb4fb502f37960fc6db87b7d36ca5c49bb2f6434619b1b695681d7b", + "blockNumber": 41815971, + "hash": "0xbef6d12330c280ed5104ca0f68017e31045d34eb7af38821c3a33de8ebc4b67c", + "from": "0x2Ff60357027861F25C7a6650564C2A606d23369d", + "to": "0xdF34022e8a280fc79499cA560439Bb6f9797EbD8", + "logs": [ + { + "address": "0x69260B9483F9871ca57f81A90D91E2F96c2Cd11d", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x000000000000000000000000df34022e8a280fc79499ca560439bb6f9797ebd8", + "0x000000000000000000000000b6ddbf75e2f0c7fc363b47b84b5c03959526aecb" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f40000" + }, + { + "address": "0x69260B9483F9871ca57f81A90D91E2F96c2Cd11d", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000df34022e8a280fc79499ca560439bb6f9797ebd8", + "0x000000000000000000000000b6ddbf75e2f0c7fc363b47b84b5c03959526aecb" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f40000" + }, + { + "address": "0xB6dDbf75e2F0C7FC363B47B84b5C03959526AecB", + "topics": [ + "0x3cd32fbc628a7c1c5a309e823125e5a4b8d98b9b31ad71d8338cc5f05829b199", + "0x0000000000000000000000002ff60357027861f25c7a6650564c2a606d23369d" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f40000" + }, + { + "address": "0x69260B9483F9871ca57f81A90D91E2F96c2Cd11d", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x000000000000000000000000b6ddbf75e2f0c7fc363b47b84b5c03959526aecb", + "0x000000000000000000000000d45cb6f5aca41afaaaebdbe4efba49c1bc41e6ba" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f40000" + }, + { + "address": "0xd45Cb6F5AcA41AfAAAeBdBE4EFBA49c1bC41E6BA", + "topics": [ + "0xc4c24354aa86aa3532ebd9da7ff92230de931c78c77fcdf84544f11bf8fae753", + "0xbea235ff677e781f981db3b8d8193dd2280c06e039b6f51dbfdad43fc6338e17", + "0x00000000000000000000000069260b9483f9871ca57f81a90d91e2f96c2cd11d" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f40000" + }, + { + "address": "0x69260B9483F9871ca57f81A90D91E2F96c2Cd11d", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000b6ddbf75e2f0c7fc363b47b84b5c03959526aecb", + "0x000000000000000000000000d45cb6f5aca41afaaaebdbe4efba49c1bc41e6ba" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f40000" + }, + { + "address": "0xdF34022e8a280fc79499cA560439Bb6f9797EbD8", + "topics": [ + "0x14438a8606c512fda07a1e9dfefc371418ed542946338bfa1c87788e903b4d68", + "0x0000000000000000000000002ff60357027861f25c7a6650564c2a606d23369d" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f40000" + } + ], + "input": "0xe591c64d0000000000000000000000000000000000000000000000004563918244f400000000000000000000000000002ff60357027861f25c7a6650564c2a606d23369d", + "value": "0x0", + "nonce": "0xf", + "gas": "0x3593e", + "gasUsed": "0x34c1c", + "cumulativeGasUsed": "0x13c6a6", + "gasPrice": "0x62b85e900", + "gasTipCap": "0x59682f00", + "gasFeeCap": "0x835105080", + "alertId": null +} \ No newline at end of file diff --git a/src/actions-local/payload/payload-ggpvault-staking-withdraw.json b/src/actions-local/payload/payload-ggpvault-staking-withdraw.json new file mode 100644 index 0000000..ff25c50 --- /dev/null +++ b/src/actions-local/payload/payload-ggpvault-staking-withdraw.json @@ -0,0 +1,37 @@ +{ + "network": "43114", + "blockHash": "0xdc43ef6b53a842eca2a85b6a8983b89e45b4493489d0caae706c537e4303231f", + "blockNumber": 41816134, + "hash": "0xe8c82f8d96cd55999da629ef44bc1434ffa85f43cfa41e44215bca5259a199c1", + "from": "0x2Ff60357027861F25C7a6650564C2A606d23369d", + "to": "0xdF34022e8a280fc79499cA560439Bb6f9797EbD8", + "logs": [ + { + "address": "0xdF34022e8a280fc79499cA560439Bb6f9797EbD8", + "topics": [ + "0x8a1d779a99a81cbb4c7490413dea3684dd84f3dfeedeec01be4d6dfc3ac6107a", + "0x0000000000000000000000002ff60357027861f25c7a6650564c2a606d23369d" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f40000" + }, + { + "address": "0x69260B9483F9871ca57f81A90D91E2F96c2Cd11d", + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x0000000000000000000000002ff60357027861f25c7a6650564c2a606d23369d", + "0x000000000000000000000000df34022e8a280fc79499ca560439bb6f9797ebd8" + ], + "data": "0x0000000000000000000000000000000000000000000000004563918244f40000" + } + ], + "input": "0x4e0614150000000000000000000000000000000000000000000000004563918244f40000", + "value": "0x0", + "nonce": "0x11", + "gas": "0x137f2", + "gasUsed": "0x134bd", + "cumulativeGasUsed": "0x44264", + "gasPrice": "0x62b85e900", + "gasTipCap": "0x59682f00", + "gasFeeCap": "0x835105080", + "alertId": null +} \ No newline at end of file diff --git a/src/actions-local/rewards.spec.ts b/src/actions-local/rewards.speca.ts similarity index 100% rename from src/actions-local/rewards.spec.ts rename to src/actions-local/rewards.speca.ts diff --git a/src/actions-local/staking.spec.ts b/src/actions-local/staking.speca.ts similarity index 100% rename from src/actions-local/staking.spec.ts rename to src/actions-local/staking.speca.ts diff --git a/src/actions/abis/ggpvault.ts b/src/actions/abis/ggpvault.ts new file mode 100644 index 0000000..ec02d66 --- /dev/null +++ b/src/actions/abis/ggpvault.ts @@ -0,0 +1,1595 @@ +export const abi = [ + { + inputs: [], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "AccessControlBadConfirmation", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + { + internalType: "bytes32", + name: "neededRole", + type: "bytes32", + }, + ], + name: "AccessControlUnauthorizedAccount", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "target", + type: "address", + }, + ], + name: "AddressEmptyCode", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "AddressInsufficientBalance", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "implementation", + type: "address", + }, + ], + name: "ERC1967InvalidImplementation", + type: "error", + }, + { + inputs: [], + name: "ERC1967NonPayable", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "allowance", + type: "uint256", + }, + { + internalType: "uint256", + name: "needed", + type: "uint256", + }, + ], + name: "ERC20InsufficientAllowance", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "sender", + type: "address", + }, + { + internalType: "uint256", + name: "balance", + type: "uint256", + }, + { + internalType: "uint256", + name: "needed", + type: "uint256", + }, + ], + name: "ERC20InsufficientBalance", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "approver", + type: "address", + }, + ], + name: "ERC20InvalidApprover", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "receiver", + type: "address", + }, + ], + name: "ERC20InvalidReceiver", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + name: "ERC20InvalidSender", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + ], + name: "ERC20InvalidSpender", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "receiver", + type: "address", + }, + { + internalType: "uint256", + name: "assets", + type: "uint256", + }, + { + internalType: "uint256", + name: "max", + type: "uint256", + }, + ], + name: "ERC4626ExceededMaxDeposit", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "receiver", + type: "address", + }, + { + internalType: "uint256", + name: "shares", + type: "uint256", + }, + { + internalType: "uint256", + name: "max", + type: "uint256", + }, + ], + name: "ERC4626ExceededMaxMint", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + internalType: "uint256", + name: "shares", + type: "uint256", + }, + { + internalType: "uint256", + name: "max", + type: "uint256", + }, + ], + name: "ERC4626ExceededMaxRedeem", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + internalType: "uint256", + name: "assets", + type: "uint256", + }, + { + internalType: "uint256", + name: "max", + type: "uint256", + }, + ], + name: "ERC4626ExceededMaxWithdraw", + type: "error", + }, + { + inputs: [], + name: "FailedInnerCall", + type: "error", + }, + { + inputs: [], + name: "InvalidInitialization", + type: "error", + }, + { + inputs: [], + name: "MathOverflowedMulDiv", + type: "error", + }, + { + inputs: [], + name: "NotInitializing", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + ], + name: "OwnableInvalidOwner", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "OwnableUnauthorizedAccount", + type: "error", + }, + { + inputs: [ + { + internalType: "address", + name: "token", + type: "address", + }, + ], + name: "SafeERC20FailedOperation", + type: "error", + }, + { + inputs: [], + name: "UUPSUnauthorizedCallContext", + type: "error", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "slot", + type: "bytes32", + }, + ], + name: "UUPSUnsupportedProxiableUUID", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "spender", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Approval", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "sender", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "assets", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "shares", + type: "uint256", + }, + ], + name: "Deposit", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "caller", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "DepositedFromStaking", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "newMax", + type: "uint256", + }, + ], + name: "GGPCapUpdated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint64", + name: "version", + type: "uint64", + }, + ], + name: "Initialized", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousOwner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "OwnershipTransferStarted", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "previousOwner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "OwnershipTransferred", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "RewardsDistributed", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "role", + type: "bytes32", + }, + { + indexed: true, + internalType: "bytes32", + name: "previousAdminRole", + type: "bytes32", + }, + { + indexed: true, + internalType: "bytes32", + name: "newAdminRole", + type: "bytes32", + }, + ], + name: "RoleAdminChanged", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "role", + type: "bytes32", + }, + { + indexed: true, + internalType: "address", + name: "account", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "sender", + type: "address", + }, + ], + name: "RoleGranted", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "role", + type: "bytes32", + }, + { + indexed: true, + internalType: "address", + name: "account", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "sender", + type: "address", + }, + ], + name: "RoleRevoked", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "newTargetAPR", + type: "uint256", + }, + ], + name: "TargetAPRUpdated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "to", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Transfer", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "implementation", + type: "address", + }, + ], + name: "Upgraded", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "sender", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "receiver", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "assets", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "shares", + type: "uint256", + }, + ], + name: "Withdraw", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "caller", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "assets", + type: "uint256", + }, + ], + name: "WithdrawnForStaking", + type: "event", + }, + { + inputs: [], + name: "APPROVED_NODE_OPERATOR", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "DEFAULT_ADMIN_ROLE", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "GGPCap", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "UPGRADE_INTERFACE_VERSION", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "acceptOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "owner", + type: "address", + }, + { + internalType: "address", + name: "spender", + type: "address", + }, + ], + name: "allowance", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "spender", + type: "address", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "approve", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "asset", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "balanceOf", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "calculateAPYFromAPR", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "shares", + type: "uint256", + }, + ], + name: "convertToAssets", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "assets", + type: "uint256", + }, + ], + name: "convertToShares", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "assets", + type: "uint256", + }, + { + internalType: "address", + name: "receiver", + type: "address", + }, + ], + name: "deposit", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "depositFromStaking", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "distributeRewards", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "getRewardsBasedOnCurrentStakedAmount", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32", + }, + ], + name: "getRoleAdmin", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getStakingContractAddress", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getUnderlyingBalance", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "ggpStorage", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32", + }, + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "grantRole", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32", + }, + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "hasRole", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_underlying", + type: "address", + }, + { + internalType: "address", + name: "_storageContract", + type: "address", + }, + { + internalType: "address", + name: "_initialOwner", + type: "address", + }, + ], + name: "initialize", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + name: "maxDeposit", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "receiver", + type: "address", + }, + ], + name: "maxMint", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "shareOwner", + type: "address", + }, + ], + name: "maxRedeem", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "shareOwner", + type: "address", + }, + ], + name: "maxWithdraw", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "shares", + type: "uint256", + }, + { + internalType: "address", + name: "receiver", + type: "address", + }, + ], + name: "mint", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "name", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "owner", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "pendingOwner", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "assets", + type: "uint256", + }, + ], + name: "previewDeposit", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "shares", + type: "uint256", + }, + ], + name: "previewMint", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "shares", + type: "uint256", + }, + ], + name: "previewRedeem", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "stakeAmount", + type: "uint256", + }, + ], + name: "previewRewardsAtStakedAmount", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "assets", + type: "uint256", + }, + ], + name: "previewWithdraw", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "proxiableUUID", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "shares", + type: "uint256", + }, + { + internalType: "address", + name: "receiver", + type: "address", + }, + { + internalType: "address", + name: "owner", + type: "address", + }, + ], + name: "redeem", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "renounceOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32", + }, + { + internalType: "address", + name: "callerConfirmation", + type: "address", + }, + ], + name: "renounceRole", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "role", + type: "bytes32", + }, + { + internalType: "address", + name: "account", + type: "address", + }, + ], + name: "revokeRole", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "GGPDepositLimit", + type: "uint256", + }, + ], + name: "setGGPCap", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "target", + type: "uint256", + }, + ], + name: "setTargetAPR", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "nodeOp", + type: "address", + }, + ], + name: "stakeAndDistributeRewards", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "address", + name: "nodeOp", + type: "address", + }, + ], + name: "stakeOnNode", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "stakingTotalAssets", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes4", + name: "interfaceId", + type: "bytes4", + }, + ], + name: "supportsInterface", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "symbol", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "targetAPR", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "totalAssets", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "totalSupply", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "transfer", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "transferFrom", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "newOwner", + type: "address", + }, + ], + name: "transferOwnership", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "newImplementation", + type: "address", + }, + { + internalType: "bytes", + name: "data", + type: "bytes", + }, + ], + name: "upgradeToAndCall", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "assets", + type: "uint256", + }, + { + internalType: "address", + name: "receiver", + type: "address", + }, + { + internalType: "address", + name: "owner", + type: "address", + }, + ], + name: "withdraw", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, +]; diff --git a/src/actions/constants.ts b/src/actions/constants.ts index c802b20..bee544f 100644 --- a/src/actions/constants.ts +++ b/src/actions/constants.ts @@ -14,6 +14,7 @@ import { abi as TokenggpAbi } from "./abis/tokenggp"; import { abi as VaultAbi } from "./abis/vault"; import { abi as WAVAXAbi } from "./abis/wavax"; import { abi as MinipoolStreamlinerAbi } from "./abis/minipoolStreamliner"; +import { abi as GGPVaultAbi } from "./abis/ggpvault"; export const isDev = process.env.NODE_ENV === "development"; @@ -40,6 +41,8 @@ export const TOKENGG_AVAX_ABI = TokenggAvaxAbi; export const TOKENGGP_ABI = TokenggpAbi; export const VAULT_ABI = VaultAbi; export const WAVAX_ABI = WAVAXAbi; +export const MINIPOOL_STREAMLINER_ABI = MinipoolStreamlinerAbi; +export const GGP_VAULT_ABI = GGPVaultAbi; export const CLAIM_NODE_OP_ADDRESS = "0xb42CfaD450B46FDc9cAC5FBF14Bc2e6091AfC35c"; @@ -64,6 +67,7 @@ export const TOKENGG_AVAX_ADDRESS = export const WAVAX_ADDRESS = "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7"; export const MINIPOOL_STREAMLINER = "0x0A75a480Af4ADC81b20b1664A1Da2bd7caEFA430"; +export const GGP_VAULT_ADDRESS = "0xdF34022e8a280fc79499cA560439Bb6f9797EbD8"; export const CLAIM_NODE_OP_INTERFACE = new utils.Interface(ClaimNodeOpAbi); export const CLAIM_PROTOCOL_DAO_INTERFACE = new utils.Interface( @@ -88,3 +92,4 @@ export const WAVAX_INTERFACE = new utils.Interface(WAVAXAbi); export const MINIPOOL_STREAMLINER_INTERFACE = new utils.Interface( MinipoolStreamlinerAbi ); +export const GGP_VAULT_INTERFACE = new utils.Interface(GGPVaultAbi); diff --git a/src/actions/ggpvault.ts b/src/actions/ggpvault.ts new file mode 100644 index 0000000..d9419da --- /dev/null +++ b/src/actions/ggpvault.ts @@ -0,0 +1,124 @@ +import { Context, Event, TransactionEvent } from "@tenderly/actions"; +import { + getDepositedFromStakingEvent, + getTargetAPRUpdatedEvent, + getWithdrawnForStakingEvent, + getXggpCapUpdatedEvent, + getXggpDepositEvent, + getXggpWithdrawEvent, +} from "./logParsing"; +import { + XGGP_DEPOSIT_DISPLAY_TEMPLATE, + XGGP_GGP_CAP_UPDATED_TEMPLATE, + XGGP_STAKING_DEPOSIT_TEMPLATE, + XGGP_STAKING_WITHDRAW_TEMPLATE, + XGGP_TARGET_APR_UPDATED_TEMPLATE, + XGGP_WITHDRAW_DISPLAY_TEMPLATE, +} from "./templates"; +import { + DepositedFromStaking, + GGPCapUpdated, + TargetAPRUpdated, + WithdrawnForStaking, + XGGPDeposit, + XGGPWithdraw, +} from "./types"; +import { initServices } from "./utils"; +import { emitter } from "./emitter"; + +const handleXggpDepositEvent = async ( + transactionEvent: TransactionEvent, + ggpDepositEvent: XGGPDeposit +) => { + await emitter.emit( + XGGP_DEPOSIT_DISPLAY_TEMPLATE(transactionEvent, ggpDepositEvent) + ); +}; + +const handleXggpWithdrawEvent = async ( + transactionEvent: TransactionEvent, + ggpWithdrawnEvent: XGGPWithdraw +) => { + const { assets } = ggpWithdrawnEvent; + await emitter.emit(XGGP_WITHDRAW_DISPLAY_TEMPLATE(transactionEvent, assets)); +}; + +const handleXggpCapUpdatedEvent = async (capUpdatedEvent: GGPCapUpdated) => { + const { newMax } = capUpdatedEvent; + await emitter.emit(XGGP_GGP_CAP_UPDATED_TEMPLATE(newMax)); +}; + +const handleXggpTargetAprUpdatedEvent = async ( + targetAprUpdatedEvent: TargetAPRUpdated +) => { + const { newTargetAPR } = targetAprUpdatedEvent; + await emitter.emit(XGGP_TARGET_APR_UPDATED_TEMPLATE(newTargetAPR)); +}; + +const handleXggpStakingDepositEvent = async ( + stakingDepositEvent: DepositedFromStaking +) => { + const { amount, caller } = stakingDepositEvent; + await emitter.emit(XGGP_STAKING_DEPOSIT_TEMPLATE(amount, caller)); +}; + +const handleXggpStakingWithdrawEvent = async ( + stakingWithdrawnEvent: WithdrawnForStaking +) => { + const { assets, caller } = stakingWithdrawnEvent; + await emitter.emit(XGGP_STAKING_WITHDRAW_TEMPLATE(assets, caller)); +}; + +export const depositOrWithdraw = async (context: Context, event: Event) => { + await initServices(context); + const transactionEvent = event as TransactionEvent; + + const xggpDepositEvent = await getXggpDepositEvent(transactionEvent); + if (xggpDepositEvent) { + await handleXggpDepositEvent(transactionEvent, xggpDepositEvent); + } else { + const xggpWithdrawEvent = await getXggpWithdrawEvent(transactionEvent); + if (!xggpWithdrawEvent) { + throw new Error("No Withdraw or Deposit event found"); + } + await handleXggpWithdrawEvent(transactionEvent, xggpWithdrawEvent); + } +}; + +export const stateVariablesUpdated = async (context: Context, event: Event) => { + await initServices(context); + const transactionEvent = event as TransactionEvent; + + const capUpdatedEvent = await getXggpCapUpdatedEvent(transactionEvent); + if (capUpdatedEvent) { + await handleXggpCapUpdatedEvent(capUpdatedEvent); + } else { + const targetAprUpdatedEvent = await getTargetAPRUpdatedEvent( + transactionEvent + ); + if (!targetAprUpdatedEvent) { + throw new Error("No Cap or Target APR event found"); + } + await handleXggpTargetAprUpdatedEvent(targetAprUpdatedEvent); + } +}; + +export const stakingTransactions = async (context: Context, event: Event) => { + await initServices(context); + const transactionEvent = event as TransactionEvent; + + const stakingDepositEvent = await getDepositedFromStakingEvent( + transactionEvent + ); + if (stakingDepositEvent) { + await handleXggpStakingDepositEvent(stakingDepositEvent); + } else { + const stakingWithdrawEvent = await getWithdrawnForStakingEvent( + transactionEvent + ); + if (!stakingWithdrawEvent) { + throw new Error("No Withdraw or Deposit event found"); + } + await handleXggpStakingWithdrawEvent(stakingWithdrawEvent); + } +}; diff --git a/src/actions/logParsing.ts b/src/actions/logParsing.ts index b67e960..e37b790 100644 --- a/src/actions/logParsing.ts +++ b/src/actions/logParsing.ts @@ -1,11 +1,21 @@ import { Log, TransactionEvent } from "@tenderly/actions"; import { Interface } from "ethers/lib/utils"; -import { TOKEN_GGAVAX_INTERFACE, STAKING_INTERFACE } from "./constants"; import { + TOKEN_GGAVAX_INTERFACE, + STAKING_INTERFACE, + GGP_VAULT_INTERFACE, +} from "./constants"; +import { + DepositedFromStaking, GGAVAXDeposit, GGAVAXWithdraw, + GGPCapUpdated, GGPStaked, GGPWithdrawn, + TargetAPRUpdated, + WithdrawnForStaking, + XGGPDeposit, + XGGPWithdraw, } from "./types"; export const getMatchingEvent = ( @@ -98,3 +108,141 @@ export const getGgAvaxDepositEvent = async ( return; } }; + +/* + +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; +} +*/ + +export const getXggpDepositEvent = async ( + transactionEvent: TransactionEvent +): Promise => { + try { + return await getMatchingEvent( + transactionEvent, + GGP_VAULT_INTERFACE, + "Deposit" + ); + } catch (e) { + return; + } +}; + +export const getXggpWithdrawEvent = async ( + transactionEvent: TransactionEvent +): Promise => { + try { + return await getMatchingEvent( + transactionEvent, + GGP_VAULT_INTERFACE, + "Withdraw" + ); + } catch (e) { + return; + } +}; + +export const getXggpCapUpdatedEvent = async ( + transactionEvent: TransactionEvent +): Promise => { + try { + return await getMatchingEvent( + transactionEvent, + GGP_VAULT_INTERFACE, + "GGPCapUpdated" + ); + } catch (e) { + return; + } +}; + +export const getTargetAPRUpdatedEvent = async ( + transactionEvent: TransactionEvent +): Promise => { + try { + return await getMatchingEvent( + transactionEvent, + GGP_VAULT_INTERFACE, + "TargetAPRUpdated" + ); + } catch (e) { + return; + } +}; + +export const getDepositedFromStakingEvent = async ( + transactionEvent: TransactionEvent +): Promise => { + try { + return await getMatchingEvent( + transactionEvent, + GGP_VAULT_INTERFACE, + "DepositedFromStaking" + ); + } catch (e) { + return; + } +}; + +export const getWithdrawnForStakingEvent = async ( + transactionEvent: TransactionEvent +): Promise => { + try { + return await getMatchingEvent( + transactionEvent, + GGP_VAULT_INTERFACE, + "WithdrawnForStaking" + ); + } catch (e) { + return; + } +}; + +export const getRewardsDistributedEvent = async ( + transactionEvent: TransactionEvent +): Promise<{ amount: string } | undefined> => { + try { + return await getMatchingEvent<{ amount: string }>( + transactionEvent, + GGP_VAULT_INTERFACE, + "RewardsDistributed" + ); + } catch (e) { + return; + } +}; diff --git a/src/actions/templates.ts b/src/actions/templates.ts index 0847222..20f67f6 100644 --- a/src/actions/templates.ts +++ b/src/actions/templates.ts @@ -10,7 +10,7 @@ import { import { BigNumber, utils } from "ethers"; import { getOrdinalDisplay, nodeHexToID } from "./utils"; import hash from "hash-emoji"; -import { RewardsInformation } from "./types"; +import { RewardsInformation, XGGPDeposit } from "./types"; export const getEmojiAddress = (address: string) => { return `${hash(address)} ${address.slice(0, 6)}...${address.slice(-4)}`; @@ -181,6 +181,15 @@ const avaxAmountDisplay = ( ...options, })} AVAX**`; +const ggpAmountDisplay = ( + amount: BigNumber, + options?: Intl.NumberFormatOptions +): string => + `**${Number(utils.formatUnits(amount, 18)).toLocaleString("en-us", { + minimumFractionDigits: 0, + ...options, + })} GGP**`; + const ggAvaxAmountField = ( amount: BigNumber, options?: Partial @@ -790,6 +799,102 @@ export const GGAVAX_WITHDRAW_DISPLAY_TEMPLATE = ( }; }; +export const XGGP_DEPOSIT_DISPLAY_TEMPLATE = ( + transactionEvent: TransactionEvent, + { assets, owner, sender, shares }: XGGPDeposit +) => { + const title = `⬆️ ${ggpAmountDisplay(assets)} Added to the Vault.`; + + return { + embeds: [ + new EmbedBuilder() + .setDescription( + `${title}\n\n[⛓️ transaction](https://snowtrace.io/tx/${ + transactionEvent.transactionHash + }) [📄 vault deposit](https://docs.seafi.app/overview/depositors) ${liquidStakerDisplay( + transactionEvent.from + )}` + ) + .setColor(0xaa5566) + .setFooter({ text: "[vault] • deposit" }), + ], + }; +}; + +export const XGGP_WITHDRAW_DISPLAY_TEMPLATE = ( + transactionEvent: TransactionEvent, + assets: BigNumber +) => { + const title = `⬇️ ${ggpAmountDisplay(assets)} Drained from the Vault.`; + return { + embeds: [ + new EmbedBuilder() + .setDescription( + `${title}\n\n[⛓️ transaction](https://snowtrace.io/tx/${ + transactionEvent.transactionHash + }) [📄 vault withdraw](https://docs.seafi.app/overview/depositors) ${liquidStakerDisplay( + transactionEvent.from + )}` + ) + .setColor(0xaa4950) + .setFooter({ text: "[vault] • withdraw" }), + ], + }; +}; + +export const XGGP_GGP_CAP_UPDATED_TEMPLATE = (newMax: BigNumber) => { + return { + embeds: [ + new EmbedBuilder() + .setTitle(`GGP Cap Updated: ${ggpAmountDisplay(newMax)}`) + .setColor(0xaa4950) + .setFooter({ text: "[vault] • variables" }), + ], + }; +}; + +export const XGGP_TARGET_APR_UPDATED_TEMPLATE = ( + targetAprBasisPoints: BigNumber +) => { + // 28 days cycles means 13 cycles per year + const apr = targetAprBasisPoints.mul(13).div(10000); + return { + embeds: [ + new EmbedBuilder() + .setTitle(`Target APY Updated: ${apr}%`) + .setColor(0xaa4950) + .setFooter({ text: "[vault] • variables" }), + ], + }; +}; + +export const XGGP_STAKING_DEPOSIT_TEMPLATE = (assets: BigNumber) => { + return { + embeds: [ + new EmbedBuilder() + .setTitle(`⬆️ ${ggpAmountDisplay(assets)} tokens added.`) + .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" }), + ], + }; +}; + +export const XGGP_STAKING_WITHDRAW_TEMPLATE = (amount: BigNumber) => { + return { + embeds: [ + new EmbedBuilder() + .setTitle(`⬇️ ${ggpAmountDisplay(amount)} tokens withdrawn.`) + .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) + .setFooter({ text: "[vault] • withdraw" }), + ], + }; +}; export const REWARDS_NEW_CYCLE_TEMPLATE = ({ rewardsCycleStartTime, rewardsEligibilityTime, diff --git a/src/actions/types.ts b/src/actions/types.ts index 8009d22..48a265b 100644 --- a/src/actions/types.ts +++ b/src/actions/types.ts @@ -40,6 +40,43 @@ export interface GGAVAXDeposit extends Event { shares: BigNumber; } +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; +} + export interface Withdrawl extends Event { src: string; wad: BigNumber;