Skip to content

Add withdraw_all convenience function to vault contract - #79

Open
mxrtins04 wants to merge 1 commit into
clevercon-protocol:mainfrom
mxrtins04:feat/withdraw-all
Open

Add withdraw_all convenience function to vault contract#79
mxrtins04 wants to merge 1 commit into
clevercon-protocol:mainfrom
mxrtins04:feat/withdraw-all

Conversation

@mxrtins04

@mxrtins04 mxrtins04 commented Jul 24, 2026

Copy link
Copy Markdown

closes #67

What changed

Adds withdraw_all(user, asset) to the vault contract. Computes the withdrawable amount (balance - locked) on-chain and withdraws it in a single call, removing the race where a task completes between an off-chain get_available read and the withdraw call. Reuses withdraw internally, so the existing locked guard, WithdrawEvent, TTL bumps, and logging all apply unchanged.

Files added/modified

  • contracts/agent-vault/src/lib.rs — added withdraw_all(env, user, asset)
  • contracts/agent-vault/src/tests.rs — added test_withdraw_all_full_withdrawal, test_withdraw_all_with_some_funds_locked, test_withdraw_all_nothing_available_fails

Security / rollback notes

  • Requires user.require_auth() before any storage read, same auth boundary as withdraw.
  • Withdraws exactly balance - locked; locked funds are left untouched, a subsequent task completion still refunds correctly.
  • Returns InsufficientAvailable when nothing is withdrawable (zero balance or fully locked).
  • Purely additive: reuses withdraw's existing logic, event, and TTL handling rather than duplicating it.
  • cargo test passes. cargo clippy --all-targets -- -D warnings should be verified before merge (hit a local toolchain issue during implementation, not a code issue).
  • Rollback is a single revert of this PR; no storage schema changes.

Summary by CodeRabbit

  • New Features
    • Added a “withdraw all available” option for assets in the vault.
    • Withdrawals automatically exclude funds currently locked by active tasks.
    • Clear errors are provided when no account or withdrawable balance is available.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds withdraw_all to calculate and withdraw a user’s available asset balance on-chain, returning appropriate errors when no account or available funds exist. Tests cover full withdrawals, locked funds, subsequent unlocking, and failure cases.

Changes

Withdraw All

Layer / File(s) Summary
Available-balance withdrawal method
contracts/agent-vault/src/lib.rs
Adds withdraw_all, computes balance - locked, returns typed errors for unavailable funds, and delegates successful transfers to withdraw.
Withdrawal behavior validation
contracts/agent-vault/src/tests.rs
Tests full withdrawal, withdrawal with locked funds, post-task unlocking, and unavailable-balance errors.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers: dopezapha, yerimahoftimes, tijesunimi004

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: adding a withdraw_all convenience function to the vault contract.
Linked Issues check ✅ Passed The changes add withdraw_all, reuse withdraw, return the withdrawn amount, and include the requested full, partial, and no-balance tests.
Out of Scope Changes check ✅ Passed The diff appears limited to the new withdraw_all method and its tests, with no unrelated code changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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 `@contracts/agent-vault/src/lib.rs`:
- Around line 484-489: Update the insufficient-available branch in withdraw so
the UserAsset storage entry identified by asset_key has its TTL refreshed before
returning VaultError::InsufficientAvailable. Reuse the same TTL-refresh behavior
used by the successful withdrawal path, while preserving the existing balance
validation and error result.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f5d63d9c-dbec-43c2-b8ce-06c85488dcdd

📥 Commits

Reviewing files that changed from the base of the PR and between dc27886 and 8afcde6.

📒 Files selected for processing (2)
  • contracts/agent-vault/src/lib.rs
  • contracts/agent-vault/src/tests.rs

Comment on lines +484 to +489
let asset_key = DataKey::UserAsset(user.clone(), asset.clone());
let account: UserAssetAccount = env.storage().persistent()
.get(&asset_key).ok_or(VaultError::InsufficientBalance)?;
let available = account.balance - account.locked;
if available <= 0 {
return Err(VaultError::InsufficientAvailable);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Refresh the asset-account TTL before the early error.

When available <= 0, this returns before withdraw refreshes DataKey::UserAsset. Repeated failed withdraw_all calls can therefore leave an otherwise active account to expire.

Proposed fix
         let account: UserAssetAccount = env.storage().persistent()
             .get(&asset_key).ok_or(VaultError::InsufficientBalance)?;
+        Self::extend_persistent_ttl(&env, &asset_key);
         let available = account.balance - account.locked;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let asset_key = DataKey::UserAsset(user.clone(), asset.clone());
let account: UserAssetAccount = env.storage().persistent()
.get(&asset_key).ok_or(VaultError::InsufficientBalance)?;
let available = account.balance - account.locked;
if available <= 0 {
return Err(VaultError::InsufficientAvailable);
let asset_key = DataKey::UserAsset(user.clone(), asset.clone());
let account: UserAssetAccount = env.storage().persistent()
.get(&asset_key).ok_or(VaultError::InsufficientBalance)?;
Self::extend_persistent_ttl(&env, &asset_key);
let available = account.balance - account.locked;
if available <= 0 {
return Err(VaultError::InsufficientAvailable);
🤖 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 `@contracts/agent-vault/src/lib.rs` around lines 484 - 489, Update the
insufficient-available branch in withdraw so the UserAsset storage entry
identified by asset_key has its TTL refreshed before returning
VaultError::InsufficientAvailable. Reuse the same TTL-refresh behavior used by
the successful withdrawal path, while preserving the existing balance validation
and error result.

@Bosun-Josh121

Copy link
Copy Markdown
Collaborator

LGTM @mxrtins04 . Just fix the CI fails

@Bosun-Josh121

Copy link
Copy Markdown
Collaborator

@mxrtins04 please fix CI

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.

[Task]: Add a withdraw_all(user, asset) convenience function

2 participants