Skip to content
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
4 changes: 2 additions & 2 deletions suspicious-funding-ts/package-lock.json

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

4 changes: 2 additions & 2 deletions suspicious-funding-ts/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "suspicious-funding",
"displayName": "Suspicious Funding Detector",
"version": "0.0.3",
"displayName": "Suspicious Funding Detector Beta",
"version": "0.0.4",
"description": "Detects suspicious funding transactions",
"repository": "https://github.com/forta-network/starter-kits/tree/main/suspicious-funding-ts",
"licenseUrl": "https://github.com/forta-network/forta-bot-sdk/blob/master/starter-project/LICENSE.md",
Expand Down
1 change: 1 addition & 0 deletions suspicious-funding-ts/publish.log
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Wed, 27 Mar 2024 16:18:40 GMT: successfully added agent id 0x90596fcef715e22cc073fdc7018039e7af742276dda1baed03032411480c65fd with manifest QmX2iXSh6c6Vh99m8yxpZ5HVaMNAJjBp6WNnVNMD4P3mEt
Thu, 28 Mar 2024 14:59:07 GMT: successfully updated agent id 0x90596fcef715e22cc073fdc7018039e7af742276dda1baed03032411480c65fd with manifest QmPSiK26ABh2J7BpB1W33bKNCzmBAB7v1NTY1dAxfxg68D
Thu, 04 Jul 2024 11:28:45 GMT: successfully added agent id 0x42e35e2f439bb673c8fdb705f48f502b532b4ab41088c30e84792d0bcc3b885a with manifest QmYPvU6qqGm8z86Hz9GqT74DYpRq9akMrGyoBbB9gzgv2d
36 changes: 23 additions & 13 deletions suspicious-funding-ts/src/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,22 @@ import {
TRUE_POSITIVE_LIST_URL,
TRUE_POSITIVE_LIST_PATH,
ETH_BLOCKS_IN_ONE_DAY,
THREE_SECOND_BLOCKS_IN_ONE_DAY
THREE_SECOND_BLOCKS_IN_ONE_DAY,
} from "./constants";
import { createFinding, getAllLabels } from "./utils";
import TruePositiveFetcher from "./truePositive.fetcher"
import TruePositiveFetcher from "./truePositive.fetcher";

const ethersProvider = getEthersProvider();
const attackers = new Map<string, { origin: string; hops: number }>();
let truePositiveFetcher: TruePositiveFetcher = new TruePositiveFetcher(TRUE_POSITIVE_LIST_URL, TRUE_POSITIVE_LIST_PATH);
let truePositiveFetcher: TruePositiveFetcher = new TruePositiveFetcher(
TRUE_POSITIVE_LIST_URL,
TRUE_POSITIVE_LIST_PATH
);
let chainId: number;

export const provideInitialize =
(provider: ethers.providers.Provider, fetcher: TruePositiveFetcher) => async () => {
(provider: ethers.providers.Provider, fetcher: TruePositiveFetcher) =>
async () => {
chainId = Number((await provider.getNetwork()).chainId);

const query: LabelQueryOptions = {
Expand All @@ -53,6 +57,10 @@ export const provideInitialize =
},
{
botId: BOTS_TO_MONITOR[2],
alertIds: ["FUNDING-CHANGENOW-NEW-ACCOUNT"],
},
{
botId: BOTS_TO_MONITOR[3],
alertIds: ["EARLY-ATTACK-DETECTOR-1"],
},
],
Expand Down Expand Up @@ -95,18 +103,20 @@ export const provideHandleTransaction =
return findings;
};

export const provideHandleBlock = (fetcher: TruePositiveFetcher) => async (blockEvent: BlockEvent) => {
const findings: Finding[] = [];
export const provideHandleBlock =
(fetcher: TruePositiveFetcher) => async (blockEvent: BlockEvent) => {
const findings: Finding[] = [];

// Choosing the denominator based on chain's block time
// so as to update TP list approx. once daily
const DAILY_BLOCKS_DENOMINATOR = chainId == 1 ? ETH_BLOCKS_IN_ONE_DAY : THREE_SECOND_BLOCKS_IN_ONE_DAY;
if (blockEvent.blockNumber % DAILY_BLOCKS_DENOMINATOR == 0) {
// Choosing the denominator based on chain's block time
// so as to update TP list approx. once daily
const DAILY_BLOCKS_DENOMINATOR =
chainId == 1 ? ETH_BLOCKS_IN_ONE_DAY : THREE_SECOND_BLOCKS_IN_ONE_DAY;
if (blockEvent.blockNumber % DAILY_BLOCKS_DENOMINATOR == 0) {
await fetcher.getTruePositiveList(attackers);
}
}

return findings;
};
return findings;
};

const handleAlert: HandleAlert = async (alertEvent: AlertEvent) => {
const findings: Finding[] = [];
Expand Down
21 changes: 12 additions & 9 deletions suspicious-funding-ts/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
export const BOTS_TO_MONITOR = [
"0xa91a31df513afff32b9d85a2c2b7e786fdd681b3cdd8d93d6074943ba31ae400", // funding tornado cash
"0x2d3bb89e9cecc0024d8ae1a9c93ca42664472cb074cc200fa2c0f77f2be34bf3", // funding fixed float
"0x9324d7865e1bcb933c19825be8482e995af75c9aeab7547631db4d2cd3522e0e", // funding change now
"0x80ed808b586aeebe9cdd4088ea4dea0a8e322909c0e4493c993e060e89c09ed1", // attack detector
"0x90596fcef715e22cc073fdc7018039e7af742276dda1baed03032411480c65fd", // suspicious funding
];

export const DAYS_TO_LOOK_BACK = 3;

// Around $5000 at the time of the update
// Around $11500 at the time of the update
export const VALUE_THRESHOLDS: Record<number, number> = {
1: 1.4,
10: 1.4,
56: 9,
137: 8300,
250: 8000,
42161: 1.4,
43114: 160,
1: 5,
10: 5,
56: 22,
137: 30000,
250: 24000,
42161: 5,
43114: 485,
};

export const alertOriginMap = {
"TORNADO-CASH": "Tornado Cash",
"FIXED-FLOAT": "Fixed Float",
"CHANGENOW": "ChangeNow",
"ATTACK-DETECTOR": "Attack Detector",
};

Expand All @@ -34,4 +36,5 @@ export const THREE_SECOND_BLOCKS_IN_ONE_DAY = ONE_DAY / THREE_SECOND_BLOCK_TIME;

export const TRUE_POSITIVE_LIST_PATH = "../tp_list.csv";
// Using the Early Attack Detector True Positive list as source of truth
export const TRUE_POSITIVE_LIST_URL = "https://raw.githubusercontent.com/forta-network/starter-kits/main/early-attack-detector-py/tp_list.csv"
export const TRUE_POSITIVE_LIST_URL =
"https://raw.githubusercontent.com/forta-network/starter-kits/main/early-attack-detector-py/tp_list.csv";