---
title: "6. Vault and Resource Patterns"
path: "/developers/scrypto/06-vault-patterns"
version: "1.2.0"
author: "Hydrate"
createdAt: "2026-02-19T06:44:48.961Z"
updatedAt: "2026-03-16T18:26:10.394Z"
---

# 6. Vault and Resource Patterns

<Infobox>
| **Vault & Resource Patterns** |
| Pattern Type | Resource Management |
| Difficulty | Beginner |
| Concepts | [Buckets, Proofs & Vaults](/contents/tech/core-concepts/buckets-proofs-and-vaults) |
| Official Docs | [Vaults and Buckets](https://docs.radixdlt.com/docs/buckets-and-vaults) |
</Infobox>

## Introduction

Radix enforces a strict invariant: every [resource](/contents/tech/core-concepts/asset-oriented-programming) must exist inside a container at all times. There are two container types: **[Vaults](https://docs.radixdlt.com/docs/buckets-and-vaults)** (permanent, on-ledger storage) and **[Buckets](https://docs.radixdlt.com/docs/resources-and-data)** (temporary, transaction-scoped carriers). The [Radix Engine](/contents/tech/core-protocols/radix-engine) guarantees that resources cannot be duplicated, accidentally destroyed, or left in limbo — if your transaction ends with an undeposited bucket, it fails. This "physical resource" model eliminates entire categories of bugs common in other smart contract platforms.

## Vault Patterns

### Single-Vault Component

The simplest pattern: a component holds one vault to store a single resource type. A token sale component, for example, stores tokens in a vault and returns XRD payment to the buyer's account.

```
struct TokenSale {
    token_vault: Vault,    // holds tokens for sale
    xrd_vault: Vault,      // collects XRD payments
    price: Decimal,
}
```

### Multi-Vault Component (HashMap)

When a component needs to manage arbitrary resource types (e.g. a DEX liquidity pool or a wallet-like component), use a `HashMap<ResourceAddress, Vault>`. When a new resource type is deposited, create a new vault; when an existing type arrives, deposit into the matching vault.

```
struct MultiVault {
    [vaults](https://docs.radixdlt.com/docs/resources-and-data): HashMap<ResourceAddress, Vault>,
}

impl MultiVault {
    pub fn deposit(&mut self, bucket: Bucket) {
        let addr = bucket.resource_address();
        self.[vaults](https://docs.radixdlt.com/docs/buckets-and-vaults)
            .entry(addr)
            .or_insert_with(|| Vault::new(addr))
            .put(bucket);
    }
}
```

### Vault Take & Put

Withdraw resources from a vault with `.take(amount)` (returns a Bucket) or `.take_all()`. Deposit with `.put(bucket)`. For non-fungibles, use `.take_non_fungible(&id)` or `.take_non_fungibles(&ids)` to withdraw specific items.

## Bucket Patterns

### Bucket Passing (Move Semantics)

[Buckets](https://docs.radixdlt.com/docs/resources-and-data) use Rust's ownership model — passing a bucket to a function *moves* it. The caller no longer has access. This prevents double-spending at the language level:

```
// Caller creates a bucket, passes it to the component
let payment: Bucket = account.withdraw(xrd_address, dec!("100"));
let tokens: Bucket = sale_component.buy(payment);
// 'payment' is now consumed — cannot be used again
account.deposit(tokens);
```

### Bucket Splitting

Use `.take(amount)` on a bucket to split it into two buckets — the original retains the remainder. This is how you implement partial fills, fee extraction, or distributing resources across multiple destinations within a single transaction.

### The Worktop

In [transaction manifests](/contents/tech/core-protocols/transaction-manifests), returned resources land on the **worktop** — a temporary staging area. Use `TAKE_FROM_WORKTOP` to create named buckets from worktop resources, then pass them to subsequent method calls. The transaction fails if any resources remain on the worktop at the end.

## External Links

- [Vaults and Buckets — Official Docs](https://docs.radixdlt.com/docs/buckets-and-vaults)

- [Resources — Official Docs](https://docs.radixdlt.com/docs/resources)

- [Regulated Token Example — Official Docs](https://docs-babylon.radixdlt.com/main/scrypto/examples/regulated-token.html)