Skip to content

fix: repair fee-anchor lifecycle accounting#428

Draft
carrion256 wants to merge 14 commits into
spr/refactor/vault-ergonomics/4f330057from
audit/fee-anchor-lifecycle-spec
Draft

fix: repair fee-anchor lifecycle accounting#428
carrion256 wants to merge 14 commits into
spr/refactor/vault-ergonomics/4f330057from
audit/fee-anchor-lifecycle-spec

Conversation

@carrion256

@carrion256 carrion256 commented May 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Fixes A-006 / Nexus 6c6f1936-9740-4470-9921-b7ffe2741079: Soroban deposits now advance the fee anchor to post-deposit assets and deposit timestamp.
  • Fixes A-007 / Nexus e95e12c4-99e3-4abf-8188-2c4083600cd9: zero (0,0) fee anchors are treated as uninitialized instead of minting fees against existing supply.
  • Fixes A-015 / Nexus d0261637-ec7c-4abf-b964-b51d18988521: direct underlying transfers are reconciled before pricing so donated idle balance cannot be captured by the next depositor.
  • Fixes A-018 / Nexus 20f09f85-0147-424e-91c3-a9dd6cea1f6e: RefreshFees is reachable through the Soroban command ABI.
  • Fixes A-020 / Nexus 0659bbec-769c-4475-b256-ca22013de56b: ResyncIdleBalance keeps fee_anchor.total_assets and fee_anchor.timestamp_ns coherent, so later fee refreshes use the resync observation time.
  • Fixes A-031 / Nexus 68a5a45d-594c-4565-9b5e-726657416c19: share/asset conversion and fee-mint paths now bound full-width quotients against operation caps before converting to u128.
  • Fixes A-039 / Nexus 21aa4dfa-595b-42a3-a1a0-cf7cba5e3f93: virtual conversion offsets are locked after capitalization / first public deposit, including later full unwind to zero state.

Notes

The first four commits are the original red/spec commits for the audited invariants. The production fixes are kept one commit per Nexus ID for auditor traceability. Commit 3163b84 pins the A-031 red specs; commit 236acee is the A-031 remediation commit.

The Soroban runtime now uses a lazy actual-balance reconciliation policy for preview-sensitive and pricing-sensitive paths. DepositWithMin, RefreshFees, and ResyncIdleBalance read the live asset token balance, reconcile idle assets, recompute total assets, and reset the fee anchor onto the reconciled baseline before continuing. This is documented in contract/vault/soroban/README.md.

A-031 uses bounded-domain math rather than saturation: deposit, withdrawal request planning, atomic withdraw/redeem, fee-share minting, and Soroban proxy_view previews compare the full Number quotient against the operation legal cap before u128 conversion. Overflowing actions fail closed with operation-specific errors; signed ABI previews reject values above i128::MAX.

A-039 is folded into this fee-anchor cluster PR from superseded PR #435. The Soroban runtime now rejects SetGovernanceConfig(VIRTUAL_OFFSETS) while stored vault accounting is nonzero, persists a VirtualOffsetsLocked instance flag after the first successful public deposit, and keeps virtual offsets immutable even after a later full unwind to zero state.

Verification

  • cargo fmt --all -- --check
  • git diff --check
  • CARGO_TARGET_DIR=/data/projects/templar/contracts/.shared-target/fee-anchor-spec cargo test -p templar-vault-kernel --lib -- --nocapture (302 passed)
  • CARGO_TARGET_DIR=/data/projects/templar/contracts/.shared-target/fee-anchor-spec cargo test -p templar-soroban-shared-types -- --nocapture (6 passed)
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/projects/templar/contracts/.shared-target/fee-anchor-spec cargo test -p templar-vault-kernel prop_a031 --test property_tests -- --nocapture (2 passed)
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/projects/templar/contracts/.shared-target/fee-anchor-spec cargo test -p templar-soroban-runtime soroban_contract_resync_idle_balance_anchors_fee_refresh_window --test integration_tests -- --nocapture (1 passed)
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/projects/templar/contracts/.shared-target/fee-anchor-spec cargo test -p templar-soroban-runtime --test integration_tests -- --nocapture (56 passed)
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/projects/templar/contracts/.shared-target/fee-anchor-spec just -f contract/vault/soroban/justfile size-budget-check (passed, deploy wasm 95397 bytes)
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/tmp/contracts-audit-fee-anchor-spec/.target-a039-fold cargo test -p templar-soroban-runtime virtual_offset -- --nocapture (passed)
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/tmp/contracts-audit-fee-anchor-spec/.target-a039-fold cargo test -p templar-soroban-runtime test_phase1_deposit_with_min_resource_probe -- --nocapture (passed)
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/tmp/contracts-audit-fee-anchor-spec/.target-a039-fold cargo test -p templar-soroban-runtime -- --nocapture (passed)
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/tmp/contracts-audit-fee-anchor-spec/.target-a039-fold just -f contract/vault/soroban/justfile size-budget-check (passed, deploy wasm 95716 bytes)

Tracker context: contracts-audit-clusters/fee-anchor-lifecycle.audit.md.

Halborn Finding IDs

Included for Halborn SSC GitHub remediation detection:

  • A-006 / Finding ID 6c6f1936-9740-4470-9921-b7ffe2741079 — Soroban deposits do not advance fee accrual anchor while NEAR does
  • A-007 / Finding ID e95e12c4-99e3-4abf-8188-2c4083600cd9 — Initial fee anchor at zero inflates proxy_view once fees are enabled
  • A-015 / Finding ID d0261637-ec7c-4abf-b964-b51d18988521 — Direct underlying transfers are mispriced until manual resync
  • A-018 / Finding ID 20f09f85-0147-424e-91c3-a9dd6cea1f6e — Fee accrual is unreachable from the deployed Soroban ABI
  • A-020 / Finding ID 0659bbec-769c-4475-b256-ca22013de56bresync_idle_balance advances fee_anchor.total_assets without updating timestamp_ns
  • A-031 / Finding ID 68a5a45d-594c-4565-9b5e-726657416c19 — Share-conversion helpers truncate 256-bit quotients to u128
  • A-039 / Finding ID 21aa4dfa-595b-42a3-a1a0-cf7cba5e3f93 — Virtual conversion offsets can be changed after the vault is capitalized

This change is Reviewable

@coderabbitai

coderabbitai Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f2638f56-cb01-49b5-a989-27da78a19fc4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds kernel bounded conversion helpers with cap enforcement, advances/initializes fee anchors during deposits/refresh, reconciles idle on-ledger asset balances into state, introduces a VaultCommand::RefreshFees path, updates Soroban entrypoints/preview logic to use bounded conversions, and adds unit/property/integration tests.

Changes

Bounded Conversion APIs and Kernel Errors

Layer / File(s) Summary
InvalidStateCode and lib re-exports
contract/vault/kernel/src/error.rs, contract/vault/kernel/src/lib.rs
Adds RequestWithdrawExpectedAssetsExceedTotalAssets and re-exports bounded conversion helpers.
Bounded Conversion Functions and Math Helpers
contract/vault/kernel/src/actions/mod.rs
Four public bounded conversion functions and internal bounded math helpers enforce caps and return specific InvalidStateCode via KernelError.
Mint/Overflow handling
contract/vault/kernel/src/actions/mod.rs
Updates mint_fee_shares/overflow logic to compute remaining capacity and reject shares above it.

Fee Anchor Advancement and Early Initialization

Layer / File(s) Summary
FeeAccrualAnchor Uninitialized Check
contract/vault/kernel/src/state/vault/mod.rs
Adds is_uninitialized() const method.
Deposit Handler Fee Anchor Updates
contract/vault/kernel/src/actions/mod.rs
handle_deposit now accepts now_ns, uses bounded share conversion with remaining-share cap, and initializes state.fee_anchor after updating totals.
Dispatcher Timestamp Forwarding
contract/vault/kernel/src/actions/mod.rs
Dispatcher forwards now_ns for Deposit and AtomicWithdraw.
Fee Refresh Early-Return
contract/vault/kernel/src/actions/mod.rs
handle_refresh_fees initializes uninitialized anchors when appropriate and emits FeesRefreshed without performing full accrual when applicable.

Withdrawal and Redemption with Bounded Conversions

Layer / File(s) Summary
Withdrawal Request Bounded Assets Conversion
contract/vault/kernel/src/actions/mod.rs
plan_withdrawal_request uses convert_to_assets_bounded capped by state.total_assets.
Atomic Withdraw and Redeem Bounded Conversions
contract/vault/kernel/src/actions/mod.rs
Atomic withdraw uses convert_to_shares_ceil_bounded with remaining-share cap; redeem uses convert_to_assets_bounded with idle_assets cap.
Kernel test updates
contract/vault/kernel/src/actions/tests.rs, contract/vault/kernel/tests/property_tests.rs
Adds deposit tests for zero-share rejection and fee-anchor advancement; updates property tests for fee-minting overflow and deposit boundary cases.

Virtual Offsets Locking Infrastructure

Layer / File(s) Summary
Virtual Offsets Locked Storage and Helpers
contract/vault/soroban/src/contract/types.rs, contract/vault/soroban/src/contract/helpers.rs
Adds VaultDataKey::VirtualOffsetsLocked and helpers virtual_offsets_locked() / lock_virtual_offsets().
Governance validation and deposit locking
contract/vault/soroban/src/contract/entrypoints.rs
Rejects virtual-offset changes when vault is capitalized or offsets locked; deposit_with_min locks virtual offsets after first capitalization.

Idle Asset Reconciliation Against Live Token Balance

Layer / File(s) Summary
Idle Asset Reconciliation and State Loading
contract/vault/soroban/src/fungible_vault.rs, contract/vault/soroban/src/contract/entrypoints.rs
Adds reconcile_actual_idle_assets to read actual token balance, update idle_assets, sync totals, and refresh fee_anchor; load_state_and_config calls reconciliation.
Preview and uninitialized anchor handling
contract/vault/soroban/src/fungible_vault.rs
preview_state_with_fee_accrual early-returns for zero shares and initializes uninitialized anchors before time-window accrual.
Resync integration
contract/vault/soroban/src/contract/entrypoints.rs
resync_idle_balance_impl delegates to reconcile helper; adds while-idle variant used by admin flows.

RefreshFees Command Architecture

Layer / File(s) Summary
RefreshFees Command Codec
contract/vault/soroban/shared-types/src/lib.rs
Adds VaultCommand::RefreshFees with encode/decode and test coverage.
CuratorVault RefreshFees Entry Point
contract/vault/soroban/src/contract/curator_vault.rs
CuratorVault::refresh_fees() applies KernelAction::RefreshFees.
RefreshFees Entrypoint Implementation
contract/vault/soroban/src/contract/entrypoints.rs
refresh_fees_impl() reconciles idle assets then conditionally calls vault.refresh_fees(now_ns); wired into public dispatcher.

Proxy View Bounded Conversion Updates

Layer / File(s) Summary
Proxy View Conversion Logic
contract/vault/soroban/src/contract/entrypoints.rs
Replaces unbounded conversions with bounded/ceil-bounded helpers; maps conversion failures to ContractError::ConversionOverflow; updates max mint/redeem and preview calculations accordingly.
Module import updates
contract/vault/soroban/src/contract/mod.rs
Imports reconcile_actual_idle_assets, bounded conversion helpers, and InvalidStateCode.

Property Tests, Documentation, and Integration Test Setup

Layer / File(s) Summary
Property Tests for fee minting and deposit boundaries
contract/vault/kernel/tests/property_tests.rs
Updates "Property 45a / A-031" and adds "Property 45b / A-031" for deposit mint boundary.
Fee Anchor and Idle Balance Accounting README
contract/vault/soroban/README.md
Documents idle-asset reconciliation, fee-anchor anchoring, and lazy reconciliation during state-changing operations.
Integration fixtures and tests
contract/vault/soroban/tests/integration_tests.rs
Extends fixture with asset_token, mints assets in tests before preview/assertions, adds RefreshFees and donation/resync tests, and strengthens stored-state assertions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • peer2f00l
  • SmolinPavel
  • royalf00l
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 73.42% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: repair fee-anchor lifecycle accounting' clearly and specifically identifies the main focus of the changeset: repairing fee-anchor lifecycle accounting to address multiple related Halborn findings.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining the fixes for specific Halborn findings (A-006 through A-039), implementation approach, and verification steps performed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch audit/fee-anchor-lifecycle-spec

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • LINEAR integration encountered authorization issues. Please disconnect and reconnect the integration in the CodeRabbit UI.

Comment @coderabbitai help to get the list of available commands and usage tips.

@carrion256

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
contract/vault/kernel/src/actions/mod.rs (1)

732-758: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Reject zero-share deposits before mutating state.

A nonzero assets_in can still floor to shares_out == 0 here. In that case the vault will pull assets, increase total_assets/idle_assets, advance the fee anchor, and mint nothing to the receiver. That is a user-funds loss path on small deposits against a high share price.

🐛 Proposed fix
     let shares_out = convert_to_shares_bounded(
         &state,
         config,
         assets_in,
         u128::MAX.saturating_sub(state.total_shares),
         InvalidStateCode::MintOverflowTotalShares,
     )?;
+    if shares_out == 0 {
+        return Err(KernelError::ZeroAmount);
+    }
     if shares_out < min_shares_out {
         return Err(KernelError::Slippage {
             min: min_shares_out,
             actual: shares_out,
         });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@contract/vault/kernel/src/actions/mod.rs` around lines 732 - 758, After
computing shares_out via convert_to_shares_bounded, add an early check that
rejects zero-share deposits before mutating state: if shares_out == 0 return an
error (e.g., KernelError::Slippage { min: min_shares_out, actual: shares_out })
so we never update state.total_assets, state.idle_assets, state.total_shares or
advance FeeAccrualAnchor::new when a nonzero assets_in would mint zero shares;
place this check immediately after the convert_to_shares_bounded call and before
any checked_add mutations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@contract/vault/soroban/src/contract/entrypoints.rs`:
- Around line 406-413: refresh_fees_impl currently reconciles idle assets via
reconcile_current_idle_assets(env, vault, now_ns) which may update
fee_anchor.timestamp_ns to now_ns and then calls vault.refresh_fees(now_ns),
causing FeeRefreshTimestampMustAdvance to trigger; fix by checking whether
reconcile_current_idle_assets advanced the fee anchor to now_ns (compare
pre-reconcile fee_anchor.timestamp_ns with post-reconcile value) and if it did,
skip calling vault.refresh_fees(now_ns) (or instead call refresh_fees with the
preserved pre-reconcile timestamp) so the FeeRefreshTimestampMustAdvance path is
avoided; locate this logic in refresh_fees_impl and use
with_contract_vault_contract_error and ContractVault methods to read/preserve
fee_anchor.timestamp_ns around the reconciliation call.

In `@contract/vault/soroban/tests/integration_tests.rs`:
- Around line 1862-1865: The current assertion only enforces an upper bound on
minted_shares and would allow minted_shares == 0 to slip by; update the test
around the minted_shares check (the assertion that currently verifies
minted_shares <= 62) to also assert a positive lower bound (e.g., minted_shares
>= 1) so the test enforces that a nonzero payment yields nonzero shares while
still preventing surplus capture; keep the failure message clear and reference
minted_shares in the message.

---

Outside diff comments:
In `@contract/vault/kernel/src/actions/mod.rs`:
- Around line 732-758: After computing shares_out via convert_to_shares_bounded,
add an early check that rejects zero-share deposits before mutating state: if
shares_out == 0 return an error (e.g., KernelError::Slippage { min:
min_shares_out, actual: shares_out }) so we never update state.total_assets,
state.idle_assets, state.total_shares or advance FeeAccrualAnchor::new when a
nonzero assets_in would mint zero shares; place this check immediately after the
convert_to_shares_bounded call and before any checked_add mutations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9befdd90-2370-4733-b7d9-515556c96d0e

📥 Commits

Reviewing files that changed from the base of the PR and between a657f92 and ba08a36.

📒 Files selected for processing (16)
  • contract/vault/kernel/src/actions/mod.rs
  • contract/vault/kernel/src/actions/tests.rs
  • contract/vault/kernel/src/error.rs
  • contract/vault/kernel/src/lib.rs
  • contract/vault/kernel/src/state/vault/mod.rs
  • contract/vault/kernel/tests/property_tests.rs
  • contract/vault/soroban/README.md
  • contract/vault/soroban/shared-types/src/lib.rs
  • contract/vault/soroban/src/contract/curator_vault.rs
  • contract/vault/soroban/src/contract/entrypoints.rs
  • contract/vault/soroban/src/contract/helpers.rs
  • contract/vault/soroban/src/contract/mod.rs
  • contract/vault/soroban/src/contract/types.rs
  • contract/vault/soroban/src/fungible_vault.rs
  • contract/vault/soroban/src/tests.rs
  • contract/vault/soroban/tests/integration_tests.rs

Comment thread contract/vault/soroban/src/contract/entrypoints.rs
Comment thread contract/vault/soroban/tests/integration_tests.rs
@carrion256

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
contract/vault/soroban/tests/integration_tests.rs (1)

1862-1865: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Assert the exact post-donation mint here.

(1..=62) still lets severe under-minting regressions pass. In this setup the result is deterministic: after reconciling to 800 assets, a 100-asset deposit against 500 shares should mint exactly 62 shares, so this should be an equality assertion instead of a range.

Suggested patch
-    assert!(
-        (1..=62).contains(&minted_shares),
-        "deposit minted {minted_shares} shares outside expected post-donation bounds"
-    );
+    assert_eq!(
+        minted_shares, 62,
+        "deposit minted {minted_shares} shares instead of pricing against the reconciled donated NAV"
+    );
As per coding guidelines, "`**/tests/**/*.rs`: Write comprehensive unit tests for new, non-trivial Rust logic; prefer `#[rstest]` parameterization when it improves coverage and keeps cases readable`".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@contract/vault/soroban/tests/integration_tests.rs` around lines 1862 - 1865,
The test currently uses a range assertion for minted_shares which allows
under-minting to pass; replace the loose range check with an exact equality
assertion (assert_eq!(minted_shares, 62)) so the test verifies the deterministic
outcome after reconciling to 800 assets and depositing 100 assets against 500
shares; update any failure message accordingly to reflect the expected exact
value and keep the assertion referencing the minted_shares variable.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@contract/vault/soroban/tests/integration_tests.rs`:
- Around line 1862-1865: The test currently uses a range assertion for
minted_shares which allows under-minting to pass; replace the loose range check
with an exact equality assertion (assert_eq!(minted_shares, 62)) so the test
verifies the deterministic outcome after reconciling to 800 assets and
depositing 100 assets against 500 shares; update any failure message accordingly
to reflect the expected exact value and keep the assertion referencing the
minted_shares variable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d036ebe8-aa3f-495c-bf99-3a30dccd8832

📥 Commits

Reviewing files that changed from the base of the PR and between ba08a36 and 8b940a2.

📒 Files selected for processing (4)
  • contract/vault/kernel/src/actions/mod.rs
  • contract/vault/kernel/src/actions/tests.rs
  • contract/vault/soroban/src/contract/entrypoints.rs
  • contract/vault/soroban/tests/integration_tests.rs

carrion256 added 13 commits May 19, 2026 10:27
…8 Nexus 20f09f85-0147-424e-91c3-a9dd6cea1f6e Nexus d0261637-ec7c-4abf-b964-b51d18988521 Nexus 68a5a45d-594c-4565-9b5e-726657416c19)
@carrion256 carrion256 force-pushed the audit/fee-anchor-lifecycle-spec branch from 8b940a2 to 3c4abaf Compare May 19, 2026 08:28
…9 Nexus ca9eb389-f5c4-41b6-88cb-57ba837928f4 Nexus fb2a0ba4-33cc-48b2-98bc-1f090dfa0391 Nexus 16754f09-e5da-4838-81d9-1ded6598f171)

Normalize legacy zero fee anchors during migration, make zero-anchor donation growth non-feeable until the anchor is advanced, and replace unchecked fee-policy account indexing with checked input validation.

Verification: cargo fmt --all; CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/tmp/contracts-fee-a021-target cargo test -p templar-vault-kernel refresh_fees_zero_anchor_excludes_uncapped_donation_growth -- --nocapture; CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/tmp/contracts-fee-a021-target cargo test -p templar-soroban-runtime soroban_contract_proxy_view_does_not_inflate_from_zero_fee_anchor -- --nocapture; CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/tmp/contracts-fee-a021-target cargo test -p templar-soroban-runtime soroban_contract_refresh_fees_command_updates_anchor -- --nocapture; git diff --check.
@carrion256 carrion256 force-pushed the audit/fee-anchor-lifecycle-spec branch from acfd8e7 to aeba3fc Compare May 22, 2026 10:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant