Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency between how Medusa and Echidna manage libraries. #529

Closed
beirao opened this issue Jan 6, 2025 · 11 comments
Closed

Inconsistency between how Medusa and Echidna manage libraries. #529

beirao opened this issue Jan 6, 2025 · 11 comments

Comments

@beirao
Copy link

beirao commented Jan 6, 2025

After successfully setting up a test suite with Echidna, I’ve been trying to integrate Medusa for further testing. However, I’ve run into configuration issues that I suspect are causing the setup to fail.

Here is my Echidna configuration file, which works perfectly:

seqLen: 100
testLimit: 4000
workers: 10
coverage: true
corpusDir: "echidna-corpus"
testMode: assertion
deployer: "0x10000"
sender: ["0x10000", "0x20000", "0x30000"]
coverageFormats: ["txt"]
shrinkLimit: 2000
quiet: true
maxTimeDelay: 3600 # 1 hour
maxBlockDelay: 864
filterBlacklist: true
filterFunctions: []
codeSize: 0xffffffff
cryticArgs: [
  "--compile-libraries=(BorrowLogic,0xf01),(DepositLogic,0xf03),(FlashLoanLogic,0xf11),(GenericLogic,0xf12),(LiquidationLogic,0xf13),(MiniPoolBorrowLogic,0xa01),(MiniPoolDepositLogic,0xa03),(MiniPoolFlashLoanLogic,0xa11),(MiniPoolGenericLogic,0xa12),(MiniPoolLiquidationLogic,0xa13),(MiniPoolReserveLogic,0xa15),(MiniPoolValidationLogic,0xa16),(MiniPoolWithdrawLogic,0xa17)"
]
deployContracts: [
  ["0xf01", "BorrowLogic"],
  ["0xf03", "DepositLogic"],
  ["0xf11", "FlashLoanLogic"],
  ["0xf12", "GenericLogic"],
  ["0xf13", "LiquidationLogic"],
  ["0xa01", "MiniPoolBorrowLogic"],
  ["0xa03", "MiniPoolDepositLogic"],
  ["0xa11", "MiniPoolFlashLoanLogic"],
  ["0xa12", "MiniPoolGenericLogic"],
  ["0xa13", "MiniPoolLiquidationLogic"],
  ["0xa15", "MiniPoolReserveLogic"],
  ["0xa16", "MiniPoolValidationLogic"],
  ["0xa17", "MiniPoolWithdrawLogic"]
]

Here is my Medusa configuration file:

{
	"fuzzing": {
	  "workers": 10,
	  "workerResetLimit": 50,
	  "timeout": 0,
	  "testLimit": 0,
	  "shrinkLimit": 5000,
	  "callSequenceLength": 100,
	  "corpusDirectory": "",
	  "coverageEnabled": true,
	  "targetContracts": [],
	  "predeployedContracts": {
		  "BorrowLogic": "0xf01",
		  "DepositLogic": "0xf03",
		  "FlashLoanLogic": "0xf11",
		  "GenericLogic": "0xf12", 
		  "LiquidationLogic": "0xf13",

		  "MiniPoolBorrowLogic": "0xa01",
		  "MiniPoolDepositLogic": "0xa03",
		  "MiniPoolFlashLoanLogic": "0xa11",
		  "MiniPoolGenericLogic": "0xa12",
		  "MiniPoolLiquidationLogic": "0xa13",
		  "MiniPoolReserveLogic": "0xa15",
		  "MiniPoolValidationLogic": "0xa16",
		  "MiniPoolWithdrawLogic": "0xa17"
	  },
	  "targetContractsBalances": [],
	  "constructorArgs": {},
	  "deployerAddress": "0x30000",
	  "senderAddresses": ["0x10000", "0x20000", "0x30000"],
	  "blockNumberDelayMax": 60480,
	  "blockTimestampDelayMax": 604800,
	  "blockGasLimit": 125000000,
	  "transactionGasLimit": 12500000,
	  "testing": {
		"stopOnFailedTest": true,
		"stopOnFailedContractMatching": false,
		"stopOnNoTests": true,
		"testAllContracts": false,
		"traceAll": false,
		"assertionTesting": {
		  "enabled": true,
		  "testViewMethods": false,
		  "panicCodeConfig": {
			"failOnCompilerInsertedPanic": false,
			"failOnAssertion": true,
			"failOnArithmeticUnderflow": false,
			"failOnDivideByZero": false,
			"failOnEnumTypeConversionOutOfBounds": false,
			"failOnIncorrectStorageAccess": false,
			"failOnPopEmptyArray": false,
			"failOnOutOfBoundsArrayAccess": false,
			"failOnAllocateTooMuchMemory": false,
			"failOnCallUninitializedVariable": false
		  }
		},
		"propertyTesting": {
		  "enabled": true,
		  "testPrefixes": ["property_"]
		},
		"optimizationTesting": {
		  "enabled": true,
		  "testPrefixes": ["optimize_"]
		},
		"targetFunctionSignatures": [],
		"excludeFunctionSignatures": []
	  },
	  "chainConfig": {
		"codeSizeCheckDisabled": true,
		"cheatCodes": {
		  "cheatCodesEnabled": true,
		  "enableFFI": false
		},
		"skipAccountChecks": true
	  }
	},
	"compilation": {
	  "platform": "crytic-compile",
	  "platformConfig": {
		"target": "../../../contracts",
		"solcVersion": "",
		"exportDirectory": "",
		"args": [
			"--foundry-compile-all",
			"--compile-libraries=(BorrowLogic,0xf01),(DepositLogic,0xf03),(FlashLoanLogic,0xf11),(GenericLogic,0xf12),(LiquidationLogic,0xf13),(MiniPoolBorrowLogic,0xa01),(MiniPoolDepositLogic,0xa03),(MiniPoolFlashLoanLogic,0xa11),(MiniPoolGenericLogic,0xa12),(MiniPoolLiquidationLogic,0xa13),(MiniPoolReserveLogic,0xa15),(MiniPoolValidationLogic,0xa16),(MiniPoolWithdrawLogic,0xa17)"
			]	  
		}
	},
	"logging": {
	  "level": "info",
	  "logDirectory": "",
	  "noColor": false
	}
  }

When I run the command below, I encounter an error related to the predeployed contracts not being found in the compilation artifacts:

medusa fuzz --config config/medusa_config2.json
Error Log:
⇾ Reading the configuration file at: config/medusa_config2.json
⇾ Compiling targets with crytic-compile
⇾ Running command:
/opt/homebrew/bin/crytic-compile ../../../contracts --export-format solc --foundry-compile-all --compile-libraries=(BorrowLogic,0xf01),(DepositLogic,0xf03),(FlashLoanLogic,0xf11),(GenericLogic,0xf12),(LiquidationLogic,0xf13),(MiniPoolBorrowLogic,0xa01),(MiniPoolDepositLogic,0xa03),(MiniPoolFlashLoanLogic,0xa11),(MiniPoolGenericLogic,0xa12),(MiniPoolLiquidationLogic,0xa13),(MiniPoolReserveLogic,0xa15),(MiniPoolValidationLogic,0xa16),(MiniPoolWithdrawLogic,0xa17)
⇾ Finished compiling targets in 0s
⇾ Initializing corpus
error Failed to create the test chain
‣ MiniPoolFlashLoanLogic was specified in the predeployed contracts but was not found in the compilation artifacts

Interestingly, the library listed as problematic (here MiniPoolFlashLoanLogic) changes with each rerun of the command.

If there are no errors on my end, and the Echidna and Medusa config files are equivalent, then there must be a problem with how Medusa handles libraries.

@elopez
Copy link
Member

elopez commented Jan 6, 2025

Hi @beirao! can you confirm target (../../../contracts) is set correctly? is that where your foundry.toml file lives? In general it would match the folder you pass to echidna when launching it (e.g. echidna FOLDER --config echidna.yml)

@beirao
Copy link
Author

beirao commented Jan 6, 2025

Here is the working Echidna command:

echidna tests/echidna/PropertiesMain.sol --contract PropertiesMain --config tests/echidna/config/config1_fast.yaml

So I changed the medusa config file to this:

{
	"fuzzing": {
	  "workers": 10,
	  "workerResetLimit": 50,
	  "timeout": 0,
	  "testLimit": 0,
	  "shrinkLimit": 5000,
	  "callSequenceLength": 100,
	  "corpusDirectory": "",
	  "coverageEnabled": true,
	  "targetContracts": ["PropertiesMain"],
	  "predeployedContracts": {
		  "BorrowLogic": "0xf01",
		  "DepositLogic": "0xf03",
		  "FlashLoanLogic": "0xf11",
		  "GenericLogic": "0xf12", 
		  "LiquidationLogic": "0xf13",

		  "MiniPoolBorrowLogic": "0xa01",
		  "MiniPoolDepositLogic": "0xa03",
		  "MiniPoolFlashLoanLogic": "0xa11",
		  "MiniPoolGenericLogic": "0xa12",
		  "MiniPoolLiquidationLogic": "0xa13",
		  "MiniPoolReserveLogic": "0xa15",
		  "MiniPoolValidationLogic": "0xa16",
		  "MiniPoolWithdrawLogic": "0xa17"
	  },
	  "targetContractsBalances": [],
	  "constructorArgs": {},
	  "deployerAddress": "0x30000",
	  "senderAddresses": ["0x10000", "0x20000", "0x30000"],
	  "blockNumberDelayMax": 60480,
	  "blockTimestampDelayMax": 604800,
	  "blockGasLimit": 125000000,
	  "transactionGasLimit": 12500000,
	  "testing": {
		"stopOnFailedTest": true,
		"stopOnFailedContractMatching": false,
		"stopOnNoTests": true,
		"testAllContracts": false,
		"traceAll": false,
		"assertionTesting": {
		  "enabled": true,
		  "testViewMethods": false,
		  "panicCodeConfig": {
			"failOnCompilerInsertedPanic": false,
			"failOnAssertion": true,
			"failOnArithmeticUnderflow": false,
			"failOnDivideByZero": false,
			"failOnEnumTypeConversionOutOfBounds": false,
			"failOnIncorrectStorageAccess": false,
			"failOnPopEmptyArray": false,
			"failOnOutOfBoundsArrayAccess": false,
			"failOnAllocateTooMuchMemory": false,
			"failOnCallUninitializedVariable": false
		  }
		},
		"propertyTesting": {
		  "enabled": true,
		  "testPrefixes": ["property_"]
		},
		"optimizationTesting": {
		  "enabled": true,
		  "testPrefixes": ["optimize_"]
		},
		"targetFunctionSignatures": [],
		"excludeFunctionSignatures": []
	  },
	  "chainConfig": {
		"codeSizeCheckDisabled": true,
		"cheatCodes": {
		  "cheatCodesEnabled": true,
		  "enableFFI": false
		},
		"skipAccountChecks": true
	  }
	},
	"compilation": {
	  "platform": "crytic-compile",
	  "platformConfig": {
		"target": "tests/echidna/",
		"solcVersion": "",
		"exportDirectory": "",
		"args": [
			"--foundry-compile-all",
			"--compile-libraries=(BorrowLogic,0xf01),(DepositLogic,0xf03),(FlashLoanLogic,0xf11),(GenericLogic,0xf12),(LiquidationLogic,0xf13),(MiniPoolBorrowLogic,0xa01),(MiniPoolDepositLogic,0xa03),(MiniPoolFlashLoanLogic,0xa11),(MiniPoolGenericLogic,0xa12),(MiniPoolLiquidationLogic,0xa13),(MiniPoolReserveLogic,0xa15),(MiniPoolValidationLogic,0xa16),(MiniPoolWithdrawLogic,0xa17)"
			]	  
		}
	},
	"logging": {
	  "level": "info",
	  "logDirectory": "",
	  "noColor": false
	}
  }

I added PropertiesMain in 'targetContracts' and changed 'target'.

And here is the new output:

⇾ Finished compiling targets in 47s
⇾ Initializing corpus
⇾ Setting up test chain
error Failed to initialize the test chain
‣ deploying PropertiesMain returned a failed status: execution reverted

This error is strange since Echidna succeeds in deploying PropertiesMain.

Here's the file tree structure:

📁 Root
│
├── 📄 medusa_config2.json
├── 📄 foundry.toml
│
├── 📁 contracts
│   └── (all contracts)
│
└── 📁 tests
    ├── 📁 echidna
    │   ├── 📄 PropertiesMain.sol
    │
    └── 📁 foundry
        └── (all foundry tests)

The command I use from the root is:

medusa fuzz --config medusa_config2.json

It's probably not a bug but just me messing up the config file.

@elopez
Copy link
Member

elopez commented Jan 6, 2025

it sounds like target should probably be tests/echidna/PropertiesMain.sol (matching echidna) or more likely . (your whole project, seeing that you're using --foundry-compile-all as well)

@beirao
Copy link
Author

beirao commented Jan 7, 2025

I tried target set to "tests/echidna/PropertiesMain.sol", "tests/echidna/", "." or just "". The outcome is always the same.

⇾ Finished compiling targets in 47s
⇾ Initializing corpus
⇾ Setting up test chain
error Failed to initialize the test chain
‣ deploying PropertiesMain returned a failed status: execution reverted

The fact that it reverts without giving the reason makes it hard to debug. I don't know what else I can provide to help find the bug?
It works perfectly with Echidna.

@anishnaik
Copy link
Collaborator

Hey @beirao which version of medusa are you using? We added execution tracing for contract deployments to aid in debugging but it seems like it is not being attached. This can mean two things: (1) the version is outdated or (2) we cannot capture the execution trace (more likely). It would also be great if I could access to the repo so that I can run medusa on the codebase to see what is going wrong.

@beirao
Copy link
Author

beirao commented Jan 10, 2025

Hey @anishnaik,
I use medusa version 0.1.8.

I can give you the access. Should I give access to your account directly? (https://github.com/anishnaik)

@anishnaik
Copy link
Collaborator

Yes, that would be great :)

@beirao
Copy link
Author

beirao commented Jan 10, 2025

Ok you should have access now. Here is what you should run:

git clone https://github.com/Cod3x-Labs/Cod3x-Lend
cd Cod3x-Lend
git checkout mitigation
forge install
echidna tests/echidna/PropertiesMain.sol --contract PropertiesMain --config tests/echidna/config/config1_fast.yaml
medusa fuzz --config medusa_config.json

@anishnaik
Copy link
Collaborator

anishnaik commented Jan 14, 2025

Hey @beirao good news! I was able to figure out the bug.

First, definitely set the compilation target to .. This ensures that everything is compiled. If it is set to tests/echidna, it will only compile stuff in that folder and thus it won't be able to find compiled contract definitions outside of that scope.

Second, the issue was an out-of-gas issue (see below):
Screenshot 2025-01-14 at 3 20 17 PM

Thus, what you can do is set the transactionGasLimit to 25_000_000 and the blockGasLimit to 250_000_000. This worked for me.

Thanks to you I was able to find a bug in our execution tracing of deployments, so appreciate you opening the issue :) Please let me know if the above fix works for you.

@anishnaik
Copy link
Collaborator

Closed by #538

@beirao
Copy link
Author

beirao commented Jan 17, 2025

Perfect! Thanks @anishnaik it works perfectly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
@elopez @anishnaik @beirao and others