0
# Block Configuration
1
2
Configure block-level properties to test gas-sensitive contracts, fee mechanisms, and other block-dependent functionality in controlled environments.
3
4
## Capabilities
5
6
### Set Block Gas Limit
7
8
Controls the gas limit for future blocks, useful for testing gas-intensive operations and gas limit edge cases.
9
10
```typescript { .api }
11
/**
12
* Sets the gas limit for future blocks
13
* @param blockGasLimit The gas limit to set for future blocks
14
* @returns Promise that resolves once the gas limit has been set
15
*/
16
setBlockGasLimit(blockGasLimit: NumberLike): Promise<void>;
17
```
18
19
**Usage Examples:**
20
21
```typescript
22
import { network } from "hardhat";
23
24
const { networkHelpers } = await network.connect();
25
26
// Set a low gas limit to test gas limit failures
27
await networkHelpers.setBlockGasLimit(100000);
28
29
// Set a high gas limit for gas-intensive operations
30
await networkHelpers.setBlockGasLimit(30000000);
31
32
// Reset to default (typical mainnet gas limit)
33
await networkHelpers.setBlockGasLimit(15000000);
34
```
35
36
### Set Next Block Base Fee Per Gas
37
38
Configures the base fee for the next block, essential for testing EIP-1559 fee mechanisms and fee-sensitive contracts.
39
40
```typescript { .api }
41
/**
42
* Sets the base fee of the next block
43
* @param baseFeePerGas The new base fee to use (in wei)
44
* @returns Promise that resolves once the base fee is set
45
*/
46
setNextBlockBaseFeePerGas(baseFeePerGas: NumberLike): Promise<void>;
47
```
48
49
**Usage Examples:**
50
51
```typescript
52
const { networkHelpers } = await network.connect();
53
54
// Set high base fee (100 gwei)
55
await networkHelpers.setNextBlockBaseFeePerGas(100000000000n);
56
57
// Set low base fee (1 gwei)
58
await networkHelpers.setNextBlockBaseFeePerGas(1000000000n);
59
60
// Set zero base fee
61
await networkHelpers.setNextBlockBaseFeePerGas(0);
62
```
63
64
### Set PREVRANDAO
65
66
Sets the PREVRANDAO value for the next block, used for testing contracts that depend on blockchain randomness.
67
68
```typescript { .api }
69
/**
70
* Sets the PREVRANDAO value of the next block
71
* @param prevRandao The new PREVRANDAO value to use
72
* @returns Promise that resolves once the PREVRANDAO value is set
73
*/
74
setPrevRandao(prevRandao: NumberLike): Promise<void>;
75
```
76
77
**Usage Examples:**
78
79
```typescript
80
const { networkHelpers } = await network.connect();
81
82
// Set specific PREVRANDAO value
83
await networkHelpers.setPrevRandao(123456789);
84
85
// Set using hex string
86
await networkHelpers.setPrevRandao("0x1234567890abcdef");
87
88
// Set using bigint
89
await networkHelpers.setPrevRandao(0xdeadbeefcafebaben);
90
```
91
92
### Set Coinbase
93
94
Configures the coinbase address (block reward recipient) for new blocks.
95
96
```typescript { .api }
97
/**
98
* Sets the coinbase address to be used in new blocks
99
* @param address The new coinbase address
100
* @returns Promise that resolves once the coinbase address has been set
101
*/
102
setCoinbase(address: string): Promise<void>;
103
```
104
105
**Usage Examples:**
106
107
```typescript
108
const { networkHelpers } = await network.connect();
109
110
// Set coinbase to specific address
111
await networkHelpers.setCoinbase("0x742d35Cc6635C0532925a3b8D23CAaF803C5C1b7");
112
113
// Set coinbase to test address
114
const [signer] = await ethers.getSigners();
115
await networkHelpers.setCoinbase(signer.address);
116
```
117
118
## Block Configuration Testing Patterns
119
120
### Gas Limit Testing
121
122
```typescript
123
it("should handle gas limit constraints", async () => {
124
const { networkHelpers } = await network.connect();
125
126
// Deploy gas-intensive contract
127
const contract = await ethers.deployContract("GasIntensive");
128
129
// Set very low gas limit
130
await networkHelpers.setBlockGasLimit(50000);
131
132
// Gas-intensive function should fail
133
await expect(contract.expensiveOperation()).to.be.revertedWith("out of gas");
134
135
// Increase gas limit
136
await networkHelpers.setBlockGasLimit(1000000);
137
138
// Now should succeed
139
await expect(contract.expensiveOperation()).to.not.be.reverted;
140
});
141
```
142
143
### EIP-1559 Fee Testing
144
145
```typescript
146
it("should test EIP-1559 fee mechanisms", async () => {
147
const { networkHelpers } = await network.connect();
148
149
// Set high base fee
150
const highBaseFee = ethers.parseUnits("100", "gwei");
151
await networkHelpers.setNextBlockBaseFeePerGas(highBaseFee);
152
153
// Mine block to apply base fee
154
await networkHelpers.mine();
155
156
// Transaction with low max fee should fail
157
const [signer] = await ethers.getSigners();
158
await expect(
159
signer.sendTransaction({
160
to: "0x123...",
161
value: ethers.parseEther("1"),
162
maxFeePerGas: ethers.parseUnits("50", "gwei"), // Lower than base fee
163
maxPriorityFeePerGas: ethers.parseUnits("1", "gwei")
164
})
165
).to.be.reverted;
166
167
// Transaction with sufficient max fee should succeed
168
await expect(
169
signer.sendTransaction({
170
to: "0x123...",
171
value: ethers.parseEther("1"),
172
maxFeePerGas: ethers.parseUnits("150", "gwei"), // Higher than base fee
173
maxPriorityFeePerGas: ethers.parseUnits("1", "gwei")
174
})
175
).to.not.be.reverted;
176
});
177
```
178
179
### Randomness Testing
180
181
```typescript
182
it("should test contract randomness", async () => {
183
const { networkHelpers } = await network.connect();
184
185
const lottery = await ethers.deployContract("Lottery");
186
187
// Set predictable PREVRANDAO for testing
188
await networkHelpers.setPrevRandao(12345);
189
190
// Draw should be predictable with known seed
191
const tx = await lottery.draw();
192
const receipt = await tx.wait();
193
194
// Verify expected result based on known PREVRANDAO
195
const winner = await lottery.getWinner();
196
// Assert specific winner based on deterministic randomness
197
198
// Change PREVRANDAO and test different outcome
199
await networkHelpers.setPrevRandao(67890);
200
await lottery.draw();
201
202
const newWinner = await lottery.getWinner();
203
expect(newWinner).to.not.equal(winner);
204
});
205
```
206
207
### Coinbase Testing
208
209
```typescript
210
it("should test block reward distribution", async () => {
211
const { networkHelpers } = await network.connect();
212
213
const rewardContract = await ethers.deployContract("BlockRewardTracker");
214
const [deployer, miner] = await ethers.getSigners();
215
216
// Set specific coinbase address
217
await networkHelpers.setCoinbase(miner.address);
218
219
// Mine blocks and track rewards
220
const initialBalance = await ethers.provider.getBalance(miner.address);
221
222
await networkHelpers.mine(10);
223
224
// Check if coinbase address received block rewards
225
const finalBalance = await ethers.provider.getBalance(miner.address);
226
227
// In test networks, coinbase might not automatically receive rewards
228
// but the contract can check block.coinbase
229
expect(await rewardContract.getCurrentCoinbase()).to.equal(miner.address);
230
});
231
```
232
233
### Multi-Block Configuration
234
235
```typescript
236
it("should handle multiple block configuration changes", async () => {
237
const { networkHelpers } = await network.connect();
238
239
const feeTracker = await ethers.deployContract("FeeTracker");
240
241
// Configure different fee schedules
242
const fees = [
243
ethers.parseUnits("10", "gwei"),
244
ethers.parseUnits("50", "gwei"),
245
ethers.parseUnits("25", "gwei")
246
];
247
248
for (let i = 0; i < fees.length; i++) {
249
// Set base fee for next block
250
await networkHelpers.setNextBlockBaseFeePerGas(fees[i]);
251
252
// Record fee in contract (contract reads block.basefee)
253
await feeTracker.recordCurrentFee();
254
255
// Mine to apply the fee
256
await networkHelpers.mine();
257
}
258
259
// Verify fee history
260
const recordedFees = await feeTracker.getFeeHistory();
261
expect(recordedFees).to.deep.equal(fees);
262
});
263
```
264
265
### Gas Price Dynamics
266
267
```typescript
268
it("should test gas price dynamics", async () => {
269
const { networkHelpers } = await network.connect();
270
271
const auction = await ethers.deployContract("GasAuction");
272
273
// Start with low base fee
274
await networkHelpers.setNextBlockBaseFeePerGas(ethers.parseUnits("1", "gwei"));
275
await networkHelpers.mine();
276
277
// Bid with current low fees
278
await auction.bid({
279
value: ethers.parseEther("1"),
280
maxFeePerGas: ethers.parseUnits("10", "gwei")
281
});
282
283
// Simulate network congestion with high base fee
284
await networkHelpers.setNextBlockBaseFeePerGas(ethers.parseUnits("100", "gwei"));
285
await networkHelpers.mine();
286
287
// Higher gas price bid should win
288
await auction.bid({
289
value: ethers.parseEther("1.5"),
290
maxFeePerGas: ethers.parseUnits("150", "gwei")
291
});
292
293
const winner = await auction.getWinner();
294
expect(winner).to.not.equal(ethers.ZeroAddress);
295
});
296
```
297
298
### Block Properties Integration
299
300
```typescript
301
it("should integrate multiple block properties", async () => {
302
const { networkHelpers } = await network.connect();
303
304
const blockInfo = await ethers.deployContract("BlockInfo");
305
const [deployer, miner] = await ethers.getSigners();
306
307
// Configure all block properties
308
await networkHelpers.setBlockGasLimit(8000000);
309
await networkHelpers.setNextBlockBaseFeePerGas(ethers.parseUnits("20", "gwei"));
310
await networkHelpers.setPrevRandao(0xabcdef123456789n);
311
await networkHelpers.setCoinbase(miner.address);
312
313
// Capture block info
314
await blockInfo.captureBlockInfo();
315
316
// Verify all properties were set correctly
317
expect(await blockInfo.gasLimit()).to.equal(8000000);
318
expect(await blockInfo.baseFee()).to.equal(ethers.parseUnits("20", "gwei"));
319
expect(await blockInfo.prevRandao()).to.equal(0xabcdef123456789n);
320
expect(await blockInfo.coinbase()).to.equal(miner.address);
321
});
322
```