Skip to content

Commit 253e159

Browse files
authored
Native M1 development support and releases with Nix (#700)
1 parent f1b0a8f commit 253e159

File tree

5 files changed

+65
-24
lines changed

5 files changed

+65
-24
lines changed

.github/workflows/nix.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
- ubuntu-latest
1919
- macos-latest
2020
steps:
21-
- uses: actions/checkout@v2.3.4
21+
- uses: actions/checkout@v2.4.0
2222
- uses: cachix/install-nix-action@v16
2323
with:
2424
nix_path: nixpkgs=channel:nixos-unstable

README.md

+17-8
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Our tool signals each execution trace in the corpus with the following "line mar
7373
- `*` if an execution ended with a STOP
7474
- `r` if an execution ended with a REVERT
7575
- `o` if an execution ended with an out-of-gas error
76-
- `e` if an execution ended with any other error (zero division, assertion failure, etc)
76+
- `e` if an execution ended with any other error (zero division, assertion failure, etc)
7777

7878
### Support for smart contract build systems
7979

@@ -171,16 +171,16 @@ checking for these would be a good place to start.
171171

172172
Our [Building Secure Smart Contracts](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna#echidna-tutorial) repository contains a crash course on Echidna, including examples, lessons and exercises.
173173

174-
### Limitations and known issues
174+
## Limitations and known issues
175175

176176
EVM emulation and testing is hard. Echidna has a number of limitations in the latest release. Some of these are inherited from [hevm](https://github.com/dapphub/dapptools/tree/master/src/hevm) while some are results from design/performance decisions or simply bugs in our code. We list them here including their corresponding issue and the status ("wont fix", "in review", "fixed"). Issues that are "fixed" are expected to be included in the next Echidna release.
177177

178-
| Description | Issue | Status |
178+
| Description | Issue | Status |
179179
| :--- | :---: | :---: |
180180
| Debug information can be insufficient | [#656](https://github.com/crytic/echidna/issues/656) | *[in review for 2.0](https://github.com/crytic/echidna/pull/674)* |
181181
| Vyper support is limited | [#652](https://github.com/crytic/echidna/issues/652) | *wont fix* |
182182
| Limited library support for testing | [#651](https://github.com/crytic/echidna/issues/651) | *wont fix* |
183-
| If the contract is not properly linked, Echidna will crash | [#514](https://github.com/crytic/echidna/issues/514) | *in review* |
183+
| If the contract is not properly linked, Echidna will crash | [#514](https://github.com/crytic/echidna/issues/514) | *in review* |
184184
| Assertions are not detected in internal transactions | [#601](https://github.com/crytic/echidna/issues/601) | *[in review for 2.0](https://github.com/crytic/echidna/pull/674)* |
185185
| Assertions are not detected in solc 0.8.x | [#669](https://github.com/crytic/echidna/issues/669) | *[in review for 2.0](https://github.com/crytic/echidna/pull/674)* |
186186
| Value generation can fail in multi-abi mode, since the function hash is not precise enough | [#579](https://github.com/crytic/echidna/issues/579) | *[in review for 2.0](https://github.com/crytic/echidna/pull/674)*|
@@ -215,13 +215,22 @@ Some Linux distributions do not ship static libraries for certain things that Ha
215215

216216
If you're getting errors building related to linking, try tinkering with `--extra-include-dirs` and `--extra-lib-dirs`.
217217

218-
### Building using Nix
218+
### Building using Nix (works natively on Apple M1 systems)
219219

220-
Nix users can install the lastest Echidna with:
220+
[Nix users](https://nixos.org/download.html) can install the lastest Echidna with:
221221
```
222222
$ nix-env -i -f https://github.com/crytic/echidna/tarball/master
223223
```
224224

225+
To build a standalone release for non-Nix macOS systems, the following will
226+
bundle Echidna and all linked dylibs in a tarball:
227+
228+
```
229+
$ nix-build macos-release.nix
230+
$ ll result/
231+
bin echidna-1.7.3-aarch64-darwin.tar.gz
232+
```
233+
225234
It is possible to develop Echidna with Cabal inside `nix-shell`. Nix will automatically
226235
install all the dependencies required for development including `crytic-compile` and `solc`.
227236
A quick way to get GHCi with Echidna ready for work:
@@ -253,7 +262,7 @@ This is a partial list of smart contracts projects that use Echidna for testing:
253262
* [Aragon Staking](https://github.com/aragon/staking/blob/82bf54a3e11ec4e50d470d66048a2dd3154f940b/packages/protocol/contracts/test/lib/EchidnaStaking.sol)
254263
* [Centre Token](https://github.com/centrehq/centre-tokens/tree/master/echidna_tests)
255264
* [Tokencard](https://github.com/tokencard/contracts/tree/master/tools/echidna)
256-
* [Minimalist USD Stablecoin](https://github.com/usmfum/USM/pull/41)
265+
* [Minimalist USD Stablecoin](https://github.com/usmfum/USM/pull/41)
257266

258267
### Trophies
259268

@@ -280,7 +289,7 @@ The following security vulnerabilities were found by Echidna. If you found a sec
280289

281290
We can also use Echidna to reproduce research examples from smart contract fuzzing papers to show how quickly it can find the solution. All these can be solved, from a few seconds to one or two minutes on a laptop computer.
282291

283-
| Source | Code
292+
| Source | Code
284293
|--|--
285294
[Using automatic analysis tools with MakerDAO contracts](https://forum.openzeppelin.com/t/using-automatic-analysis-tools-with-makerdao-contracts/1021) | [SimpleDSChief](https://github.com/crytic/echidna/blob/master/examples/solidity/research/vera_dschief.sol)
286295
[Integer precision bug in Sigma Prime](https://github.com/b-mueller/sabre#example-2-integer-precision-bug) | [VerifyFunWithNumbers](https://github.com/crytic/echidna/blob/master/examples/solidity/research/solcfuzz_funwithnumbers.sol)

default.nix

+9-15
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
{ pkgs ? import (builtins.fetchTarball {
2-
name = "nixpkgs-unstable-2021-10-15";
3-
url = "https://github.com/nixos/nixpkgs/archive/ee084c02040e864eeeb4cf4f8538d92f7c675671.tar.gz";
4-
sha256 = "sha256:1x8amcixdaw3ryyia32pb706vzhvn5whq9n8jin0qcha5qnm1fnh";
5-
}) {},
1+
{ pkgs ? import nix/pkgs.nix,
62
profiling ? false,
73
tests ? true
84
}:
9-
105
let
116
# this is not perfect for development as it hardcodes solc to 0.5.7, test suite runs fine though
127
# would be great to integrate solc-select to be more flexible, improve this in future
@@ -30,11 +25,9 @@ let
3025
'';
3126
};
3227

33-
slither-analyzer = pkgs.slither-analyzer.override { withSolc = false; };
34-
35-
v = "1.7.2";
28+
v = "1.7.3";
3629

37-
testInputs = [ slither-analyzer solc ];
30+
testInputs = [ pkgs.slither-analyzer solc ];
3831

3932
f = { mkDerivation, aeson, ansi-terminal, base, base16-bytestring, binary
4033
, brick, bytestring, cborg, containers, data-dword, data-has, deepseq
@@ -53,17 +46,16 @@ let
5346
libraryHaskellDepends = [
5447
aeson ansi-terminal base base16-bytestring binary brick bytestring
5548
cborg containers data-dword data-has deepseq directory exceptions
56-
filepath hashable hevm lens lens-aeson megaparsec MonadRandom mtl
57-
optparse-applicative process random stm temporary text transformers
58-
unix unliftio unliftio-core unordered-containers vector
49+
filepath hashable hevm lens lens-aeson ListLike megaparsec MonadRandom
50+
mtl optparse-applicative process random semver stm temporary text
51+
transformers unix unliftio unliftio-core unordered-containers vector
5952
vector-instances vty wl-pprint-annotated word8 yaml extra ListLike
60-
semver
6153
] ++ (if pkgs.lib.inNixShell then testHaskellDepends else []);
6254
executableHaskellDepends = libraryHaskellDepends;
6355
testHaskellDepends = [ tasty tasty-hunit tasty-quickcheck ];
64-
libraryToolDepends = [ hpack ];
6556
testToolDepends = testInputs;
6657
configureFlags = if profiling then [ "--enable-profiling" "--enable-library-profiling" ] else [];
58+
libraryToolDepends = [ hpack pkgs.slither-analyzer solc ];
6759
preConfigure = ''
6860
hpack
6961
# re-enable dynamic build for Linux
@@ -81,6 +73,8 @@ let
8173
buildInputs = with pkgs.haskellPackages; [
8274
hlint
8375
cabal-install
76+
] ++ pkgs.lib.optional (!pkgs.stdenv.isAarch64) [
77+
# this doesn't work due to ormolu not building
8478
haskell-language-server
8579
];
8680
nativeBuildInputs = if tests then [] else testInputs;

macos-release.nix

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{ tests ? false }:
2+
let
3+
pkgs = import nix/pkgs.nix;
4+
echidna = import ./. { inherit tests; };
5+
in
6+
with pkgs; runCommand "echidna-${echidna.version}-bundled-dylibs" {
7+
buildInputs = [
8+
macdylibbundler
9+
darwin.sigtool
10+
darwin.cctools
11+
];
12+
} ''
13+
mkdir -p $out/bin
14+
cp ${echidna}/bin/echidna-test $out/bin/echidna-test
15+
chmod 755 $out/bin/echidna-test
16+
dylibbundler -b \
17+
-x $out/bin/echidna-test \
18+
-d $out/bin \
19+
-p '@executable_path'
20+
21+
# Manually fix iconv dylib ignored by dylibbundler
22+
cp ${pkgs.libiconv.outPath}/lib/libiconv-nocharset.dylib $out/bin/
23+
cp ${pkgs.libiconv.outPath}/lib/libcharset.1.0.0.dylib $out/bin/libcharset.1.dylib
24+
chmod 755 $out/bin/libiconv-nocharset.dylib $out/bin/libcharset.1.dylib
25+
install_name_tool -id "@rpath/libiconv-nocharset.dylib" $out/bin/libiconv-nocharset.dylib
26+
install_name_tool -id "@rpath/libcharset.1.dylib" $out/bin/libcharset.1.dylib
27+
install_name_tool -change ${pkgs.libiconv.outPath}/lib/libiconv-nocharset.dylib "@executable_path/libiconv-nocharset.dylib" $out/bin/libiconv.dylib
28+
install_name_tool -change ${pkgs.libiconv.outPath}/lib/libcharset.1.dylib "@executable_path/libcharset.1.dylib" $out/bin/libiconv.dylib
29+
30+
# re-sign the binaries since the load paths were modified
31+
codesign -s - -f $out/bin/*
32+
tar -czvf $out/echidna-${echidna.version}-${stdenv.system}.tar.gz -C $out/bin .
33+
''

nix/pkgs.nix

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import (builtins.fetchTarball {
2+
name = "nixpkgs-unstable-2022-01-07";
3+
url = "https://github.com/nixos/nixpkgs/archive/d77bbfcbb650d9c219ca3286e1efb707b922d7c2.tar.gz";
4+
sha256 = "sha256:1wh9qr6wvnfaprws2kbm4n9wxbckzh5d33lc4xfk6ama9bhbxr92";
5+
}) { }

0 commit comments

Comments
 (0)