crytic / echidna

Ethereum smart contract fuzzer
https://secure-contracts.com/program-analysis/echidna/index.html
GNU Affero General Public License v3.0
2.72k stars 362 forks source link

[Bug-Candidate]: #1236

Closed JacobYiu closed 5 months ago

JacobYiu commented 5 months ago

Describe the issue:

Hi, I have recently tried using echidna. When I ran echidna on some of my contracts, it was working perfectly, but it did not seem to run for my reentrancy smart contract. This is my code which I obtained from SWC. It gives me this [2024-04-12 14:28:59.08] Compiling reentrancy.sol... Done! (0.225115472s) Multiple contracts found, only analyzing the first Analyzing contract: /home/jacobyiu/ESBMC_Project/contracts/echidna/vuln/reentrancy.sol:Bank echidna: No tests found in ABI. If you are using assert(), use --test-mode assertion

Code example to reproduce the issue:

` pragma solidity ^0.5.0;

contract ModifierEntrancy { mapping (address => uint) public tokenBalance; Bank public bank; bool private locked = false;

constructor() public {
    bank = new Bank(); // Set up the external contract
}

modifier nonReentrant() {
    require(!locked, "Reentrant call detected!");
    locked = true;
    _;
    locked = false;
}

modifier supportsToken() {
    require(keccak256(abi.encodePacked("Nu Token")) == bank.supportsToken(), "Token not supported");
    _;
}

function airDrop() public nonReentrant supportsToken {
    require(tokenBalance[msg.sender] == 0, "Already has tokens");
    tokenBalance[msg.sender] += 20; // Simulate airdropping tokens
}

// Invariant to ensure that the locked variable is always false when not in use
function echidna_reentrancy_invariant() public view returns (bool) {
    return !locked;
}

}

contract Bank { // Dummy function to emulate external call response function supportsToken() external pure returns(bytes32) { return keccak256(abi.encodePacked("Nu Token")); } } `

Version:

echidna 2.2.3 slither 0.10.1

Relevant log output:

No response

ggrieco-tob commented 5 months ago

Hello!

You need to specify the correct contract name which has the properties. Use the --contract command line option.

JacobYiu commented 5 months ago

Oh thank you very much! I did not realise I had to place contract inside because echidna had automatically detected right contract where the invariant was placed.

JacobYiu commented 5 months ago

Hi, I may be an idiot, but I was wondering how you would deploy multiple contracts. If I have 2 contracts main and dummy, where the test invariant is placed in main, how would I deploy both of them where they both contain some eth? I have managed to deploy both, where main contains an initial balance, but I am unable to figure out how to have an initial balance for dummy. I have read through the configuration file and have been struggling over an hour to do so.

// contract: "timeStamp" deployer: "0x555555" balanceContract: 100 deployContracts: [["0x30005", "User"]] sender: ["0x30005", "0x200005"] balanceAddr: 0x30000 testMode: property testLimit: 500000

Also would echidna happen to have a discord server? I have some question about echidna because I am writing about it on my dissertation and I would not want to spam the github server.

elopez commented 5 months ago

Hi @JacobYiu! We have a Slack workspace you can join, the link is in the readme: https://github.com/crytic/echidna?tab=readme-ov-file#getting-help

You can fund your main contract with enough eth using balanceContract, and then the constructor function of your main contract can transfer eth to other addresses / contracts to distribute the funds, or deploy extra contracts you may need.

JacobYiu commented 5 months ago

Thank you very much for the reply! I will continue this issue on the slack forum.