Skip to content

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

Description

@grantfox-oss

To fully exit an asset today, a user must first read their available balance (get_available) off-chain and then submit a withdraw for that exact amount. This is a race: if a task completes between the read and the withdraw, the available balance changes and the user either leaves dust behind or over-requests and reverts with InsufficientAvailable.

Add a withdraw_all that computes the withdrawable amount on-chain and transfers exactly the unlocked portion in a single call:

pub fn withdraw_all(env: Env, user: Address, asset: Address) -> Result<i128, VaultError> {
    user.require_auth();
    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);
    }
    Self::withdraw(env, user, asset, available)?; // reuse existing logic + event
    Ok(available)
}

Reusing withdraw means the existing per-asset locked guard, the WithdrawEvent, TTL bumps, and logging all apply unchanged — this function is purely a safe "max" wrapper. It returns the amount withdrawn so the caller can display it.

Acceptance criteria

  • withdraw_all(env, user, asset) -> Result<i128, VaultError> withdraws exactly balance - locked for that asset
  • Returns the amount withdrawn
  • Errors with InsufficientAvailable when nothing is withdrawable (all locked or zero balance)
  • Leaves locked funds untouched; a subsequent task completion still refunds correctly
  • Emits WithdrawEvent (via reuse of withdraw)
  • Tests cover: full withdrawal, withdrawal with some funds locked, and the nothing-available case
  • cargo test and cargo clippy --all-targets -- -D warnings pass

Relevant files

  • contracts/agent-vault/src/lib.rs (new function reusing withdraw)
  • contracts/agent-vault/src/tests.rs

Notes for contributors

If you'd like to work on this, comment below so we can assign it to you.
Questions welcome — see CONTRIBUTING.md for setup
and workflow.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions