Skip to content

Commit

Permalink
Added the completed invariant fuzzing suite (#106)
Browse files Browse the repository at this point in the history
  • Loading branch information
ljz3 authored Sep 11, 2024
1 parent ca05c11 commit fee887c
Show file tree
Hide file tree
Showing 35 changed files with 4,734 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@ bootstrap.out

# MacOS
.DS_Store

# Fuzz
crytic-export
echidna-corpus
medusa-corpus
med-logs
54 changes: 54 additions & 0 deletions echidna-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
workers: 1

testMode: assertion

prefix: echidna_
corpusDir: echidna-corpus

testLimit: 100000000000
# testLimit: 1000000
codeSize: 100000

shrinkLimit: 1000

seqLen: 100

deployer: "0xfffff"
sender: ["0x10000", "0x20000", "0x30000"]

filterBlacklist: true
filterFunctions:
[
"Fuzz.handler_activateWithdrawalQueue()",
"Fuzz.handler_deactivateWithdrawalQueue()",
"Fuzz.handler_deposit(uint8,uint256,uint256)",
"Fuzz.handler_depositETH(uint256,uint256)",
"Fuzz.handler_depositTo(uint8,uint8,uint256,uint256)",
"Fuzz.handler_depositToETH(uint8,uint256,uint256)",
"Fuzz.handler_finaliseQueuedWithdrawal(uint8,uint256)",
"Fuzz.handler_finaliseQueuedWithdrawalsAggregated(uint8,uint8,uint256,uint256)",
"Fuzz.handler_onMessageReceiveChild(bool,uint8,uint8,uint8,uint256)",
"Fuzz.handler_onMessageReceiveRoot(bool,uint8,uint8,uint8,uint256)",
"Fuzz.handler_pauseChild()",
"Fuzz.handler_pauseRoot()",
"Fuzz.handler_setRateControlThreshold(uint8,uint256,uint256,uint256)",
"Fuzz.handler_setWithdrawalDelay(uint256)",
"Fuzz.handler_unpauseChild()",
"Fuzz.handler_unpauseRoot()",
"Fuzz.handler_updateImxCumulativeDepositLimit(uint256)",
"Fuzz.handler_withdraw(uint8,uint256,uint256)",
"Fuzz.handler_withdrawETH(uint256,uint256)",
"Fuzz.handler_withdrawETHTo(uint8,uint256,uint256)",
"Fuzz.handler_withdrawIMX(uint256,uint256)",
"Fuzz.handler_withdrawIMXTo(uint8,uint256,uint256)",
"Fuzz.handler_withdrawTo(uint8,uint8,uint256,uint256)",
"Fuzz.handler_withdrawWIMX(uint256,uint256)",
"Fuzz.handler_withdrawWIMXTo(uint8,uint256,uint256)",
]

cryticArgs: ["--foundry-compile-all"]

# Initial Ether balance of contractAddr
balanceContract: 0xffffffffffffffffffffffffffffffffffffffffffffffff
# maximum value to send to payable functions
maxValue: 100000000000000000000000000000 # 100000000000 eth
116 changes: 116 additions & 0 deletions medusa.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
{
"fuzzing": {
"workers": 1,
"workerResetLimit": 50,
"timeout": 0,
"testLimit": 1000000,
"callSequenceLength": 100,
"corpusDirectory": "medusa-corpus",
"coverageEnabled": true,
"deploymentOrder": [
"Fuzz"
],
"targetContracts": [
"Fuzz"
],
"targetContractsBalances": [
"0xffffffffffffffffffffffffffffffffffffffffffffffff"
],
"constructorArgs": {},
"deployerAddress": "0xfffff",
"senderAddresses": [
"0x10000",
"0x20000",
"0x30000"
],
"blockNumberDelayMax": 60480,
"blockTimestampDelayMax": 604800,
"blockGasLimit": 125000000,
"transactionGasLimit": 12500000,
"testing": {
"stopOnFailedTest": false,
"stopOnFailedContractMatching": true,
"stopOnNoTests": true,
"testAllContracts": false,
"traceAll": false,
"excludeFunctionSignatures": [
"Fuzz.handler_activateWithdrawalQueue()",
"Fuzz.handler_deactivateWithdrawalQueue()",
"Fuzz.handler_deposit(uint8,uint256,uint256)",
"Fuzz.handler_depositETH(uint256,uint256)",
"Fuzz.handler_depositTo(uint8,uint8,uint256,uint256)",
"Fuzz.handler_depositToETH(uint8,uint256,uint256)",
"Fuzz.handler_finaliseQueuedWithdrawal(uint8,uint256)",
"Fuzz.handler_finaliseQueuedWithdrawalsAggregated(uint8,uint8,uint256,uint256)",
"Fuzz.handler_onMessageReceiveChild(bool,uint8,uint8,uint8,uint256)",
"Fuzz.handler_onMessageReceiveRoot(bool,uint8,uint8,uint8,uint256)",
"Fuzz.handler_pauseChild()",
"Fuzz.handler_pauseRoot()",
"Fuzz.handler_setRateControlThreshold(uint8,uint256,uint256,uint256)",
"Fuzz.handler_setWithdrawalDelay(uint256)",
"Fuzz.handler_unpauseChild()",
"Fuzz.handler_unpauseRoot()",
"Fuzz.handler_updateImxCumulativeDepositLimit(uint256)",
"Fuzz.handler_withdraw(uint8,uint256,uint256)",
"Fuzz.handler_withdrawETH(uint256,uint256)",
"Fuzz.handler_withdrawETHTo(uint8,uint256,uint256)",
"Fuzz.handler_withdrawIMX(uint256,uint256)",
"Fuzz.handler_withdrawIMXTo(uint8,uint256,uint256)",
"Fuzz.handler_withdrawTo(uint8,uint8,uint256,uint256)",
"Fuzz.handler_withdrawWIMX(uint256,uint256)",
"Fuzz.handler_withdrawWIMXTo(uint8,uint256,uint256)"
],
"assertionTesting": {
"enabled": true,
"testViewMethods": true,
"panicCodeConfig": {
"failOnCompilerInsertedPanic": false,
"failOnAssertion": true,
"failOnArithmeticUnderflow": false,
"failOnDivideByZero": false,
"failOnEnumTypeConversionOutOfBounds": false,
"failOnIncorrectStorageAccess": false,
"failOnPopEmptyArray": false,
"failOnOutOfBoundsArrayAccess": false,
"failOnAllocateTooMuchMemory": false,
"failOnCallUninitializedVariable": false
}
},
"propertyTesting": {
"enabled": false,
"testPrefixes": [
"property_"
]
},
"optimizationTesting": {
"enabled": false,
"testPrefixes": [
"optimize_"
]
}
},
"chainConfig": {
"codeSizeCheckDisabled": true,
"cheatCodes": {
"cheatCodesEnabled": true,
"enableFFI": false
}
}
},
"compilation": {
"platform": "crytic-compile",
"platformConfig": {
"target": ".",
"solcVersion": "",
"exportDirectory": "",
"args": [
"--foundry-compile-all"
]
}
},
"logging": {
"level": "info",
"logDirectory": "med-logs",
"noColor": true
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"@nomicfoundation/hardhat-toolbox": "^4.0.0",
"@nomicfoundation/hardhat-verify": "^2.0.0",
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
"@perimetersec/fuzzlib": "0.3.0",
"@typechain/ethers-v6": "^0.5.0",
"@typechain/hardhat": "^9.0.0",
"@types/chai": "^4.2.0",
Expand Down
3 changes: 2 additions & 1 deletion remappings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
@openzeppelin/contracts-upgradeable=lib/openzeppelin-contracts-upgradeable/contracts
@axelar-cgp-solidity=lib/axelar-cgp-solidity
@axelar-gmp-sdk-solidity=lib/axelar-gmp-sdk-solidity
@axelar-network/axelar-gmp-sdk-solidity/=lib/axelar-gmp-sdk-solidity/
@axelar-network/axelar-gmp-sdk-solidity/=lib/axelar-gmp-sdk-solidity/
@perimetersec/fuzzlib/src/=node_modules/@perimetersec/fuzzlib/src/
17 changes: 17 additions & 0 deletions test/fuzzing/Fuzz.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import "./FuzzIntegrityChildERC20Bridge.sol";
import "./FuzzIntegrityRootERC20BridgeFlowRate.sol";

/**
* @title Fuzz
* @author 0xScourgedev
* @notice Composite contract for all of the handlers
*/
contract Fuzz is FuzzChildERC20BridgeIntegrity, FuzzRootERC20BridgeFlowRateIntegrity {
constructor() payable {
setup();
setupActors();
}
}
21 changes: 21 additions & 0 deletions test/fuzzing/FuzzIntegrityBase.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

/**
* @title FuzzIntegrityBase
* @author 0xScourgedev
* @notice Contains the base for all fuzz integrity contracts
*/
abstract contract FuzzIntegrityBase {
/**
* @notice Executes a delegatecall to the this contract with the given callData
* @dev This function is used to call the handlers in order to test the integrity of the handlers
* @param callData The data to be used in the delegatecall
* @return the success of the delegatecall and the return data
*/
function _testSelf(bytes memory callData) internal returns (bool, bytes4) {
(bool success, bytes memory returnData) = address(this).delegatecall(callData);

return (success, bytes4(returnData));
}
}
Loading

0 comments on commit fee887c

Please sign in to comment.