From f8d8e42fafb917c1047fc92a0c83e3e1b7be6877 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 6 Feb 2026 18:57:24 +0000 Subject: [PATCH 1/7] Add automated TEST_COVERAGE.md updates on PR merge - Add scripts/update-test-coverage-doc.sh that runs tests with coverage, parses results (coverage %, pass/fail counts, per-file breakdown), and updates the auto-generated sections in cadence/tests/TEST_COVERAGE.md - Add .github/workflows/update_test_coverage.yml that triggers on push to main (i.e. after PR merge) and runs the update script - Add HTML comment markers in TEST_COVERAGE.md to delineate the auto-generated stats table and per-file results table from the manually curated analysis sections https://claude.ai/code/session_01McrgPdo8SVWxQQ63j9Esbb --- .github/workflows/update_test_coverage.yml | 65 ++++++++ cadence/tests/TEST_COVERAGE.md | 32 +++- scripts/update-test-coverage-doc.sh | 174 +++++++++++++++++++++ 3 files changed, 266 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/update_test_coverage.yml create mode 100755 scripts/update-test-coverage-doc.sh diff --git a/.github/workflows/update_test_coverage.yml b/.github/workflows/update_test_coverage.yml new file mode 100644 index 00000000..ed1941b7 --- /dev/null +++ b/.github/workflows/update_test_coverage.yml @@ -0,0 +1,65 @@ +name: Update TEST_COVERAGE.md + +on: + push: + branches: + - main + workflow_dispatch: + +# Prevent concurrent runs from conflicting commits +concurrency: + group: update-test-coverage + cancel-in-progress: true + +permissions: + contents: write + +jobs: + update-coverage-doc: + name: Update test coverage documentation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.GH_PAT }} + submodules: "true" + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: "1.23.x" + + - uses: actions/cache@v4 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Install Flow CLI + env: + FLOW_CLI_VERSION: v2.7.2 + run: sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)" + + - name: Update PATH + run: | + echo "/root/.local/bin" >> $GITHUB_PATH + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Install dependencies + run: flow deps install --skip-alias --skip-deployments + + - name: Run tests and update TEST_COVERAGE.md + run: ./scripts/update-test-coverage-doc.sh + + - name: Commit and push if changed + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add cadence/tests/TEST_COVERAGE.md + if git diff --cached --quiet; then + echo "No changes to TEST_COVERAGE.md" + else + git commit -m "docs: auto-update TEST_COVERAGE.md with latest test results" + git push + fi diff --git a/cadence/tests/TEST_COVERAGE.md b/cadence/tests/TEST_COVERAGE.md index 85db3cf4..7f63f7f7 100644 --- a/cadence/tests/TEST_COVERAGE.md +++ b/cadence/tests/TEST_COVERAGE.md @@ -1,10 +1,22 @@ # Test Coverage Analysis - TidalProtocol (FlowCreditMarket) -**Analysis Date:** 2026-01-28 + + + +| Metric | Value | +|--------|-------| +| **Last Updated** | 2026-01-28 | +| **Coverage** | 89.7% | +| **Test Files** | 31 | +| **Total Tests** | 22 | +| **Passed** | 22 | +| **Failed** | 0 | +| **Status** | All tests passing | + + + **Repository:** TidalProtocol **Core Contract:** FlowCreditMarket.cdc -**Test Coverage:** 89.7% -**Total Core Tests:** 31 test files --- @@ -53,6 +65,15 @@ The protocol uses Cadence's native Test framework with: - Time manipulation capabilities (`Test.moveTime()`, `Test.moveToBlockHeight()`) - Custom test runner script (`run_tests.sh`) to handle contract persistence issues + + + +### Latest Test Results by File + +*Results will be populated automatically after the next PR merge to main.* + + + --- ## Test Organization and Structure @@ -1129,6 +1150,7 @@ Implementing these test enhancements will increase confidence in the protocol's --- -**Document Version:** 1.0 -**Last Updated:** 2026-01-28 +**Document Version:** 1.1 +**Last Updated:** 2026-02-06 +**Auto-updated by:** `.github/workflows/update_test_coverage.yml` on every PR merge to main **Next Review:** After implementation of high-priority test gaps diff --git a/scripts/update-test-coverage-doc.sh b/scripts/update-test-coverage-doc.sh new file mode 100755 index 00000000..81420d33 --- /dev/null +++ b/scripts/update-test-coverage-doc.sh @@ -0,0 +1,174 @@ +#!/usr/bin/env bash +set -euo pipefail + +# update-test-coverage-doc.sh +# +# Runs the Cadence test suite with coverage, parses the output, and updates +# the auto-generated sections of cadence/tests/TEST_COVERAGE.md. +# +# Usage: +# ./scripts/update-test-coverage-doc.sh # run tests and update doc +# ./scripts/update-test-coverage-doc.sh --from-file output.txt # parse existing output + +ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" +DOC_FILE="$ROOT_DIR/cadence/tests/TEST_COVERAGE.md" +TEST_DIR="$ROOT_DIR/cadence/tests" +OUTPUT_FILE="" + +# --------------------------------------------------------------------------- +# Parse arguments +# --------------------------------------------------------------------------- +while [[ $# -gt 0 ]]; do + case "$1" in + --from-file) + OUTPUT_FILE="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + +# --------------------------------------------------------------------------- +# Run tests (or read prior output) +# --------------------------------------------------------------------------- +if [[ -n "$OUTPUT_FILE" ]]; then + echo "Reading test output from $OUTPUT_FILE" + TEST_OUTPUT="$(cat "$OUTPUT_FILE")" +else + echo "Running tests with coverage..." + TEST_OUTPUT="$(flow test --cover --covercode="contracts" \ + "$TEST_DIR"/*_test.cdc 2>&1)" || true +fi + +# --------------------------------------------------------------------------- +# Parse results +# --------------------------------------------------------------------------- +TODAY="$(date -u +%Y-%m-%d)" + +# Coverage percentage — look for "Coverage: XX.X% of statements" +COVERAGE="$(echo "$TEST_OUTPUT" | grep -oP 'Coverage:\s+\K[0-9]+(\.[0-9]+)?%' | head -1)" || true +if [[ -z "$COVERAGE" ]]; then + COVERAGE="N/A" +fi + +# Count test files +TOTAL_FILES="$(find "$TEST_DIR" -maxdepth 1 -name '*_test.cdc' | wc -l)" + +# Individual test results — lines like "- PASS: funcName" or "- FAIL: funcName" +PASS_COUNT="$(echo "$TEST_OUTPUT" | grep -cP '^\s*-\s+PASS:' || true)" +FAIL_COUNT="$(echo "$TEST_OUTPUT" | grep -cP '^\s*-\s+FAIL:' || true)" +TOTAL_TESTS=$((PASS_COUNT + FAIL_COUNT)) + +if [[ "$FAIL_COUNT" -eq 0 && "$TOTAL_TESTS" -gt 0 ]]; then + STATUS="All tests passing" +elif [[ "$TOTAL_TESTS" -eq 0 ]]; then + STATUS="No test results parsed" +else + STATUS="$FAIL_COUNT failing" +fi + +# --------------------------------------------------------------------------- +# Build per-file results table +# --------------------------------------------------------------------------- +# Parse "Test results: " blocks followed by PASS/FAIL lines. +FILE_TABLE="" +CURRENT_FILE="" +FILE_PASS=0 +FILE_FAIL=0 + +flush_file() { + if [[ -n "$CURRENT_FILE" ]]; then + local ftotal=$((FILE_PASS + FILE_FAIL)) + local fstatus="PASS" + if [[ "$FILE_FAIL" -gt 0 ]]; then + fstatus="FAIL" + fi + FILE_TABLE+="| ${CURRENT_FILE} | ${ftotal} | ${FILE_PASS} | ${FILE_FAIL} | ${fstatus} |"$'\n' + fi +} + +while IFS= read -r line; do + if echo "$line" | grep -qP '^Test results:'; then + flush_file + # Extract just the filename + CURRENT_FILE="$(echo "$line" | grep -oP '[^/]+_test\.cdc' || echo "$line")" + FILE_PASS=0 + FILE_FAIL=0 + elif echo "$line" | grep -qP '^\s*-\s+PASS:'; then + FILE_PASS=$((FILE_PASS + 1)) + elif echo "$line" | grep -qP '^\s*-\s+FAIL:'; then + FILE_FAIL=$((FILE_FAIL + 1)) + fi +done <<< "$TEST_OUTPUT" +flush_file + +# --------------------------------------------------------------------------- +# Build the replacement block +# --------------------------------------------------------------------------- +STATS_BLOCK=" + + +| Metric | Value | +|--------|-------| +| **Last Updated** | ${TODAY} | +| **Coverage** | ${COVERAGE} | +| **Test Files** | ${TOTAL_FILES} | +| **Total Tests** | ${TOTAL_TESTS} | +| **Passed** | ${PASS_COUNT} | +| **Failed** | ${FAIL_COUNT} | +| **Status** | ${STATUS} | + +" + +RESULTS_BLOCK=" + + +### Latest Test Results by File + +| File | Tests | Passed | Failed | Status | +|------|-------|--------|--------|--------| +${FILE_TABLE} +" + +# --------------------------------------------------------------------------- +# Update the markdown file +# --------------------------------------------------------------------------- +if [[ ! -f "$DOC_FILE" ]]; then + echo "Error: $DOC_FILE not found" >&2 + exit 1 +fi + +# Replace content between markers using awk +update_section() { + local start_marker="$1" + local end_marker="$2" + local new_content="$3" + local file="$4" + + awk -v start="$start_marker" -v end="$end_marker" -v content="$new_content" ' + $0 ~ start { print content; skip=1; next } + $0 ~ end { skip=0; next } + !skip { print } + ' "$file" +} + +# Apply stats section +TEMP_FILE="$(mktemp)" +update_section "AUTO-GENERATED-STATS-START" "AUTO-GENERATED-STATS-END" \ + "$STATS_BLOCK" "$DOC_FILE" > "$TEMP_FILE" + +# Apply results section +update_section "AUTO-GENERATED-RESULTS-START" "AUTO-GENERATED-RESULTS-END" \ + "$RESULTS_BLOCK" "$TEMP_FILE" > "$DOC_FILE" + +rm -f "$TEMP_FILE" + +echo "" +echo "Updated $DOC_FILE" +echo " Coverage: $COVERAGE" +echo " Tests: $TOTAL_TESTS ($PASS_COUNT passed, $FAIL_COUNT failed)" +echo " Test files: $TOTAL_FILES" +echo " Status: $STATUS" From 4bff0e37b09a6113e161a023902929856ce9586d Mon Sep 17 00:00:00 2001 From: vishal <1117327+vishalchangrani@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:46:21 -0500 Subject: [PATCH 2/7] Add Cadence lint target to Makefile Co-Authored-By: Claude Opus 4.6 --- Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..b7a820e1 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +.PHONY: lint +lint: + @output=$$(flow cadence lint $$(find cadence -name "*.cdc") 2>&1); \ + echo "$$output"; \ + if echo "$$output" | grep -qE "[1-9][0-9]* problems"; then \ + echo "Lint failed: problems found"; \ + exit 1; \ + fi From ff6f39ff01efa06fc1618790957dab20e7447173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Thu, 19 Mar 2026 12:53:31 -0700 Subject: [PATCH 3/7] update CLI --- .github/workflows/cadence_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cadence_tests.yml b/.github/workflows/cadence_tests.yml index d0fe6a17..a9a0dba7 100644 --- a/.github/workflows/cadence_tests.yml +++ b/.github/workflows/cadence_tests.yml @@ -34,7 +34,7 @@ jobs: key: flow-deps-${{ hashFiles('flow.json') }} - name: Install Flow CLI env: - FLOW_CLI_VERSION: v2.7.2 + FLOW_CLI_VERSION: v2.15.1 run: sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)" - name: Update PATH and show Flow version run: | From 6d043e389b118b3f0ae6d3cd4719975ae846a34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Thu, 19 Mar 2026 12:57:46 -0700 Subject: [PATCH 4/7] move lint and test to Makefile, like in FlowActions --- .github/workflows/cadence_tests.yml | 6 ++---- Makefile | 15 +++++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cadence_tests.yml b/.github/workflows/cadence_tests.yml index a9a0dba7..105801c2 100644 --- a/.github/workflows/cadence_tests.yml +++ b/.github/workflows/cadence_tests.yml @@ -33,9 +33,7 @@ jobs: path: ./imports key: flow-deps-${{ hashFiles('flow.json') }} - name: Install Flow CLI - env: - FLOW_CLI_VERSION: v2.15.1 - run: sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)" + run: sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)" -- v2.15.1 - name: Update PATH and show Flow version run: | echo "/root/.local/bin" >> $GITHUB_PATH @@ -45,7 +43,7 @@ jobs: - name: Install dependencies run: flow deps install --skip-alias --skip-deployments - name: Run tests - run: flow test --cover --covercode="contracts" --coverprofile="coverage.lcov" ./cadence/tests/*_test.cdc + run: make ci - name: Upload coverage report uses: codecov/codecov-action@v5 with: diff --git a/Makefile b/Makefile index b7a820e1..8c3e86cd 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,11 @@ +.PHONY: test +test: + flow test --cover --covercode="contracts" --coverprofile="coverage.lcov" ./cadence/tests/*_test.cdc + .PHONY: lint lint: - @output=$$(flow cadence lint $$(find cadence -name "*.cdc") 2>&1); \ - echo "$$output"; \ - if echo "$$output" | grep -qE "[1-9][0-9]* problems"; then \ - echo "Lint failed: problems found"; \ - exit 1; \ - fi + find cadence -name "*.cdc" | xargs flow cadence lint \ + | tee /dev/stderr | tail -n2 | grep -q "Lint passed" + +.PHONY: ci +ci: lint test From e5f14ef3201198ec3cd0eec8c1b5ee09c79f09a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Thu, 19 Mar 2026 13:00:35 -0700 Subject: [PATCH 5/7] Revert "Add automated TEST_COVERAGE.md updates on PR merge" This reverts commit f8d8e42fafb917c1047fc92a0c83e3e1b7be6877. --- .github/workflows/update_test_coverage.yml | 65 -------- scripts/update-test-coverage-doc.sh | 174 --------------------- 2 files changed, 239 deletions(-) delete mode 100644 .github/workflows/update_test_coverage.yml delete mode 100755 scripts/update-test-coverage-doc.sh diff --git a/.github/workflows/update_test_coverage.yml b/.github/workflows/update_test_coverage.yml deleted file mode 100644 index ed1941b7..00000000 --- a/.github/workflows/update_test_coverage.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: Update TEST_COVERAGE.md - -on: - push: - branches: - - main - workflow_dispatch: - -# Prevent concurrent runs from conflicting commits -concurrency: - group: update-test-coverage - cancel-in-progress: true - -permissions: - contents: write - -jobs: - update-coverage-doc: - name: Update test coverage documentation - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - token: ${{ secrets.GH_PAT }} - submodules: "true" - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: "1.23.x" - - - uses: actions/cache@v4 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - - name: Install Flow CLI - env: - FLOW_CLI_VERSION: v2.7.2 - run: sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)" - - - name: Update PATH - run: | - echo "/root/.local/bin" >> $GITHUB_PATH - echo "$HOME/.local/bin" >> $GITHUB_PATH - - - name: Install dependencies - run: flow deps install --skip-alias --skip-deployments - - - name: Run tests and update TEST_COVERAGE.md - run: ./scripts/update-test-coverage-doc.sh - - - name: Commit and push if changed - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add cadence/tests/TEST_COVERAGE.md - if git diff --cached --quiet; then - echo "No changes to TEST_COVERAGE.md" - else - git commit -m "docs: auto-update TEST_COVERAGE.md with latest test results" - git push - fi diff --git a/scripts/update-test-coverage-doc.sh b/scripts/update-test-coverage-doc.sh deleted file mode 100755 index 81420d33..00000000 --- a/scripts/update-test-coverage-doc.sh +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -# update-test-coverage-doc.sh -# -# Runs the Cadence test suite with coverage, parses the output, and updates -# the auto-generated sections of cadence/tests/TEST_COVERAGE.md. -# -# Usage: -# ./scripts/update-test-coverage-doc.sh # run tests and update doc -# ./scripts/update-test-coverage-doc.sh --from-file output.txt # parse existing output - -ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" -DOC_FILE="$ROOT_DIR/cadence/tests/TEST_COVERAGE.md" -TEST_DIR="$ROOT_DIR/cadence/tests" -OUTPUT_FILE="" - -# --------------------------------------------------------------------------- -# Parse arguments -# --------------------------------------------------------------------------- -while [[ $# -gt 0 ]]; do - case "$1" in - --from-file) - OUTPUT_FILE="$2" - shift 2 - ;; - *) - echo "Unknown option: $1" >&2 - exit 1 - ;; - esac -done - -# --------------------------------------------------------------------------- -# Run tests (or read prior output) -# --------------------------------------------------------------------------- -if [[ -n "$OUTPUT_FILE" ]]; then - echo "Reading test output from $OUTPUT_FILE" - TEST_OUTPUT="$(cat "$OUTPUT_FILE")" -else - echo "Running tests with coverage..." - TEST_OUTPUT="$(flow test --cover --covercode="contracts" \ - "$TEST_DIR"/*_test.cdc 2>&1)" || true -fi - -# --------------------------------------------------------------------------- -# Parse results -# --------------------------------------------------------------------------- -TODAY="$(date -u +%Y-%m-%d)" - -# Coverage percentage — look for "Coverage: XX.X% of statements" -COVERAGE="$(echo "$TEST_OUTPUT" | grep -oP 'Coverage:\s+\K[0-9]+(\.[0-9]+)?%' | head -1)" || true -if [[ -z "$COVERAGE" ]]; then - COVERAGE="N/A" -fi - -# Count test files -TOTAL_FILES="$(find "$TEST_DIR" -maxdepth 1 -name '*_test.cdc' | wc -l)" - -# Individual test results — lines like "- PASS: funcName" or "- FAIL: funcName" -PASS_COUNT="$(echo "$TEST_OUTPUT" | grep -cP '^\s*-\s+PASS:' || true)" -FAIL_COUNT="$(echo "$TEST_OUTPUT" | grep -cP '^\s*-\s+FAIL:' || true)" -TOTAL_TESTS=$((PASS_COUNT + FAIL_COUNT)) - -if [[ "$FAIL_COUNT" -eq 0 && "$TOTAL_TESTS" -gt 0 ]]; then - STATUS="All tests passing" -elif [[ "$TOTAL_TESTS" -eq 0 ]]; then - STATUS="No test results parsed" -else - STATUS="$FAIL_COUNT failing" -fi - -# --------------------------------------------------------------------------- -# Build per-file results table -# --------------------------------------------------------------------------- -# Parse "Test results: " blocks followed by PASS/FAIL lines. -FILE_TABLE="" -CURRENT_FILE="" -FILE_PASS=0 -FILE_FAIL=0 - -flush_file() { - if [[ -n "$CURRENT_FILE" ]]; then - local ftotal=$((FILE_PASS + FILE_FAIL)) - local fstatus="PASS" - if [[ "$FILE_FAIL" -gt 0 ]]; then - fstatus="FAIL" - fi - FILE_TABLE+="| ${CURRENT_FILE} | ${ftotal} | ${FILE_PASS} | ${FILE_FAIL} | ${fstatus} |"$'\n' - fi -} - -while IFS= read -r line; do - if echo "$line" | grep -qP '^Test results:'; then - flush_file - # Extract just the filename - CURRENT_FILE="$(echo "$line" | grep -oP '[^/]+_test\.cdc' || echo "$line")" - FILE_PASS=0 - FILE_FAIL=0 - elif echo "$line" | grep -qP '^\s*-\s+PASS:'; then - FILE_PASS=$((FILE_PASS + 1)) - elif echo "$line" | grep -qP '^\s*-\s+FAIL:'; then - FILE_FAIL=$((FILE_FAIL + 1)) - fi -done <<< "$TEST_OUTPUT" -flush_file - -# --------------------------------------------------------------------------- -# Build the replacement block -# --------------------------------------------------------------------------- -STATS_BLOCK=" - - -| Metric | Value | -|--------|-------| -| **Last Updated** | ${TODAY} | -| **Coverage** | ${COVERAGE} | -| **Test Files** | ${TOTAL_FILES} | -| **Total Tests** | ${TOTAL_TESTS} | -| **Passed** | ${PASS_COUNT} | -| **Failed** | ${FAIL_COUNT} | -| **Status** | ${STATUS} | - -" - -RESULTS_BLOCK=" - - -### Latest Test Results by File - -| File | Tests | Passed | Failed | Status | -|------|-------|--------|--------|--------| -${FILE_TABLE} -" - -# --------------------------------------------------------------------------- -# Update the markdown file -# --------------------------------------------------------------------------- -if [[ ! -f "$DOC_FILE" ]]; then - echo "Error: $DOC_FILE not found" >&2 - exit 1 -fi - -# Replace content between markers using awk -update_section() { - local start_marker="$1" - local end_marker="$2" - local new_content="$3" - local file="$4" - - awk -v start="$start_marker" -v end="$end_marker" -v content="$new_content" ' - $0 ~ start { print content; skip=1; next } - $0 ~ end { skip=0; next } - !skip { print } - ' "$file" -} - -# Apply stats section -TEMP_FILE="$(mktemp)" -update_section "AUTO-GENERATED-STATS-START" "AUTO-GENERATED-STATS-END" \ - "$STATS_BLOCK" "$DOC_FILE" > "$TEMP_FILE" - -# Apply results section -update_section "AUTO-GENERATED-RESULTS-START" "AUTO-GENERATED-RESULTS-END" \ - "$RESULTS_BLOCK" "$TEMP_FILE" > "$DOC_FILE" - -rm -f "$TEMP_FILE" - -echo "" -echo "Updated $DOC_FILE" -echo " Coverage: $COVERAGE" -echo " Tests: $TOTAL_TESTS ($PASS_COUNT passed, $FAIL_COUNT failed)" -echo " Test files: $TOTAL_FILES" -echo " Status: $STATUS" From 99451de702361c5a1cfe733f18598a5801840158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastian=20M=C3=BCller?= Date: Thu, 19 Mar 2026 13:10:04 -0700 Subject: [PATCH 6/7] update to Flow CLI v2.15.3 --- .github/workflows/cadence_tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cadence_tests.yml b/.github/workflows/cadence_tests.yml index 105801c2..918e0f41 100644 --- a/.github/workflows/cadence_tests.yml +++ b/.github/workflows/cadence_tests.yml @@ -33,7 +33,7 @@ jobs: path: ./imports key: flow-deps-${{ hashFiles('flow.json') }} - name: Install Flow CLI - run: sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)" -- v2.15.1 + run: sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)" -- v2.15.3 - name: Update PATH and show Flow version run: | echo "/root/.local/bin" >> $GITHUB_PATH From 59af50bc1b15aec290458dae6fd4827bab5e3ea6 Mon Sep 17 00:00:00 2001 From: Kan Zhang Date: Fri, 20 Mar 2026 12:36:26 -0700 Subject: [PATCH 7/7] Make adjustment to only look at the contracts, and make necessary changes --- Makefile | 2 +- cadence/contracts/FlowALPHealth.cdc | 1 - cadence/contracts/FlowALPInterestRates.cdc | 2 +- cadence/contracts/FlowALPModels.cdc | 6 +++--- cadence/contracts/FlowALPPositionResources.cdc | 2 +- cadence/contracts/FlowALPRebalancerv1.cdc | 4 ++-- cadence/contracts/FlowALPSupervisorv1.cdc | 2 +- cadence/contracts/FlowALPv0.cdc | 15 +++------------ cadence/contracts/MOET.cdc | 6 +++--- cadence/contracts/PriceOracleAggregatorv1.cdc | 2 +- cadence/contracts/mocks/DummyConnectors.cdc | 2 +- cadence/contracts/mocks/MockDexSwapper.cdc | 4 ++-- cadence/contracts/mocks/MockYieldToken.cdc | 6 +++--- 13 files changed, 22 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index 8c3e86cd..777982c6 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ test: .PHONY: lint lint: - find cadence -name "*.cdc" | xargs flow cadence lint \ + find cadence/contracts -name "*.cdc" | xargs flow cadence lint \ | tee /dev/stderr | tail -n2 | grep -q "Lint passed" .PHONY: ci diff --git a/cadence/contracts/FlowALPHealth.cdc b/cadence/contracts/FlowALPHealth.cdc index ee50c34d..45813648 100644 --- a/cadence/contracts/FlowALPHealth.cdc +++ b/cadence/contracts/FlowALPHealth.cdc @@ -168,7 +168,6 @@ access(all) contract FlowALPHealth { if potentialHealth >= targetHealth { // We can reach the target health by paying off some or all of the debt. We can easily // compute how many units of the token would be needed to reach the target health. - let healthChange = targetHealth - healthAfterWithdrawal let requiredEffectiveDebt = effectiveDebtAfterWithdrawal - (effectiveCollateralAfterWithdrawal / targetHealth) diff --git a/cadence/contracts/FlowALPInterestRates.cdc b/cadence/contracts/FlowALPInterestRates.cdc index 74819bd6..aa8ff0ae 100644 --- a/cadence/contracts/FlowALPInterestRates.cdc +++ b/cadence/contracts/FlowALPInterestRates.cdc @@ -34,7 +34,7 @@ access(all) contract FlowALPInterestRates { self.yearlyRate = yearlyRate } - access(all) fun interestRate(creditBalance: UFix128, debitBalance: UFix128): UFix128 { + access(all) fun interestRate(creditBalance _: UFix128, debitBalance _1: UFix128): UFix128 { return self.yearlyRate } } diff --git a/cadence/contracts/FlowALPModels.cdc b/cadence/contracts/FlowALPModels.cdc index 42f60eb5..67945e9a 100644 --- a/cadence/contracts/FlowALPModels.cdc +++ b/cadence/contracts/FlowALPModels.cdc @@ -812,7 +812,7 @@ access(all) contract FlowALPModels { /// Gets a swapper from the DEX for the given token pair. See PoolConfig.getSwapperForLiquidation. access(all) fun getSwapperForLiquidation(seizeType: Type, debtType: Type): {DeFiActions.Swapper} { return self.dex.getSwapper(inType: seizeType, outType: debtType) - ?? panic("No DEX swapper configured for liquidation pair: ".concat(seizeType.identifier).concat(" -> ").concat(debtType.identifier)) + ?? panic("No DEX swapper configured for liquidation pair: \(seizeType.identifier) -> \(debtType.identifier)") } // Setters @@ -2057,7 +2057,7 @@ access(all) contract FlowALPModels { /// Returns an authorized reference to the draw-down sink, or nil if none is configured. access(EImplementation) fun borrowDrawDownSink(): auth(FungibleToken.Withdraw) &{DeFiActions.Sink}? { - return &self.drawDownSink as auth(FungibleToken.Withdraw) &{DeFiActions.Sink}? + return &self.drawDownSink } /// Sets the draw-down sink. Sink must accept MOET deposits, or be nil. @@ -2073,7 +2073,7 @@ access(all) contract FlowALPModels { /// Returns an authorized reference to the top-up source, or nil if none is configured. access(EImplementation) fun borrowTopUpSource(): auth(FungibleToken.Withdraw) &{DeFiActions.Source}? { - return &self.topUpSource as auth(FungibleToken.Withdraw) &{DeFiActions.Source}? + return &self.topUpSource } /// Sets the top-up source. See InternalPosition.setTopUpSource. diff --git a/cadence/contracts/FlowALPPositionResources.cdc b/cadence/contracts/FlowALPPositionResources.cdc index ba406725..4a7404c5 100644 --- a/cadence/contracts/FlowALPPositionResources.cdc +++ b/cadence/contracts/FlowALPPositionResources.cdc @@ -106,7 +106,7 @@ access(all) contract FlowALPPositionResources { } /// Returns the maximum amount of the given token type that could be deposited into this position - access(all) fun getDepositCapacity(type: Type): UFix64 { + access(all) fun getDepositCapacity(type _: Type): UFix64 { // There's no limit on deposits from the position's perspective return UFix64.max } diff --git a/cadence/contracts/FlowALPRebalancerv1.cdc b/cadence/contracts/FlowALPRebalancerv1.cdc index 079b9602..7388cd44 100644 --- a/cadence/contracts/FlowALPRebalancerv1.cdc +++ b/cadence/contracts/FlowALPRebalancerv1.cdc @@ -96,7 +96,7 @@ access(all) contract FlowALPRebalancerv1 { txFunder: {DeFiActions.Sink, DeFiActions.Source} ) { pre { - interval > UInt64(0): + interval > 0: "Invalid interval: \(interval) - must be greater than 0" interval < UInt64(UFix64.max) - UInt64(getCurrentBlock().timestamp): "Invalid interval: \(interval) - must be less than the maximum interval of \(UInt64(UFix64.max) - UInt64(getCurrentBlock().timestamp))" @@ -171,7 +171,7 @@ access(all) contract FlowALPRebalancerv1 { /// @param id: The id of the scheduled transaction /// @param data: The data that was passed when the transaction was originally scheduled /// - access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data: AnyStruct?) { + access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data _: AnyStruct?) { // we want to panic and not keep spending fees on scheduled transactions if borrow fails let positionRebalanceCap = self._positionRebalanceCapability.borrow()! positionRebalanceCap.rebalance(force: self.recurringConfig.getForceRebalance()) diff --git a/cadence/contracts/FlowALPSupervisorv1.cdc b/cadence/contracts/FlowALPSupervisorv1.cdc index 92468569..c8665ae1 100644 --- a/cadence/contracts/FlowALPSupervisorv1.cdc +++ b/cadence/contracts/FlowALPSupervisorv1.cdc @@ -47,7 +47,7 @@ access(all) contract FlowALPSupervisorv1 { /// Scheduler callback: on each tick, call fixReschedule on every registered paid rebalancer, /// recovering any that failed to schedule their next transaction. Stale UUIDs (rebalancer /// deleted without being removed from this set) are pruned automatically. - access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data: AnyStruct?) { + access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data _: AnyStruct?) { emit Executed(id: id) for positionID in self.paidRebalancers.keys { let found = FlowALPRebalancerPaidv1.fixReschedule(positionID: positionID) diff --git a/cadence/contracts/FlowALPv0.cdc b/cadence/contracts/FlowALPv0.cdc index 224bf8e1..17aab380 100644 --- a/cadence/contracts/FlowALPv0.cdc +++ b/cadence/contracts/FlowALPv0.cdc @@ -755,7 +755,7 @@ access(all) contract FlowALPv0 { access(self) fun computeRequiredDepositForHealth( position: &{FlowALPModels.InternalPosition}, depositType: Type, - withdrawType: Type, + withdrawType _: Type, effectiveCollateral: UFix128, effectiveDebt: UFix128, targetHealth: UFix128 @@ -1030,7 +1030,6 @@ access(all) contract FlowALPv0 { // assign issuance & repayment connectors within the InternalPosition let iPos = self._borrowPosition(pid: id) - let fundsType = funds.getType() iPos.setDrawDownSink(issuanceSink) if repaymentSource != nil { iPos.setTopUpSource(repaymentSource) @@ -1044,14 +1043,7 @@ access(all) contract FlowALPv0 { self._rebalancePositionNoLock(pid: id, force: true) } - // Create a capability to the Pool for the Position resource - // The Pool is stored in the FlowALPv0 contract account - let poolCap = FlowALPv0.account.capabilities.storage.issue( - FlowALPv0.PoolStoragePath - ) - // Create and return the Position resource - let position <- FlowALPPositionResources.createPosition(id: id) self.unlockPosition(id) @@ -1402,7 +1394,7 @@ access(all) contract FlowALPv0 { /// Returns a mutable reference to the pool's configuration. /// Use this to update config fields that don't require events or side effects. access(FlowALPModels.EGovernance) fun borrowConfig(): auth(FlowALPModels.EImplementation) &{FlowALPModels.PoolConfig} { - return &self.config as auth(FlowALPModels.EImplementation) &{FlowALPModels.PoolConfig} + return &self.config } /// Pauses the pool, temporarily preventing further withdrawals, deposits, and liquidations @@ -2240,7 +2232,7 @@ access(all) contract FlowALPv0 { ) FlowALPv0.account.storage.save(<-pool, to: FlowALPv0.PoolStoragePath) let cap = FlowALPv0.account.capabilities.storage.issue<&Pool>(FlowALPv0.PoolStoragePath) - FlowALPv0.account.capabilities.unpublish(FlowALPv0.PoolPublicPath) + let _ = FlowALPv0.account.capabilities.unpublish(FlowALPv0.PoolPublicPath) FlowALPv0.account.capabilities.publish(cap, at: FlowALPv0.PoolPublicPath) } } @@ -2282,7 +2274,6 @@ access(all) contract FlowALPv0 { <-create PoolFactory(), to: self.PoolFactoryPath ) - let factory = self.account.storage.borrow<&PoolFactory>(from: self.PoolFactoryPath)! FlowALPPositionResources.setPoolCap(cap: self._borrowPool()) } } diff --git a/cadence/contracts/MOET.cdc b/cadence/contracts/MOET.cdc index edc666f9..06389587 100644 --- a/cadence/contracts/MOET.cdc +++ b/cadence/contracts/MOET.cdc @@ -25,11 +25,11 @@ access(all) contract MOET : FungibleToken { /// and store the returned Vault in their storage in order to allow their /// account to be able to receive deposits of this token type. /// - access(all) fun createEmptyVault(vaultType: Type): @MOET.Vault { + access(all) fun createEmptyVault(vaultType _: Type): @MOET.Vault { return <- create Vault(balance: 0.0) } - access(all) view fun getContractViews(resourceType: Type?): [Type] { + access(all) view fun getContractViews(resourceType _: Type?): [Type] { return [ Type(), Type(), @@ -38,7 +38,7 @@ access(all) contract MOET : FungibleToken { ] } - access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? { + access(all) fun resolveContractView(resourceType _: Type?, viewType: Type): AnyStruct? { switch viewType { case Type(): return FungibleTokenMetadataViews.FTView( diff --git a/cadence/contracts/PriceOracleAggregatorv1.cdc b/cadence/contracts/PriceOracleAggregatorv1.cdc index d7036843..eaa2ad4f 100644 --- a/cadence/contracts/PriceOracleAggregatorv1.cdc +++ b/cadence/contracts/PriceOracleAggregatorv1.cdc @@ -340,7 +340,7 @@ access(all) contract PriceOracleAggregatorv1 { } /// Function called by the scheduler to update the price history. - access(FlowTransactionScheduler.Execute) fun executeTransaction(id: UInt64, data: AnyStruct?) { + access(FlowTransactionScheduler.Execute) fun executeTransaction(id _: UInt64, data _1: AnyStruct?) { let priceOracleAggregator = self.borrowPriceOracleAggregator() priceOracleAggregator.tryAddPriceToHistory() } diff --git a/cadence/contracts/mocks/DummyConnectors.cdc b/cadence/contracts/mocks/DummyConnectors.cdc index d72f62b3..8a7a8b1c 100644 --- a/cadence/contracts/mocks/DummyConnectors.cdc +++ b/cadence/contracts/mocks/DummyConnectors.cdc @@ -22,7 +22,7 @@ access(all) contract DummyConnectors { return UFix64.max } - access(all) fun depositCapacity(from: auth(FungibleToken.Withdraw) &{FungibleToken.Vault}) { + access(all) fun depositCapacity(from _: auth(FungibleToken.Withdraw) &{FungibleToken.Vault}) { // no-op } diff --git a/cadence/contracts/mocks/MockDexSwapper.cdc b/cadence/contracts/mocks/MockDexSwapper.cdc index ab692d70..0601f1cf 100644 --- a/cadence/contracts/mocks/MockDexSwapper.cdc +++ b/cadence/contracts/mocks/MockDexSwapper.cdc @@ -46,7 +46,7 @@ access(all) contract MockDexSwapper { /// Panics if no swapper for the given pair exists. access(all) fun removeMockDEXSwapperForPair(inType: Type, outType: Type) { let swappersForInTypeRef = &self.swappers[inType]! as auth(Mutate) &{Type: Swapper} - swappersForInTypeRef.remove(key: outType) + let _ = swappersForInTypeRef.remove(key: outType) } access(all) struct BasicQuote : DeFiActions.Quote { @@ -117,7 +117,7 @@ access(all) contract MockDexSwapper { return <- src.withdraw(amount: outAmt) } - access(all) fun swapBack(quote: {DeFiActions.Quote}?, residual: @{FungibleToken.Vault}): @{FungibleToken.Vault} { + access(all) fun swapBack(quote _: {DeFiActions.Quote}?, residual: @{FungibleToken.Vault}): @{FungibleToken.Vault} { // Not needed in tests; burn residual and panic to surface misuse Burner.burn(<-residual) panic("MockSwapper.swapBack() not implemented") diff --git a/cadence/contracts/mocks/MockYieldToken.cdc b/cadence/contracts/mocks/MockYieldToken.cdc index e5381918..e8659b17 100644 --- a/cadence/contracts/mocks/MockYieldToken.cdc +++ b/cadence/contracts/mocks/MockYieldToken.cdc @@ -29,11 +29,11 @@ access(all) contract MockYieldToken : FungibleToken { /// and store the returned Vault in their storage in order to allow their /// account to be able to receive deposits of this token type. /// - access(all) fun createEmptyVault(vaultType: Type): @MockYieldToken.Vault { + access(all) fun createEmptyVault(vaultType _: Type): @MockYieldToken.Vault { return <- create Vault(balance: 0.0) } - access(all) view fun getContractViews(resourceType: Type?): [Type] { + access(all) view fun getContractViews(resourceType _: Type?): [Type] { return [ Type(), Type(), @@ -42,7 +42,7 @@ access(all) contract MockYieldToken : FungibleToken { ] } - access(all) fun resolveContractView(resourceType: Type?, viewType: Type): AnyStruct? { + access(all) fun resolveContractView(resourceType _: Type?, viewType: Type): AnyStruct? { switch viewType { case Type(): return FungibleTokenMetadataViews.FTView(