Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forta Alert update #49

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 5 additions & 12 deletions agents/bot-operations-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@

## Alerts

- BNBx-REWARD-CHANGE

- Fired when Reward changes by more than 0.5 %
- Severity is set to "Medium"
- Type is set to "Info"
- metadata: lastRewardAmount, curentRewardAmount

- BNBx-DAILY-REWARDS

- Fired when Daily Rewards is not executed
Expand All @@ -22,35 +15,35 @@

- BNBx-START-DELEGATION

- Fired when StartDelegation is not executed for 36 hours
- Fired when StartDelegation is not executed for 48 hours
- Severity is set to "Critical"
- Type is set to "Info"
- metadata: lastStartDelegationTime

- BNBx-COMPLETE-DELEGATION

- Fired when CompleteDelegation is not executed for 12 hours past StartDelegation
- Fired when CompleteDelegation is not executed for 1 hour past StartDelegation
- Severity is set to "Critical"
- Type is set to "Info"
- metadata: lastStartDelegationTime, lastCompleteDelegationTime

- BNBx-START-UNDELEGATION

- Fired when StartUndelegation is not executed for 7 days and 1 hours
- Fired when StartUndelegation is not executed for 10 mins past its schedule time
- Severity is set to "Critical"
- Type is set to "Info"
- metadata: lastStartUndelegationTime

- BNBx-UNDELEGATION-UPDATE

- Fired when undelegationStarted is not executed for 12 hours past StartUndelegation
- Fired when undelegationStarted is not executed for 30 Mins past StartUndelegation
- Severity is set to "Critical"
- Type is set to "Info"
- metadata: lastStartDelegationTime, lastUndelegationUpdateTime

- BNBx-COMPLETE-UNDELEGATION

- Fired when CompleteUndelegation is not executed for 8 days and 12 hours past StartUndelegation
- Fired when CompleteUndelegation is not executed for 7 days and 3 hours past StartUndelegation
- Severity is set to "Critical"
- Type is set to "Info"
- metadata: lastStartUndelegationTime, lastCompleteUndelegationTime
4 changes: 2 additions & 2 deletions agents/bot-operations-agent/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion agents/bot-operations-agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.0.1",
"description": "Alerts on Off Chain Bot Delays and Failures",
"chainIds": [
1
56
],
"scripts": {
"build": "tsc",
Expand Down
1 change: 1 addition & 0 deletions agents/bot-operations-agent/publish.log
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ Tue, 30 Aug 2022 19:58:56 GMT: successfully added agent id 0xb62f2ab23098094bf40
Wed, 31 Aug 2022 20:59:13 GMT: successfully updated agent id 0xb62f2ab23098094bf40db49a7379222d44f94bc656cd67906cf173b2eadb2e9c with manifest QmVKTNiRU9k4naWSwVNK54GovBfVzd7xTin77hFp31g7yK
Mon, 05 Sep 2022 18:28:37 GMT: successfully updated agent id 0xb62f2ab23098094bf40db49a7379222d44f94bc656cd67906cf173b2eadb2e9c with manifest QmYKn7Ytmdi6BWCS1McXiYME3VoSwNaejHqicjnWX4axEs
Wed, 07 Sep 2022 19:30:06 GMT: successfully updated agent id 0xb62f2ab23098094bf40db49a7379222d44f94bc656cd67906cf173b2eadb2e9c with manifest QmWDUsnKTu2FTq9UXpSeJcEu9FiFjBiyoqnoqWnsPc5gzq
Thu, 22 Dec 2022 16:28:37 GMT: successfully updated agent id 0xb62f2ab23098094bf40db49a7379222d44f94bc656cd67906cf173b2eadb2e9c with manifest QmRjvzT164q3cEpYqCD6HJ4KK13sLWtRM8J17SCP9JR1cY
173 changes: 74 additions & 99 deletions agents/bot-operations-agent/src/agent.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { BigNumber } from "ethers";
import {
Finding,
FindingSeverity,
Expand All @@ -12,24 +11,21 @@ import {
COMPLETE_UNDELEGATION_DELAY,
COMPLETE_UNDELEGATION_FN,
protocol,
REWARD_CHANGE_BPS,
REWARD_DELAY_HOURS,
REWARD_EVENT,
STAKE_MANAGER,
START_DELEGATION_DELAY,
START_DELEGATION_FN,
START_UNDELEGATION_DELAY,
START_UNDELEGATION_DELAY_MINS,
START_UNDELEGATION_FN,
TOTAL_BPS,
UNDELEGATION_UPDATE_DELAY,
UNDELEGATION_UPDATE_DELAY_MINS,
UNDELEGATION_UPDATE_FN,
} from "./constants";

import { getHours } from "./utils";
import { getHours, getMins } from "./utils";

let dailyRewardsFailed: boolean,
lastRewardsTime: Date,
lastRewardAmount: BigNumber;
let dailyRewardsFailed: boolean, lastRewardsTime: Date;

let lastStartDelegationTime: Date, startDelegationFailed: boolean;
let lastCompleteDelegationTime: Date, completeDelegationFailed: boolean;
Expand All @@ -43,7 +39,7 @@ const handleTransaction: HandleTransaction = async (
) => {
const findings: Finding[] = (
await Promise.all([
// handleRewardTransaction(txEvent),
handleRewardTransaction(txEvent),
handleStartDelegationTransaction(txEvent),
handleCompleteDelegationTransaction(txEvent),
handleStartUndelegationTransaction(txEvent),
Expand All @@ -55,73 +51,44 @@ const handleTransaction: HandleTransaction = async (
return findings;
};

// const handleRewardTransaction: HandleTransaction = async (
// txEvent: TransactionEvent
// ) => {
// const findings: Finding[] = [];
// const bnbxRewardEvents = txEvent.filterLog(REWARD_EVENT, STAKE_MANAGER);

// if (bnbxRewardEvents.length) {
// const { _amount } = bnbxRewardEvents[0].args;
// if (lastRewardsTime) {
// if (
// lastRewardAmount
// .sub(_amount)
// .abs()
// .gt(lastRewardAmount.mul(REWARD_CHANGE_BPS).div(TOTAL_BPS))
// ) {
// findings.push(
// Finding.fromObject({
// name: "Significant Reward Change",
// description: `Reward changed more than ${
// (REWARD_CHANGE_BPS * 100) / TOTAL_BPS
// } %`,
// alertId: "BNBx-REWARD-CHANGE",
// protocol: protocol,
// severity: FindingSeverity.Medium,
// type: FindingType.Info,
// metadata: {
// lastRewardAmount: lastRewardAmount.toString(),
// cuurentRewardAmount: _amount.toString(),
// },
// })
// );
// }
// }

// lastRewardsTime = new Date();
// dailyRewardsFailed = false;
// lastRewardAmount = _amount;

// return findings;
// }

// if (!lastRewardsTime) return findings;

// if (dailyRewardsFailed) return findings;

// const currentTime = new Date();
// const diff = currentTime.getTime() - lastRewardsTime.getTime();
// const diffHours = getHours(diff);
// if (diffHours > REWARD_DELAY_HOURS) {
// findings.push(
// Finding.fromObject({
// name: "Daily Rewards Failed",
// description: `Daily Rewards Autocompund not invoked since ${REWARD_DELAY_HOURS} Hours`,
// alertId: "BNBx-DAILY-REWARDS",
// protocol: protocol,
// severity: FindingSeverity.Critical,
// type: FindingType.Info,
// metadata: {
// lastRewardsTime: lastRewardsTime.toUTCString(),
// },
// })
// );
// dailyRewardsFailed = true;
// }

// return findings;
// };
const handleRewardTransaction: HandleTransaction = async (
txEvent: TransactionEvent
) => {
const findings: Finding[] = [];
const bnbxRewardEvents = txEvent.filterLog(REWARD_EVENT, STAKE_MANAGER);

if (bnbxRewardEvents.length) {
lastRewardsTime = new Date();
dailyRewardsFailed = false;
return [];
}

if (!lastRewardsTime) return [];

if (dailyRewardsFailed) return [];

const currentTime = new Date();
const diff = currentTime.getTime() - lastRewardsTime.getTime();
const diffHours = getHours(diff);
if (diffHours > REWARD_DELAY_HOURS) {
findings.push(
Finding.fromObject({
name: "Daily Rewards Failed",
description: `Rewards Autocompound not invoked since ${REWARD_DELAY_HOURS} Hours`,
alertId: "BNBx-DAILY-REWARDS",
protocol: protocol,
severity: FindingSeverity.Critical,
type: FindingType.Info,
metadata: {
lastRewardsTime: lastRewardsTime.toUTCString(),
},
})
);
dailyRewardsFailed = true;
}

return findings;
};

const handleStartDelegationTransaction: HandleTransaction = async (
txEvent: TransactionEvent
Expand All @@ -132,15 +99,18 @@ const handleStartDelegationTransaction: HandleTransaction = async (
STAKE_MANAGER
);

// found startDelegation -> no alert
if (startDelegationInvocations.length) {
lastStartDelegationTime = new Date();
startDelegationFailed = false;
return findings;
return [];
}

if (!lastStartDelegationTime) return findings;
// startDelegation not invoked since forta bot deployment -> no alert
if (!lastStartDelegationTime) return [];

if (startDelegationFailed) return findings;
// already alerted earlier -> repeated alert will make channel noisy
if (startDelegationFailed) return [];

const currentTime = new Date();
const diff = currentTime.getTime() - lastStartDelegationTime.getTime();
Expand Down Expand Up @@ -177,27 +147,27 @@ const handleCompleteDelegationTransaction: HandleTransaction = async (
if (completeDelegationInvocations.length) {
lastCompleteDelegationTime = new Date();
completeDelegationFailed = false;
return findings;
return [];
}

if (!lastStartDelegationTime || !lastCompleteDelegationTime) {
return findings;
return [];
}

if (startDelegationFailed || completeDelegationFailed) return findings;
if (startDelegationFailed || completeDelegationFailed) return [];

const currentTime = new Date();
const diff = currentTime.getTime() - lastStartDelegationTime.getTime();
const diffHours = getHours(diff);

if (
diffHours > COMPLETE_DELEGATION_DELAY &&
diffHours >= COMPLETE_DELEGATION_DELAY &&
lastStartDelegationTime.getTime() > lastCompleteDelegationTime.getTime()
) {
findings.push(
Finding.fromObject({
name: "Complete Delegation Failed",
description: `Complete Delegation not invoked since ${COMPLETE_DELEGATION_DELAY} Hours past last Start Delegation`,
description: `Complete Delegation not invoked since ${COMPLETE_DELEGATION_DELAY} Hour past last Start Delegation`,
alertId: "BNBx-COMPLETE-DELEGATION",
protocol: protocol,
severity: FindingSeverity.Critical,
Expand Down Expand Up @@ -226,21 +196,26 @@ const handleStartUndelegationTransaction: HandleTransaction = async (
if (startUndelegationInvocations.length) {
lastStartUndelegationTime = new Date();
startUndelegationFailed = false;
return findings;
return [];
}

if (!lastStartUndelegationTime) return findings;
if (!lastStartUndelegationTime) return [];

if (startUndelegationFailed) return findings;
if (startUndelegationFailed) return [];

const currentTime = new Date();
const diff = currentTime.getTime() - lastStartUndelegationTime.getTime();
const diffHours = getHours(diff);
if (diffHours > START_UNDELEGATION_DELAY) {
const diffMins = getMins(diff);

if (
diffHours >= START_UNDELEGATION_DELAY &&
diffMins >= START_UNDELEGATION_DELAY_MINS
) {
findings.push(
Finding.fromObject({
name: "Start Undelegation Failed",
description: `Start Undelegation not invoked since ${START_UNDELEGATION_DELAY} Hours`,
description: `Start Undelegation not invoked ${START_UNDELEGATION_DELAY_MINS} Mins since its schedule time`,
alertId: "BNBx-START-UNDELEGATION",
protocol: protocol,
severity: FindingSeverity.Critical,
Expand Down Expand Up @@ -268,27 +243,27 @@ const handleUndelegationUpdateTransaction: HandleTransaction = async (
if (UndelegationUpdateInvocations.length) {
lastUndelegationUpdateTime = new Date();
undelegationUpdateFailed = false;
return findings;
return [];
}

if (!lastStartUndelegationTime || !lastUndelegationUpdateTime) {
return findings;
return [];
}

if (startUndelegationFailed || undelegationUpdateFailed) return findings;
if (startUndelegationFailed || undelegationUpdateFailed) return [];

const currentTime = new Date();
const diff = currentTime.getTime() - lastStartUndelegationTime.getTime();
const diffHours = getHours(diff);
const diffMins = getMins(diff);

if (
diffHours > UNDELEGATION_UPDATE_DELAY &&
diffMins >= UNDELEGATION_UPDATE_DELAY_MINS &&
lastStartUndelegationTime.getTime() > lastUndelegationUpdateTime.getTime()
) {
findings.push(
Finding.fromObject({
name: "Undelegation Update Failed",
description: `Undelegation not invoked at Beacon Chain since ${UNDELEGATION_UPDATE_DELAY} Hours past last Start UnDelegation`,
description: `Undelegation not invoked at Beacon Chain since ${UNDELEGATION_UPDATE_DELAY_MINS} Mins past last Start UnDelegation`,
alertId: "BNBx-UNDELEGATION-UPDATE",
protocol: protocol,
severity: FindingSeverity.Critical,
Expand Down Expand Up @@ -317,21 +292,21 @@ const handleCompleteUndelegationTransaction: HandleTransaction = async (
if (completeUndelegationInvocations.length) {
lastCompleteUndelegationTime = new Date();
completeUndelegationFailed = false;
return findings;
return [];
}

if (!lastStartUndelegationTime || !lastCompleteUndelegationTime) {
return findings;
return [];
}

if (startUndelegationFailed || completeUndelegationFailed) return findings;
if (startUndelegationFailed || completeUndelegationFailed) return [];

const currentTime = new Date();
const diff = currentTime.getTime() - lastStartUndelegationTime.getTime();
const diffHours = getHours(diff);

if (
diffHours > COMPLETE_UNDELEGATION_DELAY &&
diffHours >= COMPLETE_UNDELEGATION_DELAY &&
lastStartUndelegationTime.getTime() > lastCompleteUndelegationTime.getTime()
) {
findings.push(
Expand Down
Loading