Skip to content
Back to skills

Balancer V3 Architecture

ASecurity

This skill should be used when the user asks about "Balancer V3 architecture", "Vault design", "transient accounting", "unlock pattern", "credit/debt system", "Balancer V3 overview", or needs high-level understanding of how Balancer V3 works.

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 10, 2026
business

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 10, 2026

npx -y skills add cyotee/indexedex --skill balancer-v3-architecture --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Balancer V3 Architecture?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Balancer V3 Architecture
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/cyotee-balancer-v3-architecture/badge)](https://www.skillsdirectory.com/skills/cyotee-balancer-v3-architecture)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: Balancer V3 Architecture
description: This skill should be used when the user asks about "Balancer V3 architecture", "Vault design", "transient accounting", "unlock pattern", "credit/debt system", "Balancer V3 overview", or needs high-level understanding of how Balancer V3 works.
version: 0.1.0
---

# Balancer V3 Architecture Overview

Balancer V3 is a complete rewrite of the Balancer protocol, featuring a singleton Vault design with transient accounting for gas-efficient operations.

## Core Architecture

### Singleton Vault Pattern

All liquidity in Balancer V3 is managed by a single Vault contract:

```
┌─────────────────────────────────────────────────────────────┐
│                         VAULT                               │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐           │
│  │   Pool A    │ │   Pool B    │ │   Pool C    │           │
│  │  (Weighted) │ │   (Stable)  │ │   (Custom)  │           │
│  └─────────────┘ └─────────────┘ └─────────────┘           │
│                                                              │
│  Token Reserves: All ERC20 balances held centrally          │
│  Pool Accounting: Per-pool balance tracking                 │
└─────────────────────────────────────────────────────────────┘
```

### Contract Hierarchy

| Contract | Purpose |
|----------|---------|
| **Vault** | Main entry point. Core swap/liquidity operations. Inherits VaultCommon + Proxy pattern. |
| **VaultExtension** | Less frequently used functions (pool registration, queries). Delegate-called via Proxy. |
| **VaultAdmin** | Permissioned administrative functions. |
| **Router** | User-facing entry point. Handles ETH, Permit2, unlocking. |

### Key Design Principles

1. **Transient Accounting**: Tokens aren't transferred during operation - only deltas tracked
2. **Unlock Pattern**: All operations happen within an `unlock()` callback
3. **Pools as External Contracts**: Pools contain only math logic, no token balances
4. **Hooks**: Extensibility via optional hook contracts per pool

## Transient Accounting Model

Instead of transferring tokens on each swap, V3 tracks credits and debts:

```solidity
// During an unlock session:
// 1. Operations create credits (tokens owed TO user) and debts (tokens owed BY user)
// 2. At session end, all deltas must net to zero
// 3. Only then do actual token transfers occur

function unlock(bytes calldata data) external transient returns (bytes memory result) {
    // Callback to msg.sender with data
    return (msg.sender).functionCall(data);
}

// The transient modifier ensures:
// - Sets isUnlocked = true
// - After callback, checks nonZeroDeltaCount == 0
// - Reverts with BalanceNotSettled() if unsettled
```

### Credit/Debt Functions

```solidity
// Give credit to caller (tokens owed TO them)
function _supplyCredit(IERC20 token, uint256 amount) internal;

// Take debt from caller (tokens owed BY them)
function _takeDebt(IERC20 token, uint256 amount) internal;

// Settle debt by transferring tokens to Vault
function settle(IERC20 token, uint256 amountHint) external returns (uint256 credit);

// Claim credit by receiving tokens from Vault
function sendTo(IERC20 token, address to, uint256 amount) external;
```

## Token Handling

### Token Types

```solidity
enum TokenType {
    STANDARD,    // No rate provider, 1:1 value
    WITH_RATE    // Has rate provider for yield-bearing or wrapped tokens
}

struct TokenConfig {
    IERC20 token;
    TokenType tokenType;
    IRateProvider rateProvider;  // For WITH_RATE tokens
    bool paysYieldFees;          // Yield fees charged on this token
}
```

### Scaling System

All internal math uses 18-decimal precision ("scaled18"):

```solidity
struct PoolData {
    IERC20[] tokens;
    uint256[] balancesRaw;           // Native decimals
    uint256[] balancesLiveScaled18;  // 18 decimals, rate-adjusted
    uint256[] tokenRates;            // Rate provider values or FP(1)
    uint256[] decimalScalingFactors; // 10^(18 - decimals)
}
```

## Pools in V3

Pools are separate contracts that implement `IBasePool`:

```solidity
interface IBasePool {
    // Core swap math - called by Vault
    function onSwap(PoolSwapParams memory request) external returns (uint256);

    // Invariant calculation for add/remove liquidity
    function computeInvariant(uint256[] memory balancesLiveScaled18, Rounding rounding)
        external view returns (uint256);

    // Balance computation for single-token operations
    function computeBalance(
        uint256[] memory balancesLiveScaled18,
        uint256 tokenInIndex,
        uint256 invariantRatio
    ) external view returns (uint256 newBalance);
}
```

### Pool Tokens (BPT)

Each pool has its own ERC20 token (BPT - Balancer Pool Token):
- Minted when adding liquidity
- Burned when removing liquidity
- Token contract IS the pool contract (via BalancerPoolToken)
- Balances stored in Vault, not the token contract

## ERC4626 Buffers

V3 supports efficient wrapped token operations via buffers:

```solidity
// Buffers hold underlying + wrapped token reserves
// Enables wrap/unwrap without external calls when liquidity available
function erc4626BufferWrapOrUnwrap(BufferWrapOrUnwrapParams memory params) external;
```

## Key Storage Locations

```solidity
// Pool state
mapping(address pool => PoolConfigBits) internal _poolConfigBits;
mapping(address pool => IERC20[]) internal _poolTokens;
mapping(address pool => mapping(uint256 index => bytes32)) internal _poolTokenBalances;

// Token reserves (total Vault balance per token)
mapping(IERC20 token => uint256) internal _reservesOf;

// ERC4626 buffers
mapping(IERC4626 => bytes32 packedBalance) internal _bufferTokenBalances;
```

## Progressive Disclosure

For deeper understanding, see these related skills:

| Skill | Topic |
|-------|-------|
| `balancer-v3-vault` | Detailed Vault operations (swap, add/remove liquidity) |
| `balancer-v3-pools` | Pool registration and initialization |
| `balancer-v3-weighted-pool` | Weighted Pool math and factory |
| `balancer-v3-router` | Router patterns and user interaction |
| `balancer-v3-hooks` | Hook system for pool customization |

Files in this skill

  • SKILL.md6.5 KB
  • references/vault-types.md4.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…