Skip to content

Commit

Permalink
ci: quick and dirty medusa action forking echidna-action
Browse files Browse the repository at this point in the history
  • Loading branch information
0xteddybear committed Oct 15, 2024
1 parent fe17c34 commit 92dd632
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 36 deletions.
9 changes: 9 additions & 0 deletions .github/actions/medusa-action/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM trailofbits/eth-security-toolbox:latest

COPY entrypoint.sh /entrypoint.sh
RUN foundryup
USER root
RUN cp -rT /home/ethsec/ /root
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/.local/bin:/root/.vyper/bin:/root/.foundry/bin:/root/.vyper/bin

ENTRYPOINT ["/entrypoint.sh"]
49 changes: 49 additions & 0 deletions .github/actions/medusa-action/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: "medusa-action"

description: "Run Medusa, the smart contract fuzzer"

branding:
icon: 'shield'
color: 'red'

inputs:
timeout:
description: "Time to run the campaign"
required: false
output-file:
description: "Capture medusa's output into this file. The path must be relative to the repository root."
required: false
negate-exit-status:
description: "Apply logical NOT to medusa-test's exit status (for testing the action)"
required: false
medusa-workdir:
description: "Path to run medusa-test from."
required: false
internal-github-workspace:
# Do not set manually. This is a hacky way to pass the host workspace to inside the action
# This is used to improve compatibility when using ignore-compile.
# GitHub rewrites the argument if it is passed directly, to we use toJSON to "transform"
# it and avoid the remapping done by GitHub Actions.
default: ${{ toJSON(github.workspace) }}

outputs:
output-file:
description: "If produced, the file containing medusa-test's output, relative to the repository root."
value: ${{ steps.medusa.outputs.output-file }}

runs:
using: "composite"
steps:
- run: |
docker build -t eth-security-toolbox:latest ${{ github.action_path }}
shell: bash
- id: medusa
run: |
# medusa campaign
${{ github.action_path }}/launch.sh eth-security-toolbox:latest
shell: bash
env:
INPUT_NEGATE-EXIT-STATUS: ${{ inputs.negate-exit-status }}
INPUT_MEDUSA-WORKDIR: ${{ inputs.medusa-workdir }}
INPUT_OUTPUT-FILE: ${{ inputs.output-file }}
INPUT_INTERNAL-GITHUB-WORKSPACE: ${{ inputs.internal-github-workspace }}
67 changes: 67 additions & 0 deletions .github/actions/medusa-action/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#! /bin/bash

set -eu

OPTIONS="contract config format corpus-dir test-limit test-mode shrink-limit \
seq-len contract-addr deployer sender seed crytic-args solc-args"

SWITCHES="multi-abi"

# smoelius: `get` works for non-standard variable names like `INPUT_CORPUS-DIR`.
get() {
env | sed -n "s/^$1=\(.*\)/\1/;T;p"
}

compatibility_link()
{
HOST_GITHUB_WORKSPACE="$(get INPUT_INTERNAL-GITHUB-WORKSPACE | tr -d \")"
if [[ -d "$GITHUB_WORKSPACE" ]]; then
mkdir -p "$(dirname "$HOST_GITHUB_WORKSPACE")"
ln -s "$GITHUB_WORKSPACE" "$HOST_GITHUB_WORKSPACE"
echo "[-] Applied compatibility link: $HOST_GITHUB_WORKSPACE -> $GITHUB_WORKSPACE"
fi
}

compatibility_link

CMD=(medusa fuzz)

for OPTION in $OPTIONS; do
NAME=INPUT_"${OPTION^^}"
VALUE="$(get "$NAME")"
if [[ -n "$VALUE" ]]; then
CMD+=(--"$OPTION" "$VALUE")
fi
done

for SWITCH in $SWITCHES; do
NAME=INPUT_"${SWITCH^^}"
VALUE="$(get "$NAME")"
if [[ -n "$VALUE" ]]; then
CMD+=(--"$SWITCH")
fi
done

echo "medusa version: $(medusa --version)" >&2
echo "medusa command line: ${CMD[@]}" >&2
echo 'PATH: ' "$PATH" >&2
echo 'foundry version: ' "$(forge --version)" >&2
echo >&2

OUTPUT_FILE="$(get 'INPUT_OUTPUT-FILE')"
if [[ -n "$OUTPUT_FILE" ]]; then
echo "::set-output name=output-file::$OUTPUT_FILE"
# tee stdout to $OUTPUT_FILE to capture medusa's output
exec > >(tee "$OUTPUT_FILE")
fi

WORKDIR="$(get 'INPUT_MEDUSA-WORKDIR')"
if [[ -n "$WORKDIR" ]]; then
cd "$WORKDIR"
fi

if [[ -n "$(get 'INPUT_NEGATE-EXIT-STATUS')" ]]; then
! "${CMD[@]}"
else
"${CMD[@]}"
fi
14 changes: 14 additions & 0 deletions .github/actions/medusa-action/launch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

IMAGE=$1
INPUTS=$(env | cut -f1 -d= | grep '^INPUT_')

CMD=(docker run --rm -v "$PWD:/github/workspace" --workdir /github/workspace -e GITHUB_WORKSPACE=/github/workspace)

for VARNAME in $INPUTS; do
CMD+=(-e "$VARNAME")
done

CMD+=("$IMAGE")

"${CMD[@]}"
29 changes: 29 additions & 0 deletions .github/workflows/medusa.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Run medusa
on:
push:
branches: [main, dev]
pull_request:
branches:
- "**"
jobs:
medusa-tests:
name: Medusa Test
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x
cache: yarn

- name: Install dependencies
run: yarn --frozen-lockfile --network-concurrency 1

- name: Run Medusa
uses: ./.github/actions/medusa-action
36 changes: 0 additions & 36 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,42 +64,6 @@ jobs:
- name: Run tests
run: yarn test:integration

echidna-tests:
name: Echidna Test
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x
cache: 'yarn'

- name: Install dependencies
run: yarn --frozen-lockfile --network-concurrency 1

- name: Compile contracts
run: |
forge build --build-info
- name: Run Echidna
uses: crytic/echidna-action@v2
with:
files: .
contract: InvariantGreeter
test-mode: assertion
crytic-args: --ignore-compile

halmos-tests:
name: Run symbolic execution tests
runs-on: ubuntu-latest
Expand Down

0 comments on commit 92dd632

Please sign in to comment.