smithery.ai

Balancer V3 Architecture

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.

Installation

$ npx skills add https://smithery.ai

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Skill metadata

Parsed from SKILL.md frontmatter.

Version0.1.0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 6,635 B
  • docs SUMMARY.md 274 B

History

  1. First recorded snapshot · 1 installs

SKILL.md

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:

// 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

// 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

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"):

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:

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:

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

Key Storage Locations

// 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