@godzillaba/mutest 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +1 -1
  2. package/index.ts +23 -6
  3. package/package.json +4 -1
  4. package/.devcontainer/Dockerfile +0 -117
  5. package/.devcontainer/devcontainer.json +0 -62
  6. package/.devcontainer/init-firewall.sh +0 -118
  7. package/.github/workflows/test.yml +0 -38
  8. package/.gitmodules +0 -3
  9. package/CLAUDE.md +0 -39
  10. package/foundry.lock +0 -8
  11. package/foundry.toml +0 -6
  12. package/lib/forge-std/.gitattributes +0 -1
  13. package/lib/forge-std/.github/CODEOWNERS +0 -1
  14. package/lib/forge-std/.github/dependabot.yml +0 -6
  15. package/lib/forge-std/.github/workflows/ci.yml +0 -125
  16. package/lib/forge-std/.github/workflows/sync.yml +0 -36
  17. package/lib/forge-std/CONTRIBUTING.md +0 -193
  18. package/lib/forge-std/LICENSE-APACHE +0 -203
  19. package/lib/forge-std/LICENSE-MIT +0 -25
  20. package/lib/forge-std/README.md +0 -314
  21. package/lib/forge-std/RELEASE_CHECKLIST.md +0 -12
  22. package/lib/forge-std/foundry.toml +0 -18
  23. package/lib/forge-std/package.json +0 -16
  24. package/lib/forge-std/scripts/vm.py +0 -636
  25. package/lib/forge-std/src/Base.sol +0 -48
  26. package/lib/forge-std/src/Config.sol +0 -60
  27. package/lib/forge-std/src/LibVariable.sol +0 -477
  28. package/lib/forge-std/src/Script.sol +0 -28
  29. package/lib/forge-std/src/StdAssertions.sol +0 -779
  30. package/lib/forge-std/src/StdChains.sol +0 -303
  31. package/lib/forge-std/src/StdCheats.sol +0 -825
  32. package/lib/forge-std/src/StdConfig.sol +0 -632
  33. package/lib/forge-std/src/StdConstants.sol +0 -30
  34. package/lib/forge-std/src/StdError.sol +0 -15
  35. package/lib/forge-std/src/StdInvariant.sol +0 -140
  36. package/lib/forge-std/src/StdJson.sol +0 -275
  37. package/lib/forge-std/src/StdMath.sol +0 -47
  38. package/lib/forge-std/src/StdStorage.sol +0 -475
  39. package/lib/forge-std/src/StdStyle.sol +0 -333
  40. package/lib/forge-std/src/StdToml.sol +0 -275
  41. package/lib/forge-std/src/StdUtils.sol +0 -200
  42. package/lib/forge-std/src/Test.sol +0 -32
  43. package/lib/forge-std/src/Vm.sol +0 -2533
  44. package/lib/forge-std/src/console.sol +0 -1551
  45. package/lib/forge-std/src/console2.sol +0 -4
  46. package/lib/forge-std/src/interfaces/IERC1155.sol +0 -105
  47. package/lib/forge-std/src/interfaces/IERC165.sol +0 -12
  48. package/lib/forge-std/src/interfaces/IERC20.sol +0 -43
  49. package/lib/forge-std/src/interfaces/IERC4626.sol +0 -190
  50. package/lib/forge-std/src/interfaces/IERC6909.sol +0 -72
  51. package/lib/forge-std/src/interfaces/IERC721.sol +0 -164
  52. package/lib/forge-std/src/interfaces/IERC7540.sol +0 -144
  53. package/lib/forge-std/src/interfaces/IERC7575.sol +0 -241
  54. package/lib/forge-std/src/interfaces/IMulticall3.sol +0 -68
  55. package/lib/forge-std/src/safeconsole.sol +0 -13248
  56. package/lib/forge-std/test/CommonBase.t.sol +0 -44
  57. package/lib/forge-std/test/Config.t.sol +0 -381
  58. package/lib/forge-std/test/LibVariable.t.sol +0 -452
  59. package/lib/forge-std/test/StdAssertions.t.sol +0 -141
  60. package/lib/forge-std/test/StdChains.t.sol +0 -227
  61. package/lib/forge-std/test/StdCheats.t.sol +0 -638
  62. package/lib/forge-std/test/StdConstants.t.sol +0 -38
  63. package/lib/forge-std/test/StdError.t.sol +0 -119
  64. package/lib/forge-std/test/StdJson.t.sol +0 -49
  65. package/lib/forge-std/test/StdMath.t.sol +0 -202
  66. package/lib/forge-std/test/StdStorage.t.sol +0 -485
  67. package/lib/forge-std/test/StdStyle.t.sol +0 -110
  68. package/lib/forge-std/test/StdToml.t.sol +0 -49
  69. package/lib/forge-std/test/StdUtils.t.sol +0 -342
  70. package/lib/forge-std/test/Vm.t.sol +0 -18
  71. package/lib/forge-std/test/compilation/CompilationScript.sol +0 -8
  72. package/lib/forge-std/test/compilation/CompilationScriptBase.sol +0 -8
  73. package/lib/forge-std/test/compilation/CompilationTest.sol +0 -8
  74. package/lib/forge-std/test/compilation/CompilationTestBase.sol +0 -8
  75. package/lib/forge-std/test/fixtures/broadcast.log.json +0 -187
  76. package/lib/forge-std/test/fixtures/config.toml +0 -81
  77. package/lib/forge-std/test/fixtures/test.json +0 -8
  78. package/lib/forge-std/test/fixtures/test.toml +0 -6
  79. package/script/Counter.s.sol +0 -19
  80. package/src/Counter.sol +0 -14
  81. package/test/Counter.t.sol +0 -24
package/README.md CHANGED
@@ -5,7 +5,7 @@ Mutation testing for Solidity. Uses [Gambit](https://github.com/Certora/gambit)
5
5
  ## Usage
6
6
 
7
7
  ```sh
8
- npx . src/Counter.sol
8
+ npx @godzillaba/mutest src/Counter.sol
9
9
  ```
10
10
 
11
11
  Pass one or more Solidity files. Mutest will:
package/index.ts CHANGED
@@ -15,12 +15,13 @@ interface Mutant {
15
15
  async function setupWorkers(workerCount: number): Promise<string> {
16
16
  const { stdout: tempDir } = await execFile("mktemp", ["-d"]);
17
17
  const root = tempDir.trim();
18
+ const cwd = process.cwd()
18
19
 
19
20
  const workers = Array.from({ length: workerCount }, (_, i) => {
20
21
  const dir = `${root}/worker-${i}`;
21
22
  return execFile("bash", [
22
23
  "-c",
23
- `mkdir -p "${dir}" && git ls-files -z | tar -c --null -T - | tar -x -C "${dir}"`,
24
+ `mkdir -p "${dir}" && git ls-files -z | tar -c --null -T - | tar -x -C "${dir}" && ln -s ${cwd}/node_modules ${dir}/node_modules && ln -s ${cwd}/lib ${dir}/lib`,
24
25
  ]);
25
26
  });
26
27
  await Promise.all(workers);
@@ -32,11 +33,27 @@ async function runGambit(solFiles: string[]): Promise<Mutant[]> {
32
33
  const { stdout: remappingsRaw } = await execFile("forge", ["remappings"]);
33
34
  const remappings = remappingsRaw.trim().split("\n").filter(Boolean);
34
35
  const remapArgs = remappings.flatMap((r) => ["--solc_remappings", r]);
35
- for (const file of solFiles) {
36
- await execFile("gambit", ["mutate", "--filename", file, ...remapArgs]);
36
+
37
+ const results: Mutant[] = [];
38
+ const pending = [...solFiles];
39
+ const concurrency = 10;
40
+
41
+ async function worker() {
42
+ while (pending.length > 0) {
43
+ const file = pending.shift()!;
44
+ const outdir = `gambit_out/${file}`;
45
+ await execFile("gambit", [
46
+ "mutate", "--filename", file, "--outdir", outdir, ...remapArgs,
47
+ ]);
48
+ const raw = await readFile(`${outdir}/gambit_results.json`, "utf-8");
49
+ const mutants: Mutant[] = JSON.parse(raw);
50
+ for (const m of mutants) m.name = `${file}/${m.name}`;
51
+ results.push(...mutants);
52
+ }
37
53
  }
38
- const raw = await readFile("gambit_out/gambit_results.json", "utf-8");
39
- return JSON.parse(raw);
54
+
55
+ await Promise.all(Array.from({ length: concurrency }, worker));
56
+ return results;
40
57
  }
41
58
 
42
59
  async function processMutants(
@@ -56,7 +73,7 @@ async function processMutants(
56
73
  for (const mutant of queue) {
57
74
  await cp(`gambit_out/${mutant.name}`, `${workerDir}/${mutant.original}`);
58
75
  try {
59
- await execFile("forge", ["test", "--root", workerDir]);
76
+ await execFile("forge", ["test", "--optimize", "false", "--root", workerDir]);
60
77
  survived++;
61
78
  console.log(
62
79
  `[SURVIVED] #${mutant.id} ${mutant.description} ${mutant.original}`,
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "@godzillaba/mutest",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "bin": {
5
5
  "mutest": "./index.ts"
6
6
  },
7
+ "files": [
8
+ "index.ts"
9
+ ],
7
10
  "dependencies": {
8
11
  "tsx": "^4.21.0"
9
12
  }
@@ -1,117 +0,0 @@
1
- FROM node:20
2
-
3
- ARG TZ
4
- ENV TZ="$TZ"
5
-
6
- ARG CLAUDE_CODE_VERSION=latest
7
-
8
- # Install basic development tools and iptables/ipset
9
- RUN apt-get update && apt-get install -y --no-install-recommends \
10
- less \
11
- git \
12
- procps \
13
- sudo \
14
- fzf \
15
- zsh \
16
- man-db \
17
- unzip \
18
- gnupg2 \
19
- gh \
20
- iptables \
21
- ipset \
22
- iproute2 \
23
- dnsutils \
24
- aggregate \
25
- jq \
26
- nano \
27
- vim \
28
- && apt-get clean && rm -rf /var/lib/apt/lists/*
29
-
30
- # Install Go
31
- ARG GO_VERSION=1.23.6
32
- RUN ARCH=$(dpkg --print-architecture) && \
33
- wget -q "https://go.dev/dl/go${GO_VERSION}.linux-${ARCH}.tar.gz" && \
34
- tar -C /usr/local -xzf "go${GO_VERSION}.linux-${ARCH}.tar.gz" && \
35
- rm "go${GO_VERSION}.linux-${ARCH}.tar.gz"
36
- ENV PATH=$PATH:/usr/local/go/bin
37
- ENV GOPATH=/home/node/go
38
- ENV PATH=$PATH:/home/node/go/bin
39
-
40
- # Ensure default node user has access to /usr/local/share
41
- RUN mkdir -p /usr/local/share/npm-global && \
42
- chown -R node:node /usr/local/share
43
-
44
- ARG USERNAME=node
45
-
46
- # Persist bash history.
47
- RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
48
- && mkdir /commandhistory \
49
- && touch /commandhistory/.bash_history \
50
- && chown -R $USERNAME /commandhistory
51
-
52
- # Set `DEVCONTAINER` environment variable to help with orientation
53
- ENV DEVCONTAINER=true
54
-
55
- # Create workspace and config directories and set permissions
56
- RUN mkdir -p /workspace /home/node/.claude && \
57
- chown -R node:node /workspace /home/node/.claude
58
-
59
- WORKDIR /workspace
60
-
61
- ARG GIT_DELTA_VERSION=0.18.2
62
- RUN ARCH=$(dpkg --print-architecture) && \
63
- wget "https://github.com/dandavison/delta/releases/download/${GIT_DELTA_VERSION}/git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
64
- sudo dpkg -i "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
65
- rm "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb"
66
-
67
- # Set up non-root user
68
- USER node
69
-
70
- # Install global packages
71
- ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global
72
- ENV PATH=$PATH:/usr/local/share/npm-global/bin
73
-
74
- # Set the default shell to zsh rather than sh
75
- ENV SHELL=/bin/zsh
76
-
77
- # Set the default editor and visual
78
- ENV EDITOR=nano
79
- ENV VISUAL=nano
80
-
81
- # Default powerline10k theme
82
- ARG ZSH_IN_DOCKER_VERSION=1.2.0
83
- RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v${ZSH_IN_DOCKER_VERSION}/zsh-in-docker.sh)" -- \
84
- -p git \
85
- -p fzf \
86
- -a "source /usr/share/doc/fzf/examples/key-bindings.zsh" \
87
- -a "source /usr/share/doc/fzf/examples/completion.zsh" \
88
- -a "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
89
- -x
90
-
91
- # Install Gambit (Solidity mutation testing)
92
- ARG GAMBIT_VERSION=v1.0.6
93
- USER root
94
- RUN wget -q "https://github.com/Certora/gambit/releases/download/${GAMBIT_VERSION}/gambit-linux-${GAMBIT_VERSION}" -O /usr/local/bin/gambit && \
95
- chmod +x /usr/local/bin/gambit
96
- USER node
97
-
98
- # Install Foundry (forge, cast, anvil, chisel)
99
- ENV PATH=$PATH:/home/node/.foundry/bin
100
- RUN curl -L https://foundry.paradigm.xyz | bash && foundryup
101
-
102
- # Symlink solc
103
- USER root
104
- RUN ln -s /home/node/.svm/0.8.33/solc-0.8.33 /usr/local/bin/solc
105
- USER node
106
-
107
- # Install Claude
108
- RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
109
-
110
-
111
- # Copy and set up firewall script
112
- COPY init-firewall.sh /usr/local/bin/
113
- USER root
114
- RUN chmod +x /usr/local/bin/init-firewall.sh && \
115
- echo "node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh" > /etc/sudoers.d/node-firewall && \
116
- chmod 0440 /etc/sudoers.d/node-firewall
117
- USER node
@@ -1,62 +0,0 @@
1
- {
2
- "name": "Claude Code Sandbox",
3
- "build": {
4
- "dockerfile": "Dockerfile",
5
- "args": {
6
- "TZ": "${localEnv:TZ:America/Los_Angeles}",
7
- "CLAUDE_CODE_VERSION": "latest",
8
- "GIT_DELTA_VERSION": "0.18.2",
9
- "ZSH_IN_DOCKER_VERSION": "1.2.0"
10
- }
11
- },
12
- "runArgs": [
13
- "--cap-add=NET_ADMIN",
14
- "--cap-add=NET_RAW"
15
- ],
16
- "customizations": {
17
- "vscode": {
18
- "extensions": [
19
- "anthropic.claude-code",
20
- "dbaeumer.vscode-eslint",
21
- "esbenp.prettier-vscode",
22
- "eamodio.gitlens",
23
- "golang.go"
24
- ],
25
- "settings": {
26
- "go.useLanguageServer": true,
27
- "[go]": {
28
- "editor.formatOnSave": true,
29
- "editor.defaultFormatter": "golang.go",
30
- "editor.codeActionsOnSave": {
31
- "source.organizeImports": "explicit"
32
- }
33
- },
34
- "terminal.integrated.defaultProfile.linux": "zsh",
35
- "terminal.integrated.profiles.linux": {
36
- "bash": {
37
- "path": "bash",
38
- "icon": "terminal-bash"
39
- },
40
- "zsh": {
41
- "path": "zsh"
42
- }
43
- }
44
- }
45
- }
46
- },
47
- "remoteUser": "node",
48
- "mounts": [
49
- "source=claude-code-bashhistory-${devcontainerId},target=/commandhistory,type=volume",
50
- "source=claude-code-config-${devcontainerId},target=/home/node/.claude,type=volume"
51
- ],
52
- "containerEnv": {
53
- "NODE_OPTIONS": "--max-old-space-size=4096",
54
- "CLAUDE_CONFIG_DIR": "/home/node/.claude",
55
- "GOPATH": "/home/node/go",
56
- "POWERLEVEL9K_DISABLE_GITSTATUS": "true"
57
- },
58
- "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=delegated",
59
- "workspaceFolder": "/workspace",
60
- "postStartCommand": "sudo /usr/local/bin/init-firewall.sh",
61
- "waitFor": "postStartCommand"
62
- }
@@ -1,118 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail # Exit on error, undefined vars, and pipeline failures
3
- IFS=$'\n\t' # Stricter word splitting
4
-
5
- # 1. Extract Docker DNS info BEFORE any flushing
6
- DOCKER_DNS_RULES=$(iptables-save -t nat | grep "127\.0\.0\.11" || true)
7
-
8
- # Flush existing rules and delete existing ipsets
9
- iptables -F
10
- iptables -X
11
- iptables -t nat -F
12
- iptables -t nat -X
13
- iptables -t mangle -F
14
- iptables -t mangle -X
15
- ipset destroy allowed-domains 2>/dev/null || true
16
-
17
- # 2. Selectively restore ONLY internal Docker DNS resolution
18
- if [ -n "$DOCKER_DNS_RULES" ]; then
19
- echo "Restoring Docker DNS rules..."
20
- iptables -t nat -N DOCKER_OUTPUT 2>/dev/null || true
21
- iptables -t nat -N DOCKER_POSTROUTING 2>/dev/null || true
22
- echo "$DOCKER_DNS_RULES" | xargs -L 1 iptables -t nat
23
- else
24
- echo "No Docker DNS rules to restore"
25
- fi
26
-
27
- # First allow DNS and localhost before any restrictions
28
- # Allow outbound DNS
29
- iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
30
- # Allow inbound DNS responses
31
- iptables -A INPUT -p udp --sport 53 -j ACCEPT
32
- # Allow outbound SSH
33
- iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
34
- # Allow inbound SSH responses
35
- iptables -A INPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
36
- # Allow localhost
37
- iptables -A INPUT -i lo -j ACCEPT
38
- iptables -A OUTPUT -o lo -j ACCEPT
39
-
40
- # Create ipset with CIDR support
41
- ipset create allowed-domains hash:net
42
-
43
- # Resolve and add other allowed domains
44
- for domain in \
45
- "registry.npmjs.org" \
46
- "api.anthropic.com" \
47
- "sentry.io" \
48
- "statsig.anthropic.com" \
49
- "statsig.com" \
50
- "marketplace.visualstudio.com" \
51
- "vscode.blob.core.windows.net" \
52
- "update.code.visualstudio.com" \
53
- "proxy.golang.org" \
54
- "sum.golang.org" \
55
- "storage.googleapis.com" \
56
- "binaries.soliditylang.org"; do
57
- echo "Resolving $domain..."
58
- ips=$(dig +noall +answer A "$domain" | awk '$4 == "A" {print $5}')
59
- if [ -z "$ips" ]; then
60
- echo "ERROR: Failed to resolve $domain"
61
- exit 1
62
- fi
63
-
64
- while read -r ip; do
65
- if [[ ! "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
66
- echo "ERROR: Invalid IP from DNS for $domain: $ip"
67
- exit 1
68
- fi
69
- echo "Adding $ip for $domain"
70
- ipset add allowed-domains "$ip" -exist
71
- done < <(echo "$ips")
72
- done
73
-
74
- # Get host IP from default route
75
- HOST_IP=$(ip route | grep default | cut -d" " -f3)
76
- if [ -z "$HOST_IP" ]; then
77
- echo "ERROR: Failed to detect host IP"
78
- exit 1
79
- fi
80
-
81
- HOST_NETWORK=$(echo "$HOST_IP" | sed "s/\.[0-9]*$/.0\/24/")
82
- echo "Host network detected as: $HOST_NETWORK"
83
-
84
- # Set up remaining iptables rules
85
- iptables -A INPUT -s "$HOST_NETWORK" -j ACCEPT
86
- iptables -A OUTPUT -d "$HOST_NETWORK" -j ACCEPT
87
-
88
- # Set default policies to DROP first
89
- iptables -P INPUT DROP
90
- iptables -P FORWARD DROP
91
- iptables -P OUTPUT DROP
92
-
93
- # First allow established connections for already approved traffic
94
- iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
95
- iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
96
-
97
- # Then allow only specific outbound traffic to allowed domains
98
- iptables -A OUTPUT -m set --match-set allowed-domains dst -j ACCEPT
99
-
100
- # Explicitly REJECT all other outbound traffic for immediate feedback
101
- iptables -A OUTPUT -j REJECT --reject-with icmp-admin-prohibited
102
-
103
- echo "Firewall configuration complete"
104
- echo "Verifying firewall rules..."
105
- if curl --connect-timeout 5 https://example.com >/dev/null 2>&1; then
106
- echo "ERROR: Firewall verification failed - was able to reach https://example.com"
107
- exit 1
108
- else
109
- echo "Firewall verification passed - unable to reach https://example.com as expected"
110
- fi
111
-
112
- # Verify GitHub API access
113
- if curl --connect-timeout 5 https://api.github.com/zen >/dev/null 2>&1; then
114
- echo "ERROR: Firewall verification failed - was able to reach https://api.github.com"
115
- exit 1
116
- else
117
- echo "Firewall verification passed - unable to reach https://api.github.com as expected"
118
- fi
@@ -1,38 +0,0 @@
1
- name: CI
2
-
3
- permissions: {}
4
-
5
- on:
6
- push:
7
- pull_request:
8
- workflow_dispatch:
9
-
10
- env:
11
- FOUNDRY_PROFILE: ci
12
-
13
- jobs:
14
- check:
15
- name: Foundry project
16
- runs-on: ubuntu-latest
17
- permissions:
18
- contents: read
19
- steps:
20
- - uses: actions/checkout@v5
21
- with:
22
- persist-credentials: false
23
- submodules: recursive
24
-
25
- - name: Install Foundry
26
- uses: foundry-rs/foundry-toolchain@v1
27
-
28
- - name: Show Forge version
29
- run: forge --version
30
-
31
- - name: Run Forge fmt
32
- run: forge fmt --check
33
-
34
- - name: Run Forge build
35
- run: forge build --sizes
36
-
37
- - name: Run Forge tests
38
- run: forge test -vvv
package/.gitmodules DELETED
@@ -1,3 +0,0 @@
1
- [submodule "lib/forge-std"]
2
- path = lib/forge-std
3
- url = https://github.com/foundry-rs/forge-std
package/CLAUDE.md DELETED
@@ -1,39 +0,0 @@
1
- # CLAUDE.md
2
-
3
- ## Git
4
-
5
- Always commit with `--no-gpg-sign` — GPG signing is not configured in this container.
6
-
7
- ## Solidity Toolchain
8
-
9
- `solc` is symlinked into PATH via the Dockerfile. If `solc` is not found (e.g. after a container rebuild), run `forge clean && forge build` — Foundry will re-install solc via svm automatically.
10
-
11
- ## Development Environment
12
-
13
- This project runs inside a devcontainer (`.devcontainer/`). The container is locked down with an iptables firewall that only allows traffic to a small allowlist of domains.
14
-
15
- - **To install system packages or tools** — edit `.devcontainer/Dockerfile` and rebuild the container.
16
- - **To allow network access to a new domain** — add it to the domain list in `.devcontainer/init-firewall.sh`.
17
-
18
- ## Tooling Philosophy
19
-
20
- Always use the right tool for the job — install real libraries instead of reimplementing things with stdlib. If a dependency is missing and can't be installed due to the container/firewall setup, ask the user to help unblock it (e.g. add a domain to the firewall, add a package to the Dockerfile, rebuild the container). Don't silently work around missing tools with inferior hand-rolled alternatives.
21
-
22
- ## Documentation
23
-
24
- When adding or modifying a feature, always update the relevant documentation if it exists. Keep docs in sync with code.
25
-
26
- ## Code Style
27
-
28
- Inspired by NASA/JPL's "Power of 10" — code must be quickly and easily reviewable by a human.
29
-
30
- - Write minimal, concise code. No unnecessary abstractions or indirection.
31
- - Functions should be short enough to fit on a screen (~60 lines max). If longer, split by responsibility.
32
- - Simple control flow. Minimal nesting, early returns over deep if/else chains.
33
- - Smallest possible scope for all variables and data.
34
- - No comments unless the logic is genuinely non-obvious. Never restate what the code already says.
35
- - No JSDoc unless it's a public API. Skip @param/@returns that just repeat type signatures.
36
- - Don't add error handling, validation, or fallbacks for cases that can't realistically happen.
37
- - Prefer fewer lines. Three similar lines are better than a helper function used once.
38
- - Don't refactor, rename, or "improve" code you weren't asked to change.
39
- - No clever tricks. Code should be obvious, not impressive.
package/foundry.lock DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "lib/forge-std": {
3
- "tag": {
4
- "name": "v1.15.0",
5
- "rev": "0844d7e1fc5e60d77b68e469bff60265f236c398"
6
- }
7
- }
8
- }
package/foundry.toml DELETED
@@ -1,6 +0,0 @@
1
- [profile.default]
2
- src = "src"
3
- out = "out"
4
- libs = ["lib"]
5
-
6
- # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
@@ -1 +0,0 @@
1
- src/Vm.sol linguist-generated
@@ -1 +0,0 @@
1
- * @danipopes @klkvr @mattsse @grandizzy @yash-atreya @zerosnacks @onbjerg @0xrusowsky
@@ -1,6 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: "github-actions"
4
- directory: "/"
5
- schedule:
6
- interval: "weekly"
@@ -1,125 +0,0 @@
1
- name: CI
2
-
3
- permissions: {}
4
-
5
- on:
6
- workflow_dispatch:
7
- pull_request:
8
- push:
9
- branches:
10
- - master
11
-
12
- jobs:
13
- build:
14
- name: build +${{ matrix.toolchain }} ${{ matrix.flags }}
15
- runs-on: ubuntu-latest
16
- timeout-minutes: 10
17
- permissions:
18
- contents: read
19
- strategy:
20
- fail-fast: false
21
- matrix:
22
- toolchain: [stable, nightly]
23
- flags:
24
- - ""
25
- - --via-ir
26
- - --use solc:0.8.33 --via-ir
27
- - --use solc:0.8.33
28
- - --use solc:0.8.13 --via-ir
29
- - --use solc:0.8.13
30
- steps:
31
- - uses: actions/checkout@v6
32
- with:
33
- persist-credentials: false
34
- - uses: foundry-rs/foundry-toolchain@v1
35
- with:
36
- version: ${{ matrix.toolchain }}
37
- - run: forge --version
38
- - run: forge build -vvvvv --skip test --deny warnings ${{ matrix.flags }} --contracts 'test/compilation/*'
39
-
40
- test:
41
- runs-on: ubuntu-latest
42
- timeout-minutes: 10
43
- permissions:
44
- contents: read
45
- strategy:
46
- fail-fast: false
47
- matrix:
48
- toolchain: [stable, nightly]
49
- steps:
50
- - uses: actions/checkout@v6
51
- with:
52
- persist-credentials: false
53
- - uses: foundry-rs/foundry-toolchain@v1
54
- with:
55
- version: ${{ matrix.toolchain }}
56
- - run: forge --version
57
- - run: forge test -vvv
58
-
59
- fmt:
60
- runs-on: ubuntu-latest
61
- timeout-minutes: 10
62
- permissions:
63
- contents: read
64
- steps:
65
- - uses: actions/checkout@v6
66
- with:
67
- persist-credentials: false
68
- - uses: foundry-rs/foundry-toolchain@v1
69
- - run: forge --version
70
- - run: forge fmt --check
71
-
72
- typos:
73
- runs-on: ubuntu-latest
74
- timeout-minutes: 10
75
- permissions:
76
- contents: read
77
- steps:
78
- - uses: actions/checkout@v6
79
- with:
80
- persist-credentials: false
81
- - uses: crate-ci/typos@78bc6fb2c0d734235d57a2d6b9de923cc325ebdd # v1
82
-
83
- codeql:
84
- name: Analyze (${{ matrix.language }})
85
- runs-on: ubuntu-latest
86
- permissions:
87
- security-events: write
88
- actions: read
89
- contents: read
90
- strategy:
91
- fail-fast: false
92
- matrix:
93
- include:
94
- - language: actions
95
- build-mode: none
96
- steps:
97
- - name: Checkout repository
98
- uses: actions/checkout@v6
99
- with:
100
- persist-credentials: false
101
- - name: Initialize CodeQL
102
- uses: github/codeql-action/init@v4
103
- with:
104
- languages: ${{ matrix.language }}
105
- build-mode: ${{ matrix.build-mode }}
106
- - name: Perform CodeQL Analysis
107
- uses: github/codeql-action/analyze@v4
108
- with:
109
- category: "/language:${{matrix.language}}"
110
-
111
- ci-success:
112
- runs-on: ubuntu-latest
113
- if: always()
114
- needs:
115
- - build
116
- - test
117
- - fmt
118
- - typos
119
- - codeql
120
- timeout-minutes: 10
121
- steps:
122
- - name: Decide whether the needed jobs succeeded or failed
123
- uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # release/v1
124
- with:
125
- jobs: ${{ toJSON(needs) }}
@@ -1,36 +0,0 @@
1
- name: Sync Release Branch
2
-
3
- permissions: {}
4
-
5
- on:
6
- release:
7
- types:
8
- - created
9
-
10
- jobs:
11
- sync-release-branch:
12
- runs-on: ubuntu-latest
13
- permissions:
14
- contents: write
15
- if: startsWith(github.event.release.tag_name, 'v1')
16
- steps:
17
- - name: Check out the repo
18
- uses: actions/checkout@v6
19
- with:
20
- persist-credentials: true
21
- fetch-depth: 0
22
- ref: v1
23
-
24
- # The email is derived from the bots user id,
25
- # found here: https://api.github.com/users/github-actions%5Bbot%5D
26
- - name: Configure Git
27
- run: |
28
- git config user.name github-actions[bot]
29
- git config user.email 41898282+github-actions[bot]@users.noreply.github.com
30
-
31
- - name: Sync Release Branch
32
- run: |
33
- git fetch --tags
34
- git checkout v1
35
- git reset --hard ${GITHUB_REF}
36
- git push --force