You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+60-49Lines changed: 60 additions & 49 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -73,10 +73,9 @@ To test an ERC20 token, follow these steps:
73
73
74
74
You can see the output for a [compliant token](#example-output-for-a-compliant-token), and [non compliant token](#example-output-for-a-non-compliant-token).
75
75
76
-
77
76
#### Integration
78
77
79
-
Decide if you want to do internal or external testing. Both approaches have advantages and disadvantages, you can check more information about them [here](https://secure-contracts.com/program-analysis/echidna/basic/common-testing-approaches.html).
78
+
Decide if you want to do internal or external testing. Both approaches have advantages and disadvantages, you can check more information about them [here](https://secure-contracts.com/program-analysis/echidna/basic/common-testing-approaches.html).
80
79
81
80
For internal testing, create a new Solidity file containing the `CryticERC20InternalHarness` contract. `USER1`, `USER2` and `USER3` constants are initialized by default in `PropertiesConstants` contract to be the addresses from where echidna sends transactions, and `INITIAL_BALANCE` is by default `1000e18`:
// Uncomment the following lines for external testing
176
-
// "testing": {
177
-
// "testAllContracts": true
178
-
// },
179
-
"compilation": {
180
-
"platform": "crytic-compile",
181
-
"platformConfig": {
182
-
"target": ".",
183
-
"solcVersion": "",
184
-
"exportDirectory": "",
185
-
"args": ["--foundry-compile-all"]
186
-
}
187
-
}
167
+
"enabled": false
168
+
}
169
+
},
170
+
// Uncomment the following lines for external testing
171
+
// "testing": {
172
+
// "testAllContracts": true
173
+
// },
174
+
"compilation": {
175
+
"platform": "crytic-compile",
176
+
"platformConfig": {
177
+
"target": ".",
178
+
"solcVersion": "",
179
+
"exportDirectory": "",
180
+
"args": ["--foundry-compile-all"]
181
+
}
182
+
}
188
183
}
189
184
```
190
185
@@ -260,11 +255,12 @@ To test an ERC721 token, follow these steps:
260
255
261
256
You can see the output for a [compliant token](#example-output-for-a-compliant-token-1), and [non compliant token](#example-output-for-a-non-compliant-token-1).
262
257
263
-
264
258
#### Integration
265
-
Decide if you want to do internal or external testing. Both approaches have advantages and disadvantages, you can check more information about them [here](https://secure-contracts.com/program-analysis/echidna/basic/common-testing-approaches.html).
259
+
260
+
Decide if you want to do internal or external testing. Both approaches have advantages and disadvantages, you can check more information about them [here](https://secure-contracts.com/program-analysis/echidna/basic/common-testing-approaches.html).
266
261
267
262
For internal testing, create a new Solidity file containing the `CryticERC721InternalHarness` contract. `USER1`, `USER2` and `USER3` constants are initialized by default in `PropertiesConstants` contract to be the addresses from where echidna sends transactions.
contract CryticTokenMock is MyToken, PropertiesConstants {
298
-
294
+
uint256 public counter;
299
295
bool public isMintableOrBurnable;
300
296
301
-
constructor() {
297
+
constructor() {
302
298
isMintableOrBurnable = true;
303
299
}
300
+
301
+
function burn(uint256 tokenId) public {
302
+
_burn(tokenId);
303
+
}
304
+
305
+
function _customMint(address to, uint256 amount) public {
306
+
for (uint256 i; i < amount; i++) {
307
+
_mint(to, counter++);
308
+
}
309
+
}
304
310
}
305
311
```
306
312
307
313
#### Configuration
314
+
308
315
Create the following Echidna config file
309
316
310
317
```yaml
@@ -323,20 +330,23 @@ allContracts: true
323
330
324
331
To perform more than one test, save the files with a descriptive path, to identify what test each file or corpus belongs to. For these examples, we use `tests/crytic/erc721/echidna-internal.yaml` and `tests/crytic/erc721/echidna-external.yaml` for the Echidna tests for ERC721. We recommended to modify the `corpusDir` for external tests accordingly.
325
332
326
-
The above configuration will start Echidna in assertion mode. Contract will be deployed from address `0x10000`, and transactions will be sent from the owner and two different users (`0x20000` and `0x30000`). There is an initial limit of `100000` tests, but depending on the token code complexity, this can be increased. Finally, once Echidna finishes the fuzzing campaign, corpus and coverage results will be available in the `tests/crytic/erc721/echidna-corpus-internal` directory.
333
+
The above configuration will start Echidna in assertion mode. Contract will be deployed from address `0x10000`, and transactions will be sent from the owner and two different users (`0x20000` and `0x30000`). There is an initial limit of `100000` tests, but depending on the token code complexity, this can be increased. Finally, once Echidna finishes the fuzzing campaign, corpus and coverage results will be available in the `tests/crytic/erc721/echidna-corpus-internal` directory.
327
334
328
335
#### Run
329
-
Run Echidna:
330
-
- For internal testing: `echidna . --contract CryticERC721InternalHarness --config tests/crytic/erc721/echidna-internal.yaml`
331
-
- For external testing: `echidna . --contract CryticERC721ExternalHarness --config tests/crytic/erc721/echidna-external.yaml`
332
-
336
+
337
+
Run Echidna:
338
+
339
+
- For internal testing: `echidna . --contract CryticERC721InternalHarness --config tests/crytic/erc721/echidna-internal.yaml`
340
+
- For external testing: `echidna . --contract CryticERC721ExternalHarness --config tests/crytic/erc721/echidna-external.yaml`
341
+
333
342
Finally, inspect the coverage report in `tests/crytic/erc721/echidna-corpus-internal` or `tests/crytic/erc721/echidna-corpus-external` when it finishes.
334
343
335
344
#### Example: Output for a compliant token
336
345
337
346
If the token under test is compliant and no properties will fail during fuzzing, the Echidna output should be similar to the screen below:
For this example, the ExampleToken's balanceOf function was modified so it does not check that `owner` is the zero address:
363
+
353
364
```
354
365
function balanceOf(address owner) public view virtual override returns (uint256) {
355
366
return _balances[owner];
356
367
}
357
368
```
358
369
359
370
In this case, the Echidna output should be similar to the screen below, notice that all functions that rely on `balanceOf()` to work correctly will have their assertions broken, and will report the situation.
@@ -376,11 +388,11 @@ Event sequence: Panic(1), AssertFail("address(0) balance query should have rever
376
388
### ERC4626 Tests
377
389
378
390
To test an ERC4626 token, follow these steps:
391
+
379
392
1. [Integration](#integration-2)
380
393
2. [Configuration](#configuration-2)
381
394
3. [Run](#run-2)
382
395
383
-
384
396
#### Integration
385
397
386
398
Create a new Solidity file containing the `CryticERC4626Harness` contract. Make sure it properly initializes your ERC4626 vault with a test token (`TestERC20Token`):
@@ -454,7 +466,6 @@ We provide a number of tests related with fundamental mathematical properties of
454
466
1. [Integration](#integration-3)
455
467
2. [Run](#run-3)
456
468
457
-
458
469
#### Integration
459
470
460
471
Create a new Solidity file containing the `ABDKMath64x64Harness` contract:
0 commit comments