Skip to content

Commit fee887c

Browse files
authored
Added the completed invariant fuzzing suite (#106)
1 parent ca05c11 commit fee887c

35 files changed

+4734
-1
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,9 @@ bootstrap.out
3535

3636
# MacOS
3737
.DS_Store
38+
39+
# Fuzz
40+
crytic-export
41+
echidna-corpus
42+
medusa-corpus
43+
med-logs

echidna-config.yaml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
workers: 1
2+
3+
testMode: assertion
4+
5+
prefix: echidna_
6+
corpusDir: echidna-corpus
7+
8+
testLimit: 100000000000
9+
# testLimit: 1000000
10+
codeSize: 100000
11+
12+
shrinkLimit: 1000
13+
14+
seqLen: 100
15+
16+
deployer: "0xfffff"
17+
sender: ["0x10000", "0x20000", "0x30000"]
18+
19+
filterBlacklist: true
20+
filterFunctions:
21+
[
22+
"Fuzz.handler_activateWithdrawalQueue()",
23+
"Fuzz.handler_deactivateWithdrawalQueue()",
24+
"Fuzz.handler_deposit(uint8,uint256,uint256)",
25+
"Fuzz.handler_depositETH(uint256,uint256)",
26+
"Fuzz.handler_depositTo(uint8,uint8,uint256,uint256)",
27+
"Fuzz.handler_depositToETH(uint8,uint256,uint256)",
28+
"Fuzz.handler_finaliseQueuedWithdrawal(uint8,uint256)",
29+
"Fuzz.handler_finaliseQueuedWithdrawalsAggregated(uint8,uint8,uint256,uint256)",
30+
"Fuzz.handler_onMessageReceiveChild(bool,uint8,uint8,uint8,uint256)",
31+
"Fuzz.handler_onMessageReceiveRoot(bool,uint8,uint8,uint8,uint256)",
32+
"Fuzz.handler_pauseChild()",
33+
"Fuzz.handler_pauseRoot()",
34+
"Fuzz.handler_setRateControlThreshold(uint8,uint256,uint256,uint256)",
35+
"Fuzz.handler_setWithdrawalDelay(uint256)",
36+
"Fuzz.handler_unpauseChild()",
37+
"Fuzz.handler_unpauseRoot()",
38+
"Fuzz.handler_updateImxCumulativeDepositLimit(uint256)",
39+
"Fuzz.handler_withdraw(uint8,uint256,uint256)",
40+
"Fuzz.handler_withdrawETH(uint256,uint256)",
41+
"Fuzz.handler_withdrawETHTo(uint8,uint256,uint256)",
42+
"Fuzz.handler_withdrawIMX(uint256,uint256)",
43+
"Fuzz.handler_withdrawIMXTo(uint8,uint256,uint256)",
44+
"Fuzz.handler_withdrawTo(uint8,uint8,uint256,uint256)",
45+
"Fuzz.handler_withdrawWIMX(uint256,uint256)",
46+
"Fuzz.handler_withdrawWIMXTo(uint8,uint256,uint256)",
47+
]
48+
49+
cryticArgs: ["--foundry-compile-all"]
50+
51+
# Initial Ether balance of contractAddr
52+
balanceContract: 0xffffffffffffffffffffffffffffffffffffffffffffffff
53+
# maximum value to send to payable functions
54+
maxValue: 100000000000000000000000000000 # 100000000000 eth

medusa.json

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
{
2+
"fuzzing": {
3+
"workers": 1,
4+
"workerResetLimit": 50,
5+
"timeout": 0,
6+
"testLimit": 1000000,
7+
"callSequenceLength": 100,
8+
"corpusDirectory": "medusa-corpus",
9+
"coverageEnabled": true,
10+
"deploymentOrder": [
11+
"Fuzz"
12+
],
13+
"targetContracts": [
14+
"Fuzz"
15+
],
16+
"targetContractsBalances": [
17+
"0xffffffffffffffffffffffffffffffffffffffffffffffff"
18+
],
19+
"constructorArgs": {},
20+
"deployerAddress": "0xfffff",
21+
"senderAddresses": [
22+
"0x10000",
23+
"0x20000",
24+
"0x30000"
25+
],
26+
"blockNumberDelayMax": 60480,
27+
"blockTimestampDelayMax": 604800,
28+
"blockGasLimit": 125000000,
29+
"transactionGasLimit": 12500000,
30+
"testing": {
31+
"stopOnFailedTest": false,
32+
"stopOnFailedContractMatching": true,
33+
"stopOnNoTests": true,
34+
"testAllContracts": false,
35+
"traceAll": false,
36+
"excludeFunctionSignatures": [
37+
"Fuzz.handler_activateWithdrawalQueue()",
38+
"Fuzz.handler_deactivateWithdrawalQueue()",
39+
"Fuzz.handler_deposit(uint8,uint256,uint256)",
40+
"Fuzz.handler_depositETH(uint256,uint256)",
41+
"Fuzz.handler_depositTo(uint8,uint8,uint256,uint256)",
42+
"Fuzz.handler_depositToETH(uint8,uint256,uint256)",
43+
"Fuzz.handler_finaliseQueuedWithdrawal(uint8,uint256)",
44+
"Fuzz.handler_finaliseQueuedWithdrawalsAggregated(uint8,uint8,uint256,uint256)",
45+
"Fuzz.handler_onMessageReceiveChild(bool,uint8,uint8,uint8,uint256)",
46+
"Fuzz.handler_onMessageReceiveRoot(bool,uint8,uint8,uint8,uint256)",
47+
"Fuzz.handler_pauseChild()",
48+
"Fuzz.handler_pauseRoot()",
49+
"Fuzz.handler_setRateControlThreshold(uint8,uint256,uint256,uint256)",
50+
"Fuzz.handler_setWithdrawalDelay(uint256)",
51+
"Fuzz.handler_unpauseChild()",
52+
"Fuzz.handler_unpauseRoot()",
53+
"Fuzz.handler_updateImxCumulativeDepositLimit(uint256)",
54+
"Fuzz.handler_withdraw(uint8,uint256,uint256)",
55+
"Fuzz.handler_withdrawETH(uint256,uint256)",
56+
"Fuzz.handler_withdrawETHTo(uint8,uint256,uint256)",
57+
"Fuzz.handler_withdrawIMX(uint256,uint256)",
58+
"Fuzz.handler_withdrawIMXTo(uint8,uint256,uint256)",
59+
"Fuzz.handler_withdrawTo(uint8,uint8,uint256,uint256)",
60+
"Fuzz.handler_withdrawWIMX(uint256,uint256)",
61+
"Fuzz.handler_withdrawWIMXTo(uint8,uint256,uint256)"
62+
],
63+
"assertionTesting": {
64+
"enabled": true,
65+
"testViewMethods": true,
66+
"panicCodeConfig": {
67+
"failOnCompilerInsertedPanic": false,
68+
"failOnAssertion": true,
69+
"failOnArithmeticUnderflow": false,
70+
"failOnDivideByZero": false,
71+
"failOnEnumTypeConversionOutOfBounds": false,
72+
"failOnIncorrectStorageAccess": false,
73+
"failOnPopEmptyArray": false,
74+
"failOnOutOfBoundsArrayAccess": false,
75+
"failOnAllocateTooMuchMemory": false,
76+
"failOnCallUninitializedVariable": false
77+
}
78+
},
79+
"propertyTesting": {
80+
"enabled": false,
81+
"testPrefixes": [
82+
"property_"
83+
]
84+
},
85+
"optimizationTesting": {
86+
"enabled": false,
87+
"testPrefixes": [
88+
"optimize_"
89+
]
90+
}
91+
},
92+
"chainConfig": {
93+
"codeSizeCheckDisabled": true,
94+
"cheatCodes": {
95+
"cheatCodesEnabled": true,
96+
"enableFFI": false
97+
}
98+
}
99+
},
100+
"compilation": {
101+
"platform": "crytic-compile",
102+
"platformConfig": {
103+
"target": ".",
104+
"solcVersion": "",
105+
"exportDirectory": "",
106+
"args": [
107+
"--foundry-compile-all"
108+
]
109+
}
110+
},
111+
"logging": {
112+
"level": "info",
113+
"logDirectory": "med-logs",
114+
"noColor": true
115+
}
116+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
4949
"@nomicfoundation/hardhat-verify": "^2.0.0",
5050
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
51+
"@perimetersec/fuzzlib": "0.3.0",
5152
"@typechain/ethers-v6": "^0.5.0",
5253
"@typechain/hardhat": "^9.0.0",
5354
"@types/chai": "^4.2.0",

remappings.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
@openzeppelin/contracts-upgradeable=lib/openzeppelin-contracts-upgradeable/contracts
33
@axelar-cgp-solidity=lib/axelar-cgp-solidity
44
@axelar-gmp-sdk-solidity=lib/axelar-gmp-sdk-solidity
5-
@axelar-network/axelar-gmp-sdk-solidity/=lib/axelar-gmp-sdk-solidity/
5+
@axelar-network/axelar-gmp-sdk-solidity/=lib/axelar-gmp-sdk-solidity/
6+
@perimetersec/fuzzlib/src/=node_modules/@perimetersec/fuzzlib/src/

test/fuzzing/Fuzz.sol

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// SPDX-License-Identifier: GPL-3.0
2+
pragma solidity ^0.8.0;
3+
4+
import "./FuzzIntegrityChildERC20Bridge.sol";
5+
import "./FuzzIntegrityRootERC20BridgeFlowRate.sol";
6+
7+
/**
8+
* @title Fuzz
9+
* @author 0xScourgedev
10+
* @notice Composite contract for all of the handlers
11+
*/
12+
contract Fuzz is FuzzChildERC20BridgeIntegrity, FuzzRootERC20BridgeFlowRateIntegrity {
13+
constructor() payable {
14+
setup();
15+
setupActors();
16+
}
17+
}

test/fuzzing/FuzzIntegrityBase.sol

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// SPDX-License-Identifier: GPL-3.0
2+
pragma solidity ^0.8.0;
3+
4+
/**
5+
* @title FuzzIntegrityBase
6+
* @author 0xScourgedev
7+
* @notice Contains the base for all fuzz integrity contracts
8+
*/
9+
abstract contract FuzzIntegrityBase {
10+
/**
11+
* @notice Executes a delegatecall to the this contract with the given callData
12+
* @dev This function is used to call the handlers in order to test the integrity of the handlers
13+
* @param callData The data to be used in the delegatecall
14+
* @return the success of the delegatecall and the return data
15+
*/
16+
function _testSelf(bytes memory callData) internal returns (bool, bytes4) {
17+
(bool success, bytes memory returnData) = address(this).delegatecall(callData);
18+
19+
return (success, bytes4(returnData));
20+
}
21+
}

0 commit comments

Comments
 (0)