Skip to content

fix: harden adapter accounting and Blend admin boundary#431

Draft
carrion256 wants to merge 6 commits into
spr/refactor/vault-ergonomics/4f330057from
audit/adapter-accounting-a032
Draft

fix: harden adapter accounting and Blend admin boundary#431
carrion256 wants to merge 6 commits into
spr/refactor/vault-ergonomics/4f330057from
audit/adapter-accounting-a032

Conversation

@carrion256

@carrion256 carrion256 commented May 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

Consolidated adapter follow-up PR for the tracker-defined adapter-accounting-and-blend-admin boundary. This supersedes the previously split draft PRs #433, #434, #438, and #439.

Findings covered:

Local / Nexus finding Remediation
A-032 / Nexus 0c991b9f-9a55-4006-b3fc-e5af3fbb7605 Verify adapter withdrawal reports against the vault asset-token balance delta before mutating kernel accounting.
A-033 / Nexus bc013b77-b8a9-4b9a-867a-228152a95c3b Validate adapter-reported external asset observations at the Soroban runtime policy boundary before kernel sync.
A-034 / Nexus 76f200c7-618d-4fd1-bff3-109530b96144 Remove Blend adapter admin accounting shortcuts (supply_balance, withdraw_to_vault) so managed positions mutate only through the vault-routed lifecycle.
A-035 / Nexus 81068879-6d1a-460a-b176-bc982fb254cd Remove undeployed Blend adapter mutable retarget ABI (set_pool, set_vault) and stale retarget events/recipes.
A-060 / Nexus 6a5a3ec7-5477-4c2f-9488-30308ab956d6 Require constructor-bound Blend adapter admin/vault/pool addresses to be contract addresses before config persistence.

Tracker / PR boundary note

The audit tracker's adapter-identity-and-governance cluster calls for a single follow-up PR boundary named adapter-accounting-and-blend-admin for A-032/A-033/A-034/A-035 plus A-060 if accepted. This PR is now that consolidated boundary.

Superseded split PRs:

Verification

  • cargo fmt --all -- --check
  • git diff --check
  • source-shape sweep found no public Blend adapter set_pool, set_vault, supply_balance, withdraw_to_vault, pool_upd, or vlt_upd symbols
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/tmp/contracts-adapter-consolidated/.target-consolidated cargo test -p templar-soroban-blend-adapter -- --nocapture — 16 unit + 7 integration passed
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/tmp/contracts-adapter-consolidated/.target-consolidated cargo test -p templar-soroban-runtime --features testutils complete_refresh -- --nocapture — 3 runtime tests + 1 property-filtered test passed
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/tmp/contracts-adapter-consolidated/.target-consolidated cargo test -p templar-soroban-runtime --test blend_e2e withdraw_allocation_rejects_adapter_reported_assets_without_matching_balance_delta -- --nocapture — 1 passed
  • CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/data/tmp/contracts-adapter-consolidated/.target-consolidated cargo test -p templar-vault-kernel sync_external_assets -- --nocapture — 10 unit + 1 property-filtered test passed
  • post-commit Soroban size-budget-check hook passed on consolidated commits at 95908 bytes

This change is Reviewable

@coderabbitai

coderabbitai Bot commented May 14, 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: ba29649a-3853-46d7-9f57-fc7b081a9625

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

This PR refactors vault validation logic across kernel and Soroban layers. It removes the kernel's conservative "would more than double total assets" check and replaces it with operation-state-gated validation. The Blend adapter constructor now validates that admin, vault, and pool are contract addresses. Vault allocations and refreshes now stage principal updates and validate bounds before committing. Token balance verification in withdrawals ensures reported deltas match actual balance changes. Comprehensive tests validate both kernel behavior and end-to-end adapter interactions.

Changes

Vault validation and asset sync refactoring

Layer / File(s) Summary
Kernel external asset sync validation refactor
contract/vault/kernel/src/actions/mod.rs, contract/vault/kernel/src/error.rs, contract/vault/kernel/src/actions/tests.rs, contract/vault/kernel/tests/property_tests.rs
Removes the "would more than double total assets" check from plan_external_asset_sync and replaces sync_external_in_flight_assets with ensure_sync_external_state_allowed that gates syncing to Allocating, Withdrawing, or Refreshing states. Removes SyncExternalWouldMoreThanDoubleTotalAssets error variant. Action tests updated to verify new in-flight allocation bounds; property test refactored to model syncing from partially-updated vault state.
Blend adapter constructor validation and cleanup
contract/vault/soroban/blend-adapter/src/lib.rs, contract/vault/soroban/blend-adapter/tests/integration_tests.rs, contract/vault/soroban/justfile
Constructor now returns Result<(), AdapterError>, validates admin, vault, and pool are contract addresses before storing. Removes deprecated supply_balance and withdraw_to_vault admin-only entrypoints. Tests refactored to use DummyContract registration for valid contract addresses. Removes blend-adapter-set-pool and blend-adapter-set-vault recipes from justfile.
Vault allocation and refresh operation validation with staging
contract/vault/soroban/src/contract/curator_vault.rs, contract/vault/soroban/src/contract/entrypoints.rs, contract/vault/soroban/src/tests.rs
Supply and refresh completion now stage principal updates on cloned PolicyState, validate observed totals against principal bounds or market caps, sync external assets from staged policy, and commit if valid. Added balance delta verification in withdrawal allocations: checks token balance change matches realized amount. New unit tests verify allocation rejects over-reported supply, refresh rejects inflation beyond cap, and refresh accepts valid decreases.
End-to-end validation with misbehaving adapter tests
contract/vault/soroban/tests/blend_e2e.rs
Introduces OverreportingAdapter contract that reports inflated assets without matching balance changes. New e2e test verifies withdrawal allocation is rejected when adapter over-reports, leaving vault balances and snapshots unchanged.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

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

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.92% 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 clearly summarizes the main changes: hardening adapter accounting and removing Blend admin boundaries as described throughout the changeset.
Description check ✅ Passed The description provides detailed context about the PR, covering the consolidated boundary, mapped audit findings, remediations, 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/adapter-accounting-a032

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 carrion256 changed the title fix: verify adapter withdrawal balance delta fix: harden adapter accounting and Blend admin boundary May 18, 2026
@carrion256 carrion256 force-pushed the audit/adapter-accounting-a032 branch from e951f6f to 10806a4 Compare May 18, 2026 14:43
@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

🤖 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/kernel/tests/property_tests.rs`:
- Around line 3818-3824: The property test currently limits delta by calling
delta.min(in_flight), which re-introduces the old in-flight cap and prevents
exercising larger valid sync updates; remove that cap by not clamping delta to
in_flight (i.e., stop using delta.min(in_flight)) so delta can exceed in_flight
in generated cases and compute external = existing_external + delta as intended;
update the generator variables (existing_external, in_flight, delta) and
subsequent assertions in the test around VaultState::new and any uses of
in_flight to ensure the test logic expects delta > in_flight scenarios.

In `@contract/vault/soroban/blend-adapter/src/lib.rs`:
- Around line 55-64: The constructor currently validates addresses using
string-prefix-based is_contract_address; replace that with payload-based checks
by calling AddressPayload::from_address(&address) and pattern-matching for
AddressPayload::ContractIdHash to determine contract addresses, and return
AdapterError::InvalidInput via require_contract_address (or update that helper
to use AddressPayload::from_address) for admin, vault, and pool in __constructor
so validation relies on AddressPayload rather than to_string()/byte-prefix
inspection.
🪄 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: cab4b0d8-cf13-4999-adc6-144c884042d1

📥 Commits

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

📒 Files selected for processing (11)
  • contract/vault/kernel/src/actions/mod.rs
  • contract/vault/kernel/src/actions/tests.rs
  • contract/vault/kernel/src/error.rs
  • contract/vault/kernel/tests/property_tests.rs
  • contract/vault/soroban/blend-adapter/src/lib.rs
  • contract/vault/soroban/blend-adapter/tests/integration_tests.rs
  • contract/vault/soroban/justfile
  • contract/vault/soroban/src/contract/curator_vault.rs
  • contract/vault/soroban/src/contract/entrypoints.rs
  • contract/vault/soroban/src/tests.rs
  • contract/vault/soroban/tests/blend_e2e.rs
💤 Files with no reviewable changes (3)
  • contract/vault/soroban/justfile
  • contract/vault/kernel/src/actions/mod.rs
  • contract/vault/kernel/src/error.rs

Comment thread contract/vault/kernel/tests/property_tests.rs
Comment thread contract/vault/soroban/blend-adapter/src/lib.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.

…3ec7-5477-4c2f-9488-30308ab956d6)

Use Soroban AddressPayload for Blend adapter contract-address discrimination instead of parsing address strings, and keep the external-asset sync property from clamping generated deltas to in-flight allocation amounts.

Verification:

- cargo fmt --check

- cargo test -p templar-soroban-blend-adapter -- --nocapture

- cargo test -p templar-vault-kernel --test property_tests --features action-sync-external prop_spec_sync_external_assets_updates_total -- --nocapture
@carrion256 carrion256 force-pushed the audit/adapter-accounting-a032 branch from da34b37 to 4193c59 Compare May 19, 2026 08:28
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