diff --git a/.github/scripts/install-libsecp256k1.sh b/.github/scripts/install-libsecp256k1.sh index a89a51464..df39c81ef 100755 --- a/.github/scripts/install-libsecp256k1.sh +++ b/.github/scripts/install-libsecp256k1.sh @@ -9,11 +9,11 @@ if [ -f $HOME/.local/lib/libsecp256k1.a ]; then exit 0 fi -gitRef="21ffe4b22a9683cf24ae0763359e401d1284cc7a" -curl -LO "https://github.com/bitcoin-core/secp256k1/archive/$gitRef.zip" +INSTALL_VERSION=0.5.0 +curl -LO "https://github.com/bitcoin-core/secp256k1/archive/v$INSTALL_VERSION.zip" -unzip "$gitRef.zip" -cd "secp256k1-$gitRef" +unzip "v$INSTALL_VERSION.zip" && rm "v$INSTALL_VERSION.zip" +cd "secp256k1-$INSTALL_VERSION" ./autogen.sh # hevm needs reecovery module diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 138b53cd9..e541b3260 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,6 @@ jobs: if: runner.os == 'Windows' with: msystem: CLANG64 - release: false path-type: minimal update: true install: >- @@ -65,7 +64,7 @@ jobs: id: stack if: matrix.container == '' with: - ghc-version: '9.6' + ghc-version: '9.6.5' enable-stack: true stack-version: 'latest' @@ -82,16 +81,19 @@ jobs: echo "$EXTRA_LIB_WIN"; echo; echo "ghc-options:"; - echo -n ' "$locals": -Werror' - "$REPLACE_LINKER_WIN" && echo ' -pgml=C:/msys64/clang64/bin/clang.exe -pgml-supports-no-pie' || echo; + echo ' "$locals": -Werror' + "$REPLACE_LINKER_WIN" && echo ' "$everything": -pgml=D:/a/_temp/msys64/clang64/bin/clang.exe -pgml-supports-no-pie'; echo; "$SKIP_MSYS" && echo "skip-msys: true" || true + echo "system-ghc: true"; + echo "install-ghc: false"; + echo "skip-ghc-check: true"; } >> "$STACK_ROOT/config.yaml" cat "$STACK_ROOT/config.yaml" env: STACK_ROOT: ${{ steps.stack.outputs.stack-root || '/etc/stack' }} - EXTRA_INCLUDE_WIN: ${{ (runner.os == 'Windows' && '- C:/msys64/clang64/include') || '' }} - EXTRA_LIB_WIN: ${{ (runner.os == 'Windows' && '- C:/msys64/clang64/lib') || '' }} + EXTRA_INCLUDE_WIN: ${{ (runner.os == 'Windows' && '- D:/a/_temp/msys64/clang64/include') || '' }} + EXTRA_LIB_WIN: ${{ (runner.os == 'Windows' && '- D:/a/_temp/msys64/clang64/lib') || '' }} REPLACE_LINKER_WIN: ${{ (runner.os == 'Windows' && 'true') || 'false' }} SKIP_MSYS: ${{ (runner.os == 'Windows' && 'true') || 'false' }} @@ -113,9 +115,13 @@ jobs: with: path: | ~/.local - C:\msys64\home\runneradmin\.local + D:\a\_temp\msys64\home\runneradmin\.local key: ${{ runner.os }}-local-${{ env.CACHE_VERSION }}-${{ hashFiles('.github/scripts/install-*') }} + - name: Configure static build flags + run: | + printf "\nflags:\n hevm:\n static-secp256k1: true\n echidna:\n static: true\n" >> stack.yaml + - name: Cache Stack & Cabal uses: actions/cache@v4 with: @@ -143,7 +149,7 @@ jobs: - name: Build and install echidna run: | export PATH="$HASKELL_PATHS:$PATH" - stack install --flag echidna:static --ghc-options="-Werror" + stack install --ghc-options="-Werror" - name: Amend and compress binaries (macOS) if: runner.os == 'macOS' @@ -167,7 +173,7 @@ jobs: if: runner.os != 'macOS' run: | export PATH="$HASKELL_PATHS:$PATH" - stack build --flag echidna:static --test --no-run-tests --ghc-options="-Werror" + stack build --test --no-run-tests --ghc-options="-Werror" cp "$(find "$PWD" -name 'echidna-testsuite*' -type f)" . - name: Upload testsuite diff --git a/flake.lock b/flake.lock index fc545ab1e..a44f65c89 100644 --- a/flake.lock +++ b/flake.lock @@ -21,11 +21,29 @@ "systems": "systems" }, "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { @@ -52,11 +70,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1720368505, - "narHash": "sha256-5r0pInVo5d6Enti0YwUSQK4TebITypB42bWy5su3MrQ=", + "lastModified": 1726436956, + "narHash": "sha256-a3rP7uafX/qBFX0y4CGS8vvTPvxsLl9eZQ85DkIn3DI=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "ab82a9612aa45284d4adf69ee81871a389669a9e", + "rev": "039b72d0c738c934e2e36d7fc5520d1b425287a6", "type": "github" }, "original": { @@ -71,7 +89,42 @@ "flake-compat": "flake-compat", "flake-utils": "flake-utils", "nix-bundle-exe": "nix-bundle-exe", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "solc-pkgs": "solc-pkgs" + } + }, + "solc-macos-amd64-list-json": { + "flake": false, + "locked": { + "narHash": "sha256-Prwz95BgMHcWd72VwVbcH17LsV9f24K2QMcUiWUQZzI=", + "type": "file", + "url": "https://github.com/ethereum/solc-bin/raw/f743ca7/macosx-amd64/list.json" + }, + "original": { + "type": "file", + "url": "https://github.com/ethereum/solc-bin/raw/f743ca7/macosx-amd64/list.json" + } + }, + "solc-pkgs": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": [ + "nixpkgs" + ], + "solc-macos-amd64-list-json": "solc-macos-amd64-list-json" + }, + "locked": { + "lastModified": 1724145339, + "narHash": "sha256-z8pLkpdsAA0At1ofQd6KNmrxpBuUT9OKTlCDqJDW1GI=", + "owner": "hellwolf", + "repo": "solc.nix", + "rev": "9630767051bfefd552c6858c5df141368338b077", + "type": "github" + }, + "original": { + "owner": "hellwolf", + "repo": "solc.nix", + "type": "github" } }, "systems": { @@ -88,6 +141,21 @@ "repo": "default", "type": "github" } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 0e4157443..b98ea6c85 100644 --- a/flake.nix +++ b/flake.nix @@ -10,36 +10,25 @@ url = "github:3noch/nix-bundle-exe"; flake = false; }; + solc-pkgs = { + url = "github:hellwolf/solc.nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; - outputs = { self, nixpkgs, flake-utils, nix-bundle-exe, ... }: + outputs = { self, nixpkgs, flake-utils, nix-bundle-exe, solc-pkgs, ... }: flake-utils.lib.eachDefaultSystem (system: let - pkgs = nixpkgs.legacyPackages.${system}; + pkgs = import nixpkgs { + inherit system; + overlays = [solc-pkgs.overlay]; + }; + # prefer musl on Linux, static glibc + threading does not work properly # TODO: maybe only override it for echidna-redistributable? pkgsStatic = if pkgs.stdenv.hostPlatform.isLinux then pkgs.pkgsStatic else pkgs; # this is not perfect for development as it hardcodes solc to 0.5.7, test suite runs fine though - # would be great to integrate solc-select to be more flexible, improve this in future - solc = pkgs.stdenv.mkDerivation { - name = "solc"; - src = if pkgs.stdenv.isDarwin then - pkgs.fetchurl { - url = "https://binaries.soliditylang.org/macosx-amd64/solc-macosx-amd64-v0.5.7+commit.6da8b019"; - sha256 = "095mlw5x9lpdcdl9jzlvkvw46ag03xr4nj4vly4hgn92rgivimm7"; - } - else - pkgs.fetchurl { - url = "https://binaries.soliditylang.org/linux-amd64/solc-linux-amd64-v0.5.7+commit.6da8b019"; - sha256 = "0dsvzck5jh8rvdxs7zyn2ga9hif024msx8gr8ifgj4cmyb7m4341"; - }; - phases = ["installPhase" "patchPhase"]; - installPhase = '' - mkdir -p $out/bin - cp $src $out/bin/solc - chmod +x $out/bin/solc - ''; - }; + solc = solc-pkgs.mkDefault pkgs pkgs.solc_0_5_7; secp256k1-static = pkgsStatic.secp256k1.overrideAttrs (attrs: { configureFlags = attrs.configureFlags ++ [ "--enable-static" ]; @@ -54,28 +43,19 @@ if (with ps.stdenv; hostPlatform.isDarwin && hostPlatform.isx86) then ps.haskell.lib.compose.overrideCabal (_ : { extraLibraries = [ps.libiconv]; }) hprev.with-utf8 else hprev.with-utf8; + # TODO: temporary fix for static build which is still on 9.4 + witch = ps.haskell.lib.doJailbreak hprev.witch; }; }; - cc-workaround-nix-23138 = - pkgs.writeScriptBin "cc-workaround-nix-23138" '' - if [ "$1" = "--print-file-name" ] && [ "$2" = "c++" ]; then - echo c++ - else - exec cc "$@" - fi - ''; - hevm = pkgs: pkgs.lib.pipe ((hsPkgs pkgs).callCabal2nix "hevm" (pkgs.fetchFromGitHub { - owner = "trail-of-forks"; - repo = "hevm"; - rev = "3aba82f06a2d1e0a4a4c26458f747a46dad0e7e2"; - sha256 = "sha256-NXXhEqHTQEL2N9RhXa1eczIsQtIM3mvPfyWXlBXpxK4="; + owner = "ethereum"; + repo = "hevm"; + rev = "c779777d18c8ff60867f009d434b44ce08188e01"; + sha256 = "sha256-JnJUZ9AxhxTP+TBMThksh0D4R6KFdzjgu1+fBeBERws="; }) { secp256k1 = pkgs.secp256k1; }) ([ pkgs.haskell.lib.compose.dontCheck - ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ - (pkgs.haskell.lib.compose.appendConfigureFlag "--ghc-options=-pgml=${cc-workaround-nix-23138}/bin/cc-workaround-nix-23138") ]); echidna = pkgs: with pkgs; lib.pipe @@ -86,8 +66,6 @@ haskell.lib.compose.dontCheck (haskell.lib.compose.addTestToolDepends [ haskellPackages.hpack slither-analyzer solc ]) (haskell.lib.compose.disableCabalFlag "static") - ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ - (pkgs.haskell.lib.compose.appendConfigureFlag "--ghc-options=-pgml=${cc-workaround-nix-23138}/bin/cc-workaround-nix-23138") ]); echidna-static = with pkgsStatic; lib.pipe @@ -173,9 +151,7 @@ packages = _: [ (echidna pkgs) ]; shellHook = '' hpack - '' + (if pkgs.stdenv.isDarwin then '' - cabal configure --ghc-options=-pgml=${cc-workaround-nix-23138}/bin/cc-workaround-nix-23138 - '' else ""); + ''; buildInputs = [ solc slither-analyzer diff --git a/lib/Echidna/Solidity.hs b/lib/Echidna/Solidity.hs index 990309ee5..e04417070 100644 --- a/lib/Echidna/Solidity.hs +++ b/lib/Echidna/Solidity.hs @@ -30,6 +30,7 @@ import System.Info (os) import EVM (initialContract, currentContract) import EVM.ABI +import EVM.Effects (runApp) import EVM.Solidity import EVM.Types hiding (Env) @@ -59,7 +60,7 @@ readSolcBatch d = do mapM parseOne fs where parseOne f = - readSolc CombinedJSON "" (d f) >>= \case + runApp $ readSolc CombinedJSON "" (d f) >>= \case Right buildOutput -> pure buildOutput Left e -> error $ "Failed to parse combined JSON file " <> (d f) <> "\n" <> e diff --git a/src/test/Tests/Integration.hs b/src/test/Tests/Integration.hs index 6abc27f79..4152363ae 100644 --- a/src/test/Tests/Integration.hs +++ b/src/test/Tests/Integration.hs @@ -92,7 +92,7 @@ integrationTests = testGroup "Solidity Integration Testing" ] , testContract "basic/gaslimit.sol" Nothing [ ("echidna_gaslimit passed", passed "echidna_gaslimit") ] - , testContractV "basic/killed.sol" (Just (< solcV (0,8,0))) Nothing + , testContractV "basic/killed.sol" (Just (< solcV (0,8,0))) (Just "basic/killed.yaml") [ ("echidna_still_alive failed", solved "echidna_still_alive") ] , checkConstructorConditions "basic/codesize.sol" "invalid codesize" diff --git a/stack.yaml b/stack.yaml index 12aa54f57..15fa8406f 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,11 +1,11 @@ -resolver: lts-22.19 +resolver: lts-22.34 packages: - '.' extra-deps: -- git: https://github.com/trail-of-forks/hevm.git - commit: 3aba82f06a2d1e0a4a4c26458f747a46dad0e7e2 +- git: https://github.com/ethereum/hevm.git + commit: c779777d18c8ff60867f009d434b44ce08188e01 - smt2-parser-0.1.0.1@sha256:1e1a4565915ed851c13d1e6b8bb5185cf5d454da3b43170825d53e221f753d77,1421 - spawn-0.3@sha256:b91e01d8f2b076841410ae284b32046f91471943dc799c1af77d666c72101f02,1162 diff --git a/tests/solidity/basic/killed.sol b/tests/solidity/basic/killed.sol index 8f21d8a32..90983a9a9 100644 --- a/tests/solidity/basic/killed.sol +++ b/tests/solidity/basic/killed.sol @@ -1,4 +1,5 @@ contract C { + constructor() public payable {} uint private state = 0; function f(uint x) public { @@ -11,7 +12,7 @@ contract C { } function echidna_still_alive() public returns (bool) { - return true; + return address(this).balance > 0; } function echidna_revert_still_alive() public returns (bool) { diff --git a/tests/solidity/basic/killed.yaml b/tests/solidity/basic/killed.yaml new file mode 100644 index 000000000..2bac55777 --- /dev/null +++ b/tests/solidity/basic/killed.yaml @@ -0,0 +1 @@ +balanceContract: 100