GitCoin_attack/attack_vector.ipynb

492 lines
67 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "continent-northeast",
"metadata": {},
"source": [
"# Attack scenario implementation in Gitcoin Collusion Studies\n",
"This is a notebook with a simple implementation of different type of attack vectors. Detailed conceptual and math reasoning can be found in [this presentation slides](https://drive.google.com/file/d/1Y68YnHIybMNLDUSgGc_Q_Um_6FbVbElh/view?usp=sharing)\n",
"*access is restricted to BlockScience Internal view only*\n",
"\n",
"## 1. Brief Introduction\n",
"### Optimality Gap Mechanism Overview\n",
"Our current proposed solution in the Gitcoin resarch collaboration project is to: \n",
"Define community subgraph -> Find optimal funding scheme by changing the connectivity within the community to produce the maximum amount of matching funds -> Report/Flag Collusion if threshold for optimization is above a specified amount\n",
"\n",
"In QF funding collusion problem, the colluder's goal is to **attract as much matching fund as possible with limited original funding**, thus, our goal is to detect what group of users are attracting matching funds most efficiently by calculating the gap between maximun value of funds attracted and actual funds attracted.\n",
"\n",
"### Benchmarking \n",
"\n",
"Thoeretically our solution can detect all efficient funding matching schemes, among which might be effective illegal collusion, and likely some efficient organic community coordination. To further illustrate our point, we want to showcase how our algorithm can catch existing as well as hypothetical scenarios for collusion.\n",
"\n",
"Here we constructed several different collusion scenarios **based on Gitcoin Funding Report** and other mathematically possible ways to exploit native QF and pairwise funding scheme. "
]
},
{
"cell_type": "markdown",
"id": "conditional-improvement",
"metadata": {},
"source": [
"## 2.Basic generating function\n",
"This section is some hand-coded set up for agent-based simulation of attack vectors in the Gitcoin Grants system. \n",
"\n",
"This simulation has two types of agents: grants and contributors. Grants can receive funds and contributors can give fund to grants. They all have a variable \"fund\" to keep track of how much money they have as a system state.\n",
"\n",
"We then create a network with a set of users and grants, with rules to specify how it should connect.\n",
"\n",
"Finally, for easy access, I use a dictionary to keep track of the users and grants by their index. The index starts from 0, first labelling all grants and then contributors. For example, in a network with 2 grants and 5 contributors, the grants index are 0 and 1, and the user index will be from 3 to 7.\n",
"\n",
"This simple simulation **does not keep track of time**."
]
},
{
"cell_type": "code",
"execution_count": 64,
"id": "several-pathology",
"metadata": {},
"outputs": [],
"source": [
"#Element Testing\n",
"import matplotlib.pyplot as plt\n",
"import networkx as nx\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 65,
"id": "clean-drink",
"metadata": {},
"outputs": [],
"source": [
"#make agents\n",
"class grant:\n",
" def __init__(self , i, f=0):\n",
" self.type = \"grants\"\n",
" self.index = i \n",
" self.fund = f \n",
" \n",
" def receive(self, i):\n",
" self.fund += i \n",
"\n",
" def change_fund(self,x):\n",
" self.fund = x\n",
"\n",
"class user:\n",
" def __init__(self,i,f=0):\n",
" self.type = \"users\"\n",
" self.index = i #to keep track of the networkX property\n",
" self.fund = f #volum of money avliable or received\n",
" \n",
" def give(self, i, grant):\n",
" self.fund -= i\n",
" grant.receive(i)\n",
" return(self.index)\n",
" \n",
" def change_fund(self,x):\n",
" self.fund = x"
]
},
{
"cell_type": "code",
"execution_count": 66,
"id": "average-mills",
"metadata": {},
"outputs": [],
"source": [
"#make topology\n",
"## the idea is to construct a graph with a unique index for each node \n",
"## then allow agents to interact with each other"
]
},
{
"cell_type": "code",
"execution_count": 73,
"id": "bound-endorsement",
"metadata": {},
"outputs": [],
"source": [
"#initialize nwetwork\n",
"def initialize_network(network, grant_set, user_set):\n",
" directory = {}\n",
" #grant first, user next\n",
" for i in grant_set:\n",
" directory.update({i:grant(i)})\n",
" for i in user_set:\n",
" directory.update({i:user(i)})\n",
" return(directory)\n",
"\n",
"#assign initial funding situation\n",
"def add_fund(directory,grant_set, user_set,grant_money,user_money):\n",
" for i in grant_set:\n",
" grant_a = directory.get(i)\n",
" grant_a.change_fund(grant_money[i])\n",
" extra = len(grant_set)\n",
" for i in user_set:\n",
" user_a = directory.get(i)\n",
" user_a.change_fund(user_money[i-extra])\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "innocent-climb",
"metadata": {},
"outputs": [],
"source": [
"#initialize network, add fund and then give funds"
]
},
{
"cell_type": "markdown",
"id": "following-computer",
"metadata": {},
"source": [
"## 3. Collusion with fake accounts or friends\n",
"This type of collusion is primarily having a lot of coordinated users donate to the same big project. In practice, this can be creating a large number of fake accounts (which is tackled by sybil detection), or coordinating a large group on telegram or other more advanced coordination mechanism that could involve stake, or even spliting money among a large group of friends.\n",
"\n",
"According to QF and pair-wise funding mechanism, this type of attack attracts the largest amount of matching funds by spliting the money evenly and into smallest portion possible. Hypothetically, optimality gap shall allow calcualtion **based on changing numbers of total account with fixed amount of funding** on top of the current implimentation to be able to detect thsi type of collusion."
]
},
{
"cell_type": "code",
"execution_count": 68,
"id": "fancy-greenhouse",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#one grand vis\n",
"grants = {0}\n",
"tot = set(range(20))\n",
"users = tot.difference(grants)\n",
"\n",
"G = nx.Graph()\n",
"G.add_nodes_from(tot)\n",
"\n",
"for i in users:\n",
" G.add_edge(0,i)\n",
"# can also be G = nx.star_graph(20)\n",
"pos = nx.spring_layout(G)\n",
"nx.draw(G, pos)\n",
"plt.show()\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 74,
"id": "worldwide-progressive",
"metadata": {},
"outputs": [],
"source": [
"#initialize network agents\n",
"di = initialize_network(G,grants,users)"
]
},
{
"cell_type": "code",
"execution_count": 75,
"id": "reduced-literature",
"metadata": {},
"outputs": [],
"source": [
"#initialize money\n",
"grant_money = [0]\n",
"user_money = []\n",
"for i in range(len(users)):\n",
" user_money.append(100)\n",
"\n",
"add_fund(di,grants,users,grant_money,user_money)"
]
},
{
"cell_type": "code",
"execution_count": 82,
"id": "identified-produce",
"metadata": {},
"outputs": [],
"source": [
"#pay\n",
"grant_a = di.get(0)\n",
"for i in users:\n",
" user_a = di.get(i)\n",
" user_a.give(50,grant_a)\n",
" \n"
]
},
{
"cell_type": "code",
"execution_count": 83,
"id": "potential-welcome",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"950 grants\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n",
"50 users\n"
]
}
],
"source": [
"for i in range(20):\n",
" print(di.get(i).fund,di.get(i).type)"
]
},
{
"cell_type": "code",
"execution_count": 67,
"id": "super-turner",
"metadata": {},
"outputs": [],
"source": [
"# TODO visualize again with color and label\n",
"# TODO run optimality gap algorithm on it\n",
"# TODO turn this into a proper blog-postable material or do a live coding demo"
]
},
{
"cell_type": "markdown",
"id": "level-vanilla",
"metadata": {},
"source": [
"## 4. Collusion with multiple small/fake projects\n"
]
},
{
"cell_type": "code",
"execution_count": 133,
"id": "loaded-boston",
"metadata": {},
"outputs": [],
"source": [
"#initialize grants as sets\n",
"grants = set(range(3))\n",
"tot = set(range(12))\n",
"users = tot.difference(grants)"
]
},
{
"cell_type": "code",
"execution_count": 134,
"id": "annual-brisbane",
"metadata": {},
"outputs": [],
"source": [
"edge_list = [(0,3),(0,4),(0,5),(0,6),(1,6),(1,7),(1,8),(1,9),(2,9),(2,10),(2,11)]\n"
]
},
{
"cell_type": "code",
"execution_count": 135,
"id": "changed-reynolds",
"metadata": {},
"outputs": [],
"source": [
"#make graph\n",
"from networkx.algorithms import bipartite\n",
"\n",
"G2 = nx.Graph()\n",
"# Add nodes with the node attribute \"bipartite\"\n",
"G2.add_nodes_from(grants,bipartite=0)\n",
"G2.add_nodes_from(users,bipartite=1)\n",
"# Add nodes with the node attribute \"bipartite\"\n",
"G2.add_edges_from(edge_list)\n"
]
},
{
"cell_type": "code",
"execution_count": 136,
"id": "purple-point",
"metadata": {},
"outputs": [],
"source": [
"color_dic = nx.bipartite.color(G2)\n",
"color_map = []\n",
"for i in range(12):\n",
" if color_dic.get(i) == 1:\n",
" color_map.append('#ED553B') # red\n",
" else:\n",
" color_map.append('#3CAEA3') # green "
]
},
{
"cell_type": "code",
"execution_count": 137,
"id": "textile-focus",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"#And I made it pretty\n",
"top = nx.bipartite.sets(G2)[0]\n",
"pos = nx.bipartite_layout(G2, top)\n",
"\n",
"nx.draw(G2,pos, with_labels=True , node_size=300,node_color=color_map,alpha = 0.8)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 138,
"id": "specified-photography",
"metadata": {},
"outputs": [],
"source": [
"#initialize network agents\n",
"di2 = initialize_network(G2,grants,users)"
]
},
{
"cell_type": "code",
"execution_count": 139,
"id": "normal-indiana",
"metadata": {},
"outputs": [],
"source": [
"#initialize money\n",
"grant_money = [0,0,0]\n",
"user_money = []\n",
"for i in range(len(users)):\n",
" user_money.append(100)\n",
"\n",
"add_fund(di2,grants,users,grant_money,user_money)"
]
},
{
"cell_type": "code",
"execution_count": 143,
"id": "guilty-unknown",
"metadata": {},
"outputs": [],
"source": [
"#pay\n",
"for i in edge_list: \n",
" grant_a = di2.get(i[0])\n",
" user_a = di2.get(i[1]) \n",
" user_a.give(10,grant_a)"
]
},
{
"cell_type": "code",
"execution_count": 144,
"id": "dated-competition",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"40 grants\n",
"40 grants\n",
"30 grants\n",
"80 users\n",
"80 users\n",
"80 users\n",
"60 users\n",
"80 users\n",
"80 users\n",
"60 users\n",
"80 users\n",
"80 users\n"
]
}
],
"source": [
"for i in range(12):\n",
" print(di2.get(i).fund,di2.get(i).type)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "human-slovenia",
"metadata": {},
"outputs": [],
"source": [
"# TODO visualize again with color and label\n",
"# TODO run optimality gap algorithm on it\n",
"# TODO turn this into a proper blog-postable material or do a live coding demo"
]
},
{
"cell_type": "markdown",
"id": "integrated-morocco",
"metadata": {},
"source": [
"## 5. Futher Implication: two major type of collusion generation: connectivity and account numbers\n",
"As I explored earlier in this example, the Optimality Gap mechanism can catch both scenario"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "hollywood-astrology",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}