@@ -3,11 +3,12 @@ import { ethers } from 'hardhat'
3
3
import { loadFixture , mine } from '@nomicfoundation/hardhat-toolbox/network-helpers'
4
4
import { deployRif } from '../scripts/deploy-rif'
5
5
import { deployGovernor } from '../scripts/deploy-governor'
6
- import { RIFToken , RootDao , StRIFToken , TokenFaucet } from '../typechain-types'
6
+ import { deployTimelock } from '../scripts/deploy-timelock'
7
+ import { RIFToken , RootDao , StRIFToken , TokenFaucet , DaoTimelockUpgradable } from '../typechain-types'
7
8
import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'
8
9
import { deployStRIF } from '../scripts/deploy-stRIF'
9
- import { parseEther , solidityPackedKeccak256 } from 'ethers'
10
- import { Proposal , ProposalState } from '../types'
10
+ import { parseEther , solidityPackedKeccak256 , toBeHex } from 'ethers'
11
+ import { Proposal , ProposalState , OperationState } from '../types'
11
12
12
13
describe ( 'RootDAO Contact' , ( ) => {
13
14
const initialVotingDelay = 1n // secs 1 day
@@ -16,6 +17,7 @@ describe('RootDAO Contact', () => {
16
17
17
18
let rif : { rifToken : RIFToken ; rifAddress : string ; tokenFaucet : TokenFaucet }
18
19
let stRIF : StRIFToken
20
+ let timelock : DaoTimelockUpgradable
19
21
let governor : RootDao
20
22
let holders : SignerWithAddress [ ]
21
23
let deployer : SignerWithAddress
@@ -30,19 +32,25 @@ describe('RootDAO Contact', () => {
30
32
rif = await loadFixture ( deployRIF )
31
33
const deployGovToken = async ( ) => deployStRIF ( rif . rifAddress , deployer . address )
32
34
stRIF = await loadFixture ( deployGovToken )
33
-
34
- const deployDAO = async ( ) => deployGovernor ( await stRIF . getAddress ( ) , deployer . address )
35
+ timelock = await loadFixture ( deployTimelock )
36
+ const deployDAO = async ( ) =>
37
+ deployGovernor ( await stRIF . getAddress ( ) , deployer . address , await timelock . getAddress ( ) )
35
38
governor = await loadFixture ( deployDAO )
36
39
} )
37
40
38
41
describe ( 'Upon deployment' , ( ) => {
39
42
it ( 'should deploy all contracts' , async ( ) => {
40
43
expect ( rif . rifAddress ) . to . be . properAddress
41
44
expect ( await stRIF . getAddress ( ) ) . to . be . properAddress
45
+ expect ( await timelock . getAddress ( ) ) . to . be . properAddress
42
46
expect ( await governor . getAddress ( ) ) . to . be . properAddress
43
47
expect ( await rif . tokenFaucet . getAddress ( ) ) . to . be . properAddress
44
48
} )
45
49
50
+ it ( 'min delay should be set on the Timelock' , async ( ) => {
51
+ expect ( await timelock . getMinDelay ( ) )
52
+ } )
53
+
46
54
it ( 'voting delay should be initialized' , async ( ) => {
47
55
expect ( await governor . votingDelay ( ) ) . to . equal ( initialVotingDelay )
48
56
} )
@@ -60,8 +68,8 @@ describe('RootDAO Contact', () => {
60
68
const sendAmount = '2'
61
69
let proposal : Proposal
62
70
let proposalId : bigint
63
- // let proposalCalldata: string
64
71
let proposalSnapshot : bigint
72
+ // let proposalCalldata: string
65
73
66
74
const getState = async ( ) => await governor . state ( proposalId )
67
75
@@ -72,7 +80,6 @@ describe('RootDAO Contact', () => {
72
80
73
81
const createProposal = async ( proposalDesc ?: string ) => {
74
82
const blockHeight = await ethers . provider . getBlockNumber ( )
75
- const votingPeriod = await governor . votingPeriod ( )
76
83
const votingDelay = await governor . votingDelay ( )
77
84
78
85
proposal = [
@@ -86,16 +93,10 @@ describe('RootDAO Contact', () => {
86
93
. connect ( holders [ 0 ] )
87
94
. hashProposal ( proposal [ 0 ] , proposal [ 1 ] , proposal [ 2 ] , generateDescriptionHash ( proposalDesc ) )
88
95
89
- const tx = await governor . connect ( holders [ 0 ] ) . propose ( ...proposal )
90
-
91
- const snapshot = votingDelay + BigInt ( blockHeight ) + 1n
92
- const snapshotPlusDuration = votingPeriod + votingDelay + BigInt ( blockHeight ) + 1n
93
-
94
- return {
95
- snapshot,
96
- snapshotPlusDuration,
97
- tx,
98
- }
96
+ const proposalTx = await governor . connect ( holders [ 0 ] ) . propose ( ...proposal )
97
+ await proposalTx . wait ( )
98
+ proposalSnapshot = votingDelay + BigInt ( blockHeight ) + 1n
99
+ return proposalTx
99
100
}
100
101
101
102
const checkVotes = async ( ) => {
@@ -145,25 +146,29 @@ describe('RootDAO Contact', () => {
145
146
} )
146
147
147
148
it ( 'holder[0] should be able to create proposal' , async ( ) => {
148
- const { snapshot , snapshotPlusDuration , tx } = await createProposal ( )
149
-
149
+ const proposalTx = await createProposal ( )
150
+ const votingPeriod = await governor . votingPeriod ( )
150
151
const ProposalCreatedEvent = [
151
152
proposalId ,
152
153
holders [ 0 ] . address , // proposer
153
154
proposal [ 0 ] , // targets
154
155
proposal [ 1 ] , // values
155
156
[ '' ] , // ?
156
157
proposal [ 2 ] , // calldatas
157
- snapshot ,
158
- snapshotPlusDuration ,
158
+ proposalSnapshot ,
159
+ proposalSnapshot + votingPeriod ,
159
160
defaultDescription ,
160
161
]
161
162
162
- await expect ( tx )
163
+ await expect ( proposalTx )
163
164
. to . emit ( governor , 'ProposalCreated' )
164
165
. withArgs ( ...ProposalCreatedEvent )
165
166
} )
166
167
168
+ it ( 'proposal creation should initiate a Proposal Snapshot creation' , async ( ) => {
169
+ expect ( await governor . proposalSnapshot ( proposalId ) ) . equal ( proposalSnapshot )
170
+ } )
171
+
167
172
it ( 'the rest of the holders should not be able to create proposal' , async ( ) => {
168
173
await Promise . all (
169
174
holders . slice ( 1 ) . map ( async holder => {
@@ -176,13 +181,6 @@ describe('RootDAO Contact', () => {
176
181
)
177
182
} )
178
183
179
- it ( 'proposal creation should initiate a Proposal Snapshot creation' , async ( ) => {
180
- const votingDelay = await governor . votingDelay ( )
181
- const block = await ethers . provider . getBlockNumber ( )
182
- proposalSnapshot = await governor . proposalSnapshot ( proposalId )
183
- expect ( votingDelay + BigInt ( block ) ) . equal ( proposalSnapshot )
184
- } )
185
-
186
184
it ( 'should calculate the quorum correctly' , async ( ) => {
187
185
await mine ( ( await governor . votingDelay ( ) ) + 1n )
188
186
@@ -254,7 +252,7 @@ describe('RootDAO Contact', () => {
254
252
proposalSnapshot = await governor . proposalSnapshot ( proposalId )
255
253
const quorum = await governor . quorum ( proposalSnapshot )
256
254
257
- for ( let holder of holders . slice ( 2 , holders . length ) ) {
255
+ for ( const holder of holders . slice ( 2 , holders . length ) ) {
258
256
if ( ( await checkVotes ( ) ) <= quorum ) {
259
257
await governor . connect ( holder ) . castVote ( proposalId , 1 )
260
258
}
@@ -265,14 +263,27 @@ describe('RootDAO Contact', () => {
265
263
expect ( await getState ( ) ) . to . be . equal ( ProposalState . Succeeded )
266
264
} )
267
265
268
- it ( 'after a proposal succeded it should be queued for execution' , async ( ) => {
266
+ it ( 'Proposal should be registered as an operation on the Timelock' , async ( ) => {
267
+ expect ( await timelock . isOperation ( toBeHex ( proposalId ) ) )
268
+ } )
269
+
270
+ it ( 'Operation should be in Unset stage' , async ( ) => {
271
+ const state = Number ( await timelock . getOperationState ( toBeHex ( proposalId ) ) )
272
+ expect ( state ) . to . equal ( OperationState . Unset )
273
+ } )
274
+
275
+ it ( 'should return operation timestamp as 0 (because it is unset)' , async ( ) => {
276
+ expect ( await timelock . getTimestamp ( toBeHex ( proposalId ) ) ) . to . equal ( 0 )
277
+ } )
278
+
279
+ /* it('after a proposal succeeded it should be queued for execution', async () => {
269
280
const tx = await governor
270
281
.connect(deployer)
271
282
[
272
283
'execute(address[],uint256[],bytes[],bytes32)'
273
284
](proposal[0], proposal[1], proposal[2], generateDescriptionHash(otherDesc))
274
285
await tx.wait()
275
- } )
286
+ }) */
276
287
} )
277
288
} )
278
289
} )
0 commit comments