1
+ # -*- coding: utf-8 -*-
2
+ """
3
+
4
+ Copyright (C) 2021 Gitcoin Core
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU Affero General Public License as published
8
+ by the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU Affero General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Affero General Public License
17
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+
19
+ """
20
+
21
+ from pprint import pprint
22
+
23
+ from django .conf import settings
24
+ from django .core .management .base import BaseCommand
25
+ from django .utils import timezone
26
+
27
+ import requests
28
+ from grants .models import Grant
29
+
30
+ import time
31
+ from web3 import Web3
32
+ from decimal import *
33
+
34
+ class Command (BaseCommand ):
35
+
36
+ help = 'pulls data from https://twitter.com/austingriffith/status/1529825114597908484 and inserts into db'
37
+
38
+ def handle (self , * args , ** options ):
39
+
40
+ def run_query (q , url ):
41
+ request = requests .post (url ,
42
+ '' ,
43
+ json = {'query' : q })
44
+ if request .status_code == 200 :
45
+ return request .json ()
46
+ else :
47
+ raise Exception ('Query failed. return code is {}. {}' .format (request .status_code , query ))
48
+
49
+ queryGrants = """
50
+ query getGrants {
51
+ grants(orderBy: id, orderDirection: asc, first: 100) {
52
+ id
53
+ votes {
54
+ id
55
+ amount
56
+ createdAt
57
+ }
58
+ releases {
59
+ id
60
+ voteId
61
+ amount
62
+ createdAt
63
+ }
64
+ }
65
+ }
66
+ """
67
+
68
+ urls = []
69
+ if not settings .DEBUG or True :
70
+ urls += ['https://api.studio.thegraph.com/query/20308/gtc-conviction-voting-mainnet/v0.0.2' ]
71
+ urls += ['https://api.thegraph.com/subgraphs/name/danielesalatti/gtc-conviction-voting-optimism' ]
72
+ else :
73
+ urls += ['https://api.thegraph.com/subgraphs/name/danielesalatti/gtc-conviction-voting-rinkeby' ]
74
+
75
+
76
+ maxMultiplier = 50
77
+ secondsInSixMonths = 60 * 60 * 24 * 30 * 6
78
+ alphaDecay = 0.8
79
+ beta = pow (maxMultiplier , 1 / secondsInSixMonths ) - 1
80
+
81
+ def mapReleasesToVoteId (grant ):
82
+ releases = grant ['releases' ]
83
+ releaseByVoteId = {}
84
+ for release in releases :
85
+ releaseByVoteId [int (release ['voteId' ])] = release
86
+ return releaseByVoteId
87
+
88
+ def calculate_voting_power (grant ):
89
+ totalVotingPower = 0
90
+
91
+ releaseByVoteId = mapReleasesToVoteId (grant )
92
+
93
+ for vote in grant ['votes' ]:
94
+ secondsSinceVote = (time . time () - int (vote ['createdAt' ]))
95
+
96
+ secondsSinceRelease = 0
97
+
98
+ voteIdInt = int (vote ['id' ], 16 )
99
+
100
+ if (voteIdInt in releaseByVoteId ):
101
+ secondsSinceRelease = (time . time () - int (releaseByVoteId [voteIdInt ]['createdAt' ]))
102
+ secondsSinceVote = secondsSinceVote - secondsSinceRelease
103
+
104
+
105
+ secondsSinceVote = min (secondsSinceVote , secondsInSixMonths )
106
+
107
+ votingPower = Web3 .fromWei (int (vote ['amount' ]), 'ether' ) * Decimal (pow (1 + beta , secondsSinceVote ))
108
+
109
+ for i in range (0 , int (secondsSinceRelease )):
110
+ votingPower = votingPower - Decimal (((1 - alphaDecay ) / (24 * 60 * 60 ))) * votingPower
111
+
112
+ totalVotingPower = totalVotingPower + votingPower
113
+
114
+ return totalVotingPower
115
+
116
+ grantVotingPower = {}
117
+
118
+ for url in urls :
119
+ grantsResult = run_query (queryGrants , url )
120
+ grants = grantsResult ['data' ]['grants' ]
121
+ for grant in grants :
122
+ grantId = int (grant ['id' ], 16 )
123
+ vp = calculate_voting_power (grant )
124
+ if grantId not in grantVotingPower :
125
+ grantVotingPower [grantId ] = vp
126
+ else :
127
+ grantVotingPower [grantId ] = grantVotingPower [grantId ] + vp
128
+
129
+
130
+ for grantId in grantVotingPower :
131
+ # store in db
132
+ if settings .DEBUG :
133
+ print ("Grant ID: " + str (grantId ) + " Voting Power: " + str (grantVotingPower [grantId ]))
134
+ try :
135
+ grant = Grant .objects .get (pk = grantId )
136
+ grant .metadata ['cv' ] = grantVotingPower [grantId ]
137
+ grant .save ()
138
+ except Exception as e :
139
+ print ("Error:" , e )
0 commit comments