Skip to content

Commit 607f70c

Browse files
committed
Merge branch 'migration-experimental' into 0.1.2rc
2 parents 150945a + 01d79fc commit 607f70c

File tree

4 files changed

+279
-24
lines changed

4 files changed

+279
-24
lines changed

legacy-dao-params-generator.js

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
const axios = require('axios')
2+
axios.defaults.timeout = 30000
3+
4+
const Web3 = require('web3')
5+
const web3 = new Web3()
6+
const BN = require('bn.js')
7+
8+
async function getLegacyDAOParameters (daoId, subgraphEndpoint) {
9+
let voteParasQuery = `
10+
boostedVotePeriodLimit
11+
daoBountyConst
12+
minimumDaoBounty
13+
queuedVotePeriodLimit
14+
queuedVoteRequiredPercentage
15+
preBoostedVotePeriodLimit
16+
proposingRepReward
17+
quietEndingPeriod
18+
thresholdConst
19+
voteOnBehalf
20+
votersReputationLossRatio
21+
activationTime
22+
`
23+
const query = `{
24+
dao(id: "${daoId}") {
25+
id
26+
name
27+
nativeToken {
28+
id
29+
name
30+
symbol
31+
}
32+
reputationHolders(first: 1000) {
33+
balance
34+
address
35+
}
36+
reputationHoldersCount
37+
schemes {
38+
isRegistered
39+
name
40+
alias
41+
canDelegateCall
42+
canRegisterSchemes
43+
canUpgradeController
44+
canManageGlobalConstraints
45+
genericSchemeParams {
46+
voteParams {
47+
${voteParasQuery}
48+
}
49+
contractToCall
50+
}
51+
uGenericSchemeParams {
52+
voteParams {
53+
${voteParasQuery}
54+
}
55+
contractToCall
56+
}
57+
schemeRegistrarParams {
58+
voteRegisterParams {
59+
${voteParasQuery}
60+
}
61+
voteRemoveParams {
62+
${voteParasQuery}
63+
}
64+
}
65+
contributionRewardParams {
66+
voteParams {
67+
${voteParasQuery}
68+
}
69+
}
70+
contributionRewardExtParams {
71+
voteParams {
72+
${voteParasQuery}
73+
}
74+
rewarder
75+
}
76+
}
77+
}
78+
}`
79+
try {
80+
let { data } = (await axios.post(subgraphEndpoint, { query })).data
81+
let { dao } = data
82+
let migrationParams = {
83+
founders: [],
84+
Schemes: [],
85+
VotingMachinesParams: []
86+
}
87+
migrationParams.orgName = dao.name
88+
migrationParams.tokenName = dao.nativeToken.name
89+
migrationParams.tokenSymbol = dao.nativeToken.symbol
90+
// TODO: is tokenCap needed?
91+
migrationParams.tokenCap = 0
92+
// TODO: Legacy DAOs had no metadata, we should maybe ask for user input for this
93+
migrationParams.metaData = ''
94+
if (dao.reputationHoldersCount > 1000) {
95+
// TODO: Might need to handle edge case of more than 1000 reputation holders, let's check if any such exist
96+
console.log('Error: Too many rep holders')
97+
}
98+
for (let reputationHolder of dao.reputationHolders) {
99+
// TODO: DO we need DAOToken too?
100+
migrationParams.founders.push({
101+
tokens: 0,
102+
reputation: web3.utils.fromWei(reputationHolder.balance),
103+
address: reputationHolder.address
104+
})
105+
}
106+
// TODO: Maybe handle more than 1000 token holders.
107+
const tokenHoldersQuery = `{
108+
tokenHolders(where: {contract: "${dao.nativeToken.id}"}, first: 1000) {
109+
contract
110+
address
111+
balance
112+
}
113+
}`
114+
let { tokenHolders } = (await axios.post(subgraphEndpoint, { query: tokenHoldersQuery })).data.data
115+
for (let tokenHolder of tokenHolders) {
116+
let existingFounder = false
117+
for (let i in migrationParams.founders) {
118+
if (tokenHolder.address === migrationParams.founders[i].address) {
119+
existingFounder = true
120+
migrationParams.founders[i].tokens = web3.utils.fromWei(tokenHolder.balance)
121+
break
122+
}
123+
}
124+
if (!existingFounder) {
125+
migrationParams.founders.push({
126+
tokens: web3.utils.fromWei(tokenHolder.balance),
127+
reputation: 0,
128+
address: tokenHolder.address
129+
})
130+
}
131+
}
132+
let i = 0
133+
for (let scheme of dao.schemes) {
134+
if (!scheme.isRegistered) {
135+
continue
136+
}
137+
let permissions = '0x00000000'
138+
if (scheme.canRegisterSchemes) {
139+
permissions = '0x0000001F'
140+
} else if (scheme.canDelegateCall) {
141+
permissions = '0x00000010'
142+
} else if (scheme.canUpgradeController) {
143+
permissions = '0x0000000A'
144+
} else if (scheme.canManageGlobalConstraints) {
145+
permissions = '0x00000004'
146+
}
147+
148+
let schemeName = scheme.name
149+
let schemeParamsName = ''
150+
let params
151+
let voteParamsName = 'voteParams'
152+
if (scheme.genericSchemeParams !== null) {
153+
schemeParamsName = 'genericSchemeParams'
154+
params = [
155+
'GenesisProtocolAddress',
156+
{ voteParams: i },
157+
scheme[schemeParamsName].contractToCall
158+
]
159+
} else if (scheme.uGenericSchemeParams !== null) {
160+
schemeName = 'GenericScheme'
161+
schemeParamsName = 'uGenericSchemeParams'
162+
params = [
163+
'GenesisProtocolAddress',
164+
{ voteParams: i },
165+
scheme[schemeParamsName].contractToCall
166+
]
167+
} else if (scheme.schemeRegistrarParams !== null) {
168+
schemeName = 'SchemeFactory'
169+
schemeParamsName = 'schemeRegistrarParams'
170+
voteParamsName = 'voteRegisterParams'
171+
params = [
172+
'GenesisProtocolAddress',
173+
{ voteParams: i },
174+
{ packageContract: 'DAOFactoryInstance' }
175+
]
176+
} else if (scheme.contributionRewardParams !== null) {
177+
schemeParamsName = 'contributionRewardParams'
178+
params = [
179+
'GenesisProtocolAddress',
180+
{ voteParams: i }
181+
]
182+
} else if (scheme.contributionRewardExtParams !== null) {
183+
schemeParamsName = 'contributionRewardExtParams'
184+
params = [
185+
'GenesisProtocolAddress',
186+
{ voteParams: i },
187+
{ packageContract: 'DAOFactoryInstance' },
188+
'PackageVersion',
189+
'Competition'
190+
]
191+
}
192+
193+
if (schemeParamsName === '') {
194+
console.log('Cannot migrate this scheme ' + scheme.name)
195+
continue
196+
}
197+
i++
198+
migrationParams.VotingMachinesParams.push({
199+
boostedVotePeriodLimit: scheme[schemeParamsName][voteParamsName].boostedVotePeriodLimit,
200+
daoBountyConst: scheme[schemeParamsName][voteParamsName].daoBountyConst,
201+
minimumDaoBounty: web3.utils.fromWei(scheme[schemeParamsName][voteParamsName].minimumDaoBounty),
202+
queuedVotePeriodLimit: scheme[schemeParamsName][voteParamsName].queuedVotePeriodLimit,
203+
queuedVoteRequiredPercentage: scheme[schemeParamsName][voteParamsName].queuedVoteRequiredPercentage,
204+
preBoostedVotePeriodLimit: scheme[schemeParamsName][voteParamsName].preBoostedVotePeriodLimit,
205+
proposingRepReward: web3.utils.fromWei(scheme[schemeParamsName][voteParamsName].proposingRepReward),
206+
quietEndingPeriod: scheme[schemeParamsName][voteParamsName].quietEndingPeriod,
207+
thresholdConst: realMathToNumber(new BN(scheme[schemeParamsName][voteParamsName].thresholdConst)),
208+
voteOnBehalf: scheme[schemeParamsName][voteParamsName].voteOnBehalf,
209+
votersReputationLossRatio: scheme[schemeParamsName][voteParamsName].votersReputationLossRatio,
210+
activationTime: scheme[schemeParamsName][voteParamsName].activationTime
211+
})
212+
migrationParams.Schemes.push({
213+
name: schemeName,
214+
alias: scheme.alias,
215+
permissions,
216+
params
217+
})
218+
}
219+
console.log(JSON.stringify(migrationParams, null, 2))
220+
return migrationParams
221+
} catch (e) {
222+
console.log(e)
223+
}
224+
}
225+
226+
function realMathToNumber (t) {
227+
const REAL_FBITS = 40
228+
const fraction = t.maskn(REAL_FBITS).toNumber() / Math.pow(2, REAL_FBITS)
229+
return Math.round((t.shrn(REAL_FBITS).toNumber() + fraction) * 1000)
230+
}
231+
232+
if (require.main === module) {
233+
let cliArgs = process.argv.slice(2)
234+
let daoId = cliArgs[0]
235+
let subgraphEndpoint = cliArgs[1]
236+
getLegacyDAOParameters(daoId, subgraphEndpoint)
237+
} else {
238+
module.exports = {
239+
getLegacyDAOParameters
240+
}
241+
}

migrate-dao.js

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ async function migrateDAO ({ arcVersion, web3, spinner, confirm, opts, migration
199199
founders.map(({ reputation }) => web3.utils.toWei(reputation !== undefined ? reputation.toString() : '0'))
200200
]
201201

202-
const initFoundersBatchSize = 20
202+
const initFoundersBatchSize = 100
203203
const foundersBatchSize = 100
204204

205205
if (deploymentState.schemeNames === undefined) {
@@ -269,6 +269,8 @@ async function migrateDAO ({ arcVersion, web3, spinner, confirm, opts, migration
269269
setState(deploymentState, network)
270270
}
271271

272+
deploymentState.foundersToAddCount = deploymentState.foundersToAddCount === undefined ? founderAddresses.length - initFoundersBatchSize : deploymentState.foundersToAddCount
273+
272274
if (deploymentState.Avatar === undefined) {
273275
let foundersInitCount = founderAddresses.length < initFoundersBatchSize ? founderAddresses.length : initFoundersBatchSize
274276
let tokenData = await new web3.eth.Contract(utils.importAbi(`./${contractsDir}/${arcVersion}/DAOToken.json`).abi)
@@ -293,16 +295,47 @@ async function migrateDAO ({ arcVersion, web3, spinner, confirm, opts, migration
293295
]
294296
)
295297

298+
let forgeOrgSetSchemesParams = deploymentState.foundersToAddCount <= 0 ? encodedSetSchemesParams : '0x'
299+
296300
const forgeOrg = daoFactory.methods.forgeOrg(
297301
encodedForgeOrgParams,
298-
encodedSetSchemesParams
302+
forgeOrgSetSchemesParams
299303
)
300304

301305
tx = (await sendTx(forgeOrg, 'Creating a new organization...')).receipt
302306
await logTx(tx, 'Created new organization.')
303307

304308
deploymentState.Avatar = tx.events.NewOrg.returnValues._avatar
305309

310+
if (forgeOrgSetSchemesParams === '0x') {
311+
deploymentState.foundersAdditionCounter = deploymentState.foundersAdditionCounter === undefined ? 0 : deploymentState.foundersAdditionCounter
312+
while (deploymentState.foundersToAddCount > 0) {
313+
let currentBatchCount = deploymentState.foundersToAddCount < foundersBatchSize ? deploymentState.foundersToAddCount : foundersBatchSize
314+
tx = (await sendTx(daoFactory.methods.addFounders(
315+
deploymentState.Avatar,
316+
founderAddresses.slice(deploymentState.foundersAdditionCounter * foundersBatchSize + initFoundersBatchSize,
317+
deploymentState.foundersAdditionCounter * foundersBatchSize + currentBatchCount + initFoundersBatchSize),
318+
tokenDist.slice(deploymentState.foundersAdditionCounter * foundersBatchSize + initFoundersBatchSize,
319+
deploymentState.foundersAdditionCounter * foundersBatchSize + currentBatchCount + initFoundersBatchSize),
320+
repDist.slice(deploymentState.foundersAdditionCounter * foundersBatchSize + initFoundersBatchSize,
321+
deploymentState.foundersAdditionCounter * foundersBatchSize + currentBatchCount + initFoundersBatchSize)
322+
), 'Adding founders...')).receipt
323+
await logTx(tx, 'Finished adding founders.')
324+
325+
deploymentState.foundersToAddCount -= foundersBatchSize
326+
deploymentState.foundersAdditionCounter++
327+
setState(deploymentState, network)
328+
}
329+
330+
const setSchemes = daoFactory.methods.setSchemes(
331+
deploymentState.Avatar,
332+
encodedSetSchemesParams
333+
)
334+
335+
tx = (await sendTx(setSchemes, 'Setting DAO schemes...')).receipt
336+
await logTx(tx, 'DAO schemes were set.')
337+
}
338+
306339
let schemesEvents = tx.events.SchemeInstance
307340
for (let i in schemesEvents) {
308341
deploymentState.Schemes.push(
@@ -312,26 +345,7 @@ async function migrateDAO ({ arcVersion, web3, spinner, confirm, opts, migration
312345
address: schemesEvents[i].returnValues._scheme
313346
})
314347
}
315-
setState(deploymentState, network)
316-
}
317348

318-
deploymentState.foundersToAddCount = deploymentState.foundersToAddCount === undefined ? founderAddresses.length - initFoundersBatchSize : deploymentState.foundersToAddCount
319-
deploymentState.foundersAdditionCounter = deploymentState.foundersAdditionCounter === undefined ? 0 : deploymentState.foundersAdditionCounter
320-
while (deploymentState.foundersToAddCount > 0) {
321-
let currentBatchCount = deploymentState.foundersToAddCount < foundersBatchSize ? deploymentState.foundersToAddCount : foundersBatchSize
322-
tx = (await sendTx(daoFactory.methods.addFounders(
323-
deploymentState.Avatar,
324-
founderAddresses.slice(deploymentState.foundersAdditionCounter * foundersBatchSize + initFoundersBatchSize,
325-
deploymentState.foundersAdditionCounter * foundersBatchSize + currentBatchCount + initFoundersBatchSize),
326-
tokenDist.slice(deploymentState.foundersAdditionCounter * foundersBatchSize + initFoundersBatchSize,
327-
deploymentState.foundersAdditionCounter * foundersBatchSize + currentBatchCount + initFoundersBatchSize),
328-
repDist.slice(deploymentState.foundersAdditionCounter * foundersBatchSize + initFoundersBatchSize,
329-
deploymentState.foundersAdditionCounter * foundersBatchSize + currentBatchCount + initFoundersBatchSize)
330-
), 'Adding founders...')).receipt
331-
await logTx(tx, 'Finished adding founders.')
332-
333-
deploymentState.foundersToAddCount -= foundersBatchSize
334-
deploymentState.foundersAdditionCounter++
335349
setState(deploymentState, network)
336350
}
337351

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"yargs": "^12.0.2"
6464
},
6565
"devDependencies": {
66-
"axios": "^0.18.0",
66+
"axios": "^0.18.1",
6767
"command-line-args": "^5.0.2",
6868
"command-line-usage": "^5.0.5",
6969
"dotenv": "^7.0.0",

sanitize.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const Validator = require('jsonschema').Validator
33
const validator = new Validator()
44

55
const requiredNumber = {
6-
type: 'number',
6+
type: ['number', 'string'],
77
required: true
88
}
99

@@ -276,7 +276,7 @@ const member = {
276276
type: 'object',
277277
properties: {
278278
address: { $ref: 'Address', required: true },
279-
tokens: { type: 'number' },
279+
tokens: { type: ['number', 'string'] },
280280
reputation: requiredNumber
281281
}
282282
}

0 commit comments

Comments
 (0)