1
1
/* globals artifacts */
2
2
3
+ const { BN } = require ( "bn.js" ) ;
3
4
const chai = require ( "chai" ) ;
4
5
const bnChai = require ( "bn-chai" ) ;
5
6
const { ethers } = require ( "ethers" ) ;
@@ -16,6 +17,7 @@ const {
16
17
forwardTime,
17
18
getBlockTime,
18
19
expectEvent,
20
+ encodeTxData,
19
21
} = require ( "../../helpers/test-helper" ) ;
20
22
21
23
const { setupRandomColony, getMetaTransactionParameters } = require ( "../../helpers/test-data-generator" ) ;
@@ -28,10 +30,12 @@ chai.use(bnChai(web3.utils.BN));
28
30
const EtherRouter = artifacts . require ( "EtherRouter" ) ;
29
31
const IColonyNetwork = artifacts . require ( "IColonyNetwork" ) ;
30
32
const IReputationMiningCycle = artifacts . require ( "IReputationMiningCycle" ) ;
33
+ const IVotingReputation = artifacts . require ( "IVotingReputation" ) ;
31
34
const Korporatio = artifacts . require ( "Korporatio" ) ;
32
35
const TokenLocking = artifacts . require ( "TokenLocking" ) ;
33
36
34
37
const KORPORATIO = soliditySha3 ( "Korporatio" ) ;
38
+ const VOTING_REPUTATION = soliditySha3 ( "VotingReputation" ) ;
35
39
36
40
contract ( "Korporatio" , ( accounts ) => {
37
41
let colony ;
@@ -60,8 +64,6 @@ contract("Korporatio", (accounts) => {
60
64
const USER2 = accounts [ 2 ] ;
61
65
const MINER = accounts [ 5 ] ;
62
66
63
- const APPLICATION_FEE = WAD . muln ( 6500 ) ;
64
-
65
67
before ( async ( ) => {
66
68
const etherRouter = await EtherRouter . deployed ( ) ;
67
69
colonyNetwork = await IColonyNetwork . at ( etherRouter . address ) ;
@@ -168,32 +170,47 @@ contract("Korporatio", (accounts) => {
168
170
await checkErrorRevert ( korporatio . deprecate ( true , { from : USER1 } ) , "ds-auth-unauthorized" ) ;
169
171
await checkErrorRevert ( korporatio . uninstall ( { from : USER1 } ) , "ds-auth-unauthorized" ) ;
170
172
} ) ;
173
+
174
+ it ( "cannot create applications unless initialised" , async ( ) => {
175
+ await checkErrorRevert (
176
+ korporatio . createApplication ( domain1Key , domain1Value , domain1Mask , domain1Siblings , user0Key , user0Value , user0Mask , user0Siblings , {
177
+ from : USER0 ,
178
+ } ) ,
179
+ "korporatio-not-initialised"
180
+ ) ;
181
+ } ) ;
171
182
} ) ;
172
183
173
184
describe ( "creating applications" , async ( ) => {
174
185
beforeEach ( async ( ) => {
175
- await korporatio . initialise ( token . address , APPLICATION_FEE , WAD . divn ( 100 ) , SECONDS_PER_DAY , { from : USER0 } ) ;
176
-
177
186
await colony . approveStake ( korporatio . address , 1 , WAD , { from : USER0 } ) ;
187
+
188
+ await korporatio . initialise ( WAD . divn ( 100 ) , SECONDS_PER_DAY , { from : USER0 } ) ;
189
+ } ) ;
190
+
191
+ it ( "can re-initialise until first application is created" , async ( ) => {
192
+ await korporatio . initialise ( WAD . divn ( 10 ) , SECONDS_PER_DAY , { from : USER0 } ) ;
193
+
194
+ const stakeFraction = await korporatio . getStakeFraction ( ) ;
195
+ expect ( stakeFraction ) . to . eq . BN ( WAD . divn ( 10 ) ) ;
196
+
197
+ await korporatio . createApplication ( domain1Key , domain1Value , domain1Mask , domain1Siblings , user0Key , user0Value , user0Mask , user0Siblings , {
198
+ from : USER0 ,
199
+ } ) ;
200
+
201
+ await checkErrorRevert ( korporatio . initialise ( WAD . divn ( 100 ) , SECONDS_PER_DAY , { from : USER1 } ) , "korporatio-cannot-initialise" ) ;
178
202
} ) ;
179
203
180
204
it ( "can query for configuration params" , async ( ) => {
181
- const paymentToken = await korporatio . getPaymentToken ( ) ;
182
- const applicationFee = await korporatio . getApplicationFee ( ) ;
183
205
const stakeFraction = await korporatio . getStakeFraction ( ) ;
184
206
const claimDelay = await korporatio . getClaimDelay ( ) ;
185
207
186
- expect ( paymentToken ) . to . equal ( token . address ) ;
187
- expect ( applicationFee ) . to . eq . BN ( APPLICATION_FEE ) ;
188
208
expect ( stakeFraction ) . to . eq . BN ( WAD . divn ( 100 ) ) ;
189
209
expect ( claimDelay ) . to . eq . BN ( SECONDS_PER_DAY ) ;
190
210
} ) ;
191
211
192
212
it ( "cannot set configuration params if not root architect" , async ( ) => {
193
- await checkErrorRevert (
194
- korporatio . initialise ( token . address , APPLICATION_FEE , WAD . divn ( 100 ) , SECONDS_PER_DAY , { from : USER1 } ) ,
195
- "korporatio-not-root-architect"
196
- ) ;
213
+ await checkErrorRevert ( korporatio . initialise ( WAD . divn ( 100 ) , SECONDS_PER_DAY , { from : USER1 } ) , "korporatio-not-root-architect" ) ;
197
214
} ) ;
198
215
199
216
it ( "can create an application" , async ( ) => {
@@ -225,7 +242,7 @@ contract("Korporatio", (accounts) => {
225
242
} ) ;
226
243
227
244
it ( "cannot create an application with insufficient rep" , async ( ) => {
228
- await korporatio . initialise ( token . address , APPLICATION_FEE , WAD , SECONDS_PER_DAY , { from : USER0 } ) ;
245
+ await korporatio . initialise ( WAD , SECONDS_PER_DAY , { from : USER0 } ) ;
229
246
230
247
await checkErrorRevert (
231
248
korporatio . createApplication ( domain1Key , domain1Value , domain1Mask , domain1Siblings , user0Key , user0Value , user0Mask , user0Siblings , {
@@ -256,7 +273,7 @@ contract("Korporatio", (accounts) => {
256
273
const applicationId = await korporatio . getNumApplications ( ) ;
257
274
258
275
// Only applicant can cancel
259
- await checkErrorRevert ( korporatio . cancelApplication ( applicationId , { from : USER1 } ) , "korporatio-cannot-cancel " ) ;
276
+ await checkErrorRevert ( korporatio . cancelApplication ( applicationId , { from : USER1 } ) , "korporatio-not-applicant " ) ;
260
277
261
278
const tx = await korporatio . cancelApplication ( applicationId , { from : USER0 } ) ;
262
279
const blockTime = await getBlockTime ( tx . receipt . blockNumber ) ;
@@ -278,7 +295,7 @@ contract("Korporatio", (accounts) => {
278
295
279
296
await forwardTime ( SECONDS_PER_DAY , this ) ;
280
297
281
- await korporatio . reclaimStake ( applicationId ) ;
298
+ await korporatio . reclaimStake ( applicationId , { from : USER0 } ) ;
282
299
283
300
const obligation = await colony . getObligation ( USER0 , korporatio . address , 1 ) ;
284
301
expect ( obligation ) . to . be . zero ;
@@ -331,6 +348,28 @@ contract("Korporatio", (accounts) => {
331
348
await checkErrorRevert ( korporatio . slashStake ( applicationId , false , { from : USER2 } ) , "korporatio-caller-not-arbitration" ) ;
332
349
} ) ;
333
350
351
+ it ( "can reclaim a stake via arbitration if the extension is deleted" , async ( ) => {
352
+ const korporatioAddress = korporatio . address ;
353
+ await korporatio . createApplication ( domain1Key , domain1Value , domain1Mask , domain1Siblings , user0Key , user0Value , user0Mask , user0Siblings , {
354
+ from : USER0 ,
355
+ } ) ;
356
+
357
+ const lockPre = await tokenLocking . getUserLock ( token . address , USER0 ) ;
358
+ const obligationPre = await colony . getObligation ( USER0 , korporatioAddress , 1 ) ;
359
+ expect ( obligationPre ) . to . eq . BN ( WAD . divn ( 100 ) . muln ( 3 ) ) ;
360
+
361
+ await colony . uninstallExtension ( KORPORATIO , { from : USER0 } ) ;
362
+
363
+ await colony . transferStake ( 1 , UINT256_MAX , korporatioAddress , USER0 , 1 , obligationPre , USER0 , { from : USER1 } ) ;
364
+
365
+ const lockPost = await tokenLocking . getUserLock ( token . address , USER0 ) ;
366
+ const obligationPost = await colony . getObligation ( USER0 , korporatioAddress , 1 ) ;
367
+
368
+ // Obligation is zeroed out, but token balance is unchanged
369
+ expect ( obligationPost ) . to . be . zero ;
370
+ expect ( new BN ( lockPre . balance ) ) . to . eq . BN ( lockPost . balance ) ;
371
+ } ) ;
372
+
334
373
it ( "can update an application" , async ( ) => {
335
374
await korporatio . createFreeApplication ( { from : USER0 } ) ;
336
375
@@ -348,27 +387,56 @@ contract("Korporatio", (accounts) => {
348
387
await checkErrorRevert ( korporatio . updateApplication ( applicationId , ipfsHash , { from : USER0 } ) , "korporatio-stake-cancelled" ) ;
349
388
} ) ;
350
389
351
- it ( "can submit an application and pay the fee" , async ( ) => {
352
- await token . mint ( USER0 , APPLICATION_FEE ) ;
353
- await token . approve ( korporatio . address , APPLICATION_FEE ) ;
354
-
390
+ it ( "can submit an application" , async ( ) => {
355
391
await korporatio . createFreeApplication ( { from : USER0 } ) ;
356
392
357
393
const applicationId = await korporatio . getNumApplications ( ) ;
358
- const ipfsHash = soliditySha3 ( "IPFS Hash" ) ;
359
394
360
395
// Cannot submit if not root
361
- await checkErrorRevert ( korporatio . submitApplication ( applicationId , ipfsHash , { from : USER1 } ) , "korporatio-caller-not-root" ) ;
396
+ await checkErrorRevert ( korporatio . submitApplication ( applicationId , { from : USER1 } ) , "korporatio-caller-not-root" ) ;
397
+
398
+ const tx = await korporatio . submitApplication ( applicationId , { from : USER0 } ) ;
399
+ await expectEvent ( tx , "ApplicationSubmitted" , [ applicationId ] ) ;
362
400
363
- const tx = await korporatio . submitApplication ( applicationId , ipfsHash , { from : USER0 } ) ;
364
- await expectEvent ( tx , "ApplicationSubmitted" , [ applicationId , ipfsHash ] ) ;
401
+ // Cannot submit twice
402
+ await checkErrorRevert ( korporatio . submitApplication ( applicationId , { from : USER0 } ) , "korporatio-stake-cancelled" ) ;
403
+ } ) ;
404
+
405
+ it ( "can submit an application via a motion" , async ( ) => {
406
+ await colony . installExtension ( VOTING_REPUTATION , 9 ) ;
407
+ const votingAddress = await colonyNetwork . getExtensionInstallation ( VOTING_REPUTATION , colony . address ) ;
408
+ await colony . setArbitrationRole ( 1 , UINT256_MAX , votingAddress , 1 , true ) ;
409
+ await colony . setRootRole ( votingAddress , true ) ;
410
+ const voting = await IVotingReputation . at ( votingAddress ) ;
365
411
366
- const metaColonyAddress = await colonyNetwork . getMetaColony ( ) ;
367
- const metaColonyBalance = await token . balanceOf ( metaColonyAddress ) ;
368
- expect ( metaColonyBalance ) . to . eq . BN ( APPLICATION_FEE ) ;
412
+ await voting . initialise ( WAD . divn ( 1000 ) , 0 , 0 , WAD , SECONDS_PER_DAY , SECONDS_PER_DAY , SECONDS_PER_DAY , SECONDS_PER_DAY ) ;
369
413
370
- // Cannot submit once cancelled
371
- await checkErrorRevert ( korporatio . submitApplication ( applicationId , ipfsHash , { from : USER0 } ) , "korporatio-stake-cancelled" ) ;
414
+ await korporatio . createFreeApplication ( { from : USER0 } ) ;
415
+ const applicationId = await korporatio . getNumApplications ( ) ;
416
+
417
+ const action = await encodeTxData ( korporatio , "submitApplication" , [ applicationId ] ) ;
418
+
419
+ // Can't create a motion in a subdomain
420
+ await colony . addDomain ( 1 , UINT256_MAX , 1 ) ;
421
+ await checkErrorRevert (
422
+ voting . createMotion ( 2 , UINT256_MAX , korporatio . address , action , domain1Key , domain1Value , domain1Mask , domain1Siblings ) ,
423
+ "voting-rep-invalid-domain-id"
424
+ ) ;
425
+
426
+ // Only in the root domain
427
+ await voting . createMotion ( 1 , UINT256_MAX , korporatio . address , action , domain1Key , domain1Value , domain1Mask , domain1Siblings ) ;
428
+ const motionId = await voting . getMotionCount ( ) ;
429
+
430
+ await colony . approveStake ( voting . address , 1 , WAD , { from : USER0 } ) ;
431
+ await voting . stakeMotion ( motionId , 1 , UINT256_MAX , 1 , WAD . muln ( 3 ) . divn ( 1000 ) , user0Key , user0Value , user0Mask , user0Siblings , { from : USER0 } ) ;
432
+
433
+ await forwardTime ( SECONDS_PER_DAY , this ) ;
434
+
435
+ const tx = await voting . finalizeMotion ( motionId ) ;
436
+ const finalizedAt = await getBlockTime ( tx . blockNumber ) ;
437
+
438
+ const application = await korporatio . getApplication ( applicationId ) ;
439
+ expect ( application . cancelledAt ) . to . eq . BN ( finalizedAt ) ;
372
440
} ) ;
373
441
374
442
it ( "can submit a stake via metatransactions" , async ( ) => {
0 commit comments