or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdbalance-tracking.mdconstants-utilities.mdevent-testing.mdindex.mdrevert-testing.mdtime-manipulation.md

time-manipulation.mddocs/

0

# Time Manipulation

1

2

Blockchain time and block manipulation utilities for testing time-dependent contract behavior in development networks. Essential for testing time locks, vesting schedules, and other temporal smart contract logic.

3

4

## Capabilities

5

6

### Block Advancement

7

8

Mine new blocks to advance the blockchain state.

9

10

```javascript { .api }

11

/**

12

* Mine one block on the blockchain

13

* @returns {Promise<void>}

14

*/

15

function time.advanceBlock();

16

17

/**

18

* Advance blockchain to a specific block number

19

* @param {BN|number|string} target - Target block number

20

* @returns {Promise<void>}

21

*/

22

async function time.advanceBlockTo(target);

23

```

24

25

**Usage Examples:**

26

27

```javascript

28

const { time, BN } = require('@openzeppelin/test-helpers');

29

30

// Mine a single block

31

await time.advanceBlock();

32

33

// Advance to specific block (careful with large jumps!)

34

const targetBlock = await time.latestBlock().add(new BN('10'));

35

await time.advanceBlockTo(targetBlock);

36

```

37

38

### Time Queries

39

40

Get current blockchain time and block information.

41

42

```javascript { .api }

43

/**

44

* Get the timestamp of the latest block in seconds

45

* @returns {Promise<BN>} - Block timestamp as BigNumber

46

*/

47

async function time.latest();

48

49

/**

50

* Get the latest block number

51

* @returns {Promise<BN>} - Block number as BigNumber

52

*/

53

async function time.latestBlock();

54

```

55

56

**Usage Examples:**

57

58

```javascript

59

// Get current block timestamp

60

const now = await time.latest();

61

console.log('Current time:', now.toString());

62

63

// Get current block number

64

const blockNumber = await time.latestBlock();

65

console.log('Current block:', blockNumber.toString());

66

67

// Compare timestamps

68

const deadline = now.add(time.duration.days(7));

69

expect(deadline).to.be.bignumber.greaterThan(now);

70

```

71

72

### Time Advancement

73

74

Manipulate blockchain time for testing time-dependent functionality.

75

76

```javascript { .api }

77

/**

78

* Increase blockchain time by a specific duration

79

* @param {BN|number|string} duration - Duration in seconds to increase

80

* @returns {Promise<void>}

81

*/

82

async function time.increase(duration);

83

84

/**

85

* Increase blockchain time to a specific target timestamp

86

* @param {BN|number|string} target - Target timestamp in seconds

87

* @returns {Promise<void>}

88

*/

89

async function time.increaseTo(target);

90

```

91

92

**Usage Examples:**

93

94

```javascript

95

const { time } = require('@openzeppelin/test-helpers');

96

97

// Increase time by 1 hour

98

await time.increase(time.duration.hours(1));

99

100

// Jump to specific future time

101

const futureTime = (await time.latest()).add(time.duration.days(30));

102

await time.increaseTo(futureTime);

103

104

// Test time-locked function

105

it('should allow withdrawal after lock period', async function () {

106

// Lock funds for 1 week

107

await this.contract.lockFunds({ from: user });

108

109

// Try to withdraw immediately (should fail)

110

await expectRevert(

111

this.contract.withdraw({ from: user }),

112

'Funds are still locked'

113

);

114

115

// Advance time by 1 week

116

await time.increase(time.duration.weeks(1));

117

118

// Now withdrawal should succeed

119

await this.contract.withdraw({ from: user });

120

});

121

```

122

123

### Duration Utilities

124

125

Convenient time duration conversion utilities.

126

127

```javascript { .api }

128

const time.duration = {

129

/**

130

* Convert seconds to BigNumber

131

* @param {number|string} val - Value in seconds

132

* @returns {BN} - Duration as BigNumber

133

*/

134

seconds: (val) => BN,

135

136

/**

137

* Convert minutes to seconds as BigNumber

138

* @param {number|string} val - Value in minutes

139

* @returns {BN} - Duration in seconds as BigNumber

140

*/

141

minutes: (val) => BN,

142

143

/**

144

* Convert hours to seconds as BigNumber

145

* @param {number|string} val - Value in hours

146

* @returns {BN} - Duration in seconds as BigNumber

147

*/

148

hours: (val) => BN,

149

150

/**

151

* Convert days to seconds as BigNumber

152

* @param {number|string} val - Value in days

153

* @returns {BN} - Duration in seconds as BigNumber

154

*/

155

days: (val) => BN,

156

157

/**

158

* Convert weeks to seconds as BigNumber

159

* @param {number|string} val - Value in weeks

160

* @returns {BN} - Duration in seconds as BigNumber

161

*/

162

weeks: (val) => BN,

163

164

/**

165

* Convert years to seconds as BigNumber (365 days)

166

* @param {number|string} val - Value in years

167

* @returns {BN} - Duration in seconds as BigNumber

168

*/

169

years: (val) => BN,

170

};

171

```

172

173

**Usage Examples:**

174

175

```javascript

176

// Duration calculations

177

const oneHour = time.duration.hours(1);

178

const oneDay = time.duration.days(1);

179

const oneWeek = time.duration.weeks(1);

180

const oneYear = time.duration.years(1);

181

182

console.log('1 hour =', oneHour.toString(), 'seconds');

183

console.log('1 day =', oneDay.toString(), 'seconds');

184

console.log('1 week =', oneWeek.toString(), 'seconds');

185

console.log('1 year =', oneYear.toString(), 'seconds');

186

187

// Combining durations

188

const lockPeriod = time.duration.days(30).add(time.duration.hours(12));

189

await time.increase(lockPeriod);

190

```

191

192

## Comprehensive Testing Example

193

194

```javascript

195

const { time, expectRevert, BN } = require('@openzeppelin/test-helpers');

196

197

contract('TimeLock', function ([owner, beneficiary]) {

198

beforeEach(async function () {

199

this.lockDuration = time.duration.days(30);

200

this.releaseTime = (await time.latest()).add(this.lockDuration);

201

202

this.timeLock = await TimeLock.new(

203

beneficiary,

204

this.releaseTime,

205

{ from: owner }

206

);

207

});

208

209

it('should not allow release before time', async function () {

210

await expectRevert(

211

this.timeLock.release(),

212

'TimeLock: current time is before release time'

213

);

214

});

215

216

it('should allow release after time', async function () {

217

// Fast forward to release time

218

await time.increaseTo(this.releaseTime);

219

220

// Should now be able to release

221

await this.timeLock.release();

222

});

223

224

it('should handle gradual vesting', async function () {

225

const vestingStart = await time.latest();

226

const vestingDuration = time.duration.days(100);

227

228

// Check vesting at different points

229

await time.increaseTo(vestingStart.add(time.duration.days(25)));

230

let vestedAmount = await this.vestingContract.vestedAmount(beneficiary);

231

expect(vestedAmount).to.be.bignumber.equal(new BN('25')); // 25% vested

232

233

await time.increaseTo(vestingStart.add(time.duration.days(50)));

234

vestedAmount = await this.vestingContract.vestedAmount(beneficiary);

235

expect(vestedAmount).to.be.bignumber.equal(new BN('50')); // 50% vested

236

237

await time.increaseTo(vestingStart.add(vestingDuration));

238

vestedAmount = await this.vestingContract.vestedAmount(beneficiary);

239

expect(vestedAmount).to.be.bignumber.equal(new BN('100')); // 100% vested

240

});

241

});

242

```

243

244

## Important Notes

245

246

### Performance Warning

247

248

The `advanceBlockTo` function will show a warning when advancing many blocks (5+ seconds), as this can slow down tests significantly.

249

250

### Precision Limitations

251

252

Time manipulation is subject to blockchain precision limitations. Design tests to tolerate small time fluctuations when using `increaseTo`.

253

254

### Provider Compatibility

255

256

Time manipulation requires a development blockchain that supports:

257

- `evm_increaseTime` RPC method

258

- `evm_mine` RPC method

259

260

Compatible with:

261

- Ganache

262

- Hardhat Network

263

- Truffle Develop

264

265

### Block vs Time

266

267

Remember that advancing time also mines a block. Some contracts may depend on block numbers rather than timestamps.

268

269

```javascript

270

// Advance time without mining extra blocks

271

await time.increase(time.duration.hours(1));

272

273

// This will mine one additional block after time increase

274

// Current block number = previous + 1

275

```