> ## Documentation Index
> Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Proxy

> Proxy pattern utilities for upgradeable contracts

Utilities for working with proxy patterns including ERC-1967 storage slots, ERC-1167 minimal proxies, and ERC-3448 MetaProxies.

<Tip title="ERC References">
  Implements [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) (Proxy Storage Slots), [ERC-1167](https://eips.ethereum.org/EIPS/eip-1167) (Minimal Proxy), and [ERC-3448](https://eips.ethereum.org/EIPS/eip-3448) (MetaProxy).
</Tip>

## Overview

Proxy patterns enable contract upgradeability by separating logic (implementation) from state (proxy). The proxy delegates calls to the implementation while maintaining its own storage.

**Proxy Patterns:**

* **ERC-1967**: Standard storage slots for proxy metadata (implementation, admin, beacon)
* **ERC-1167**: Minimal proxy clone (45 bytes runtime) for gas-efficient deployment
* **ERC-3448**: MetaProxy with embedded metadata for factory patterns

## Quick Start

<Tabs>
  <Tab title="ERC-1967 Storage Slots">
    ```typescript theme={null}
    import * as Proxy from '@tevm/voltaire/Proxy';
    import { eth_getStorageAt } from '@tevm/voltaire/rpc';

    // Read implementation address from proxy
    const implementation = await eth_getStorageAt(
      proxyAddress,
      Proxy.IMPLEMENTATION_SLOT
    );

    // Read admin address
    const admin = await eth_getStorageAt(
      proxyAddress,
      Proxy.ADMIN_SLOT
    );

    console.log('Implementation:', implementation);
    console.log('Admin:', admin);
    ```
  </Tab>

  <Tab title="ERC-1167 Minimal Proxy">
    ```typescript theme={null}
    import * as Proxy from '@tevm/voltaire/Proxy';
    import { Address } from '@tevm/voltaire/Address';

    // Generate minimal proxy bytecode
    const implementation = Address.from('0x1234...');
    const proxyBytecode = Proxy.generateErc1167(implementation);

    console.log('Bytecode size:', proxyBytecode.length); // 55 bytes
    console.log('Runtime size:', 45); // 45 bytes after deployment

    // Parse deployed proxy
    const code = await eth_getCode(cloneAddress);
    const parsed = Proxy.parseErc1167(code);

    console.log('Implementation:', parsed.toHex());
    ```
  </Tab>

  <Tab title="ERC-3448 MetaProxy">
    ```typescript theme={null}
    import * as Proxy from '@tevm/voltaire/Proxy';
    import { Address } from '@tevm/voltaire/Address';

    // Generate MetaProxy with metadata
    const implementation = Address.from('0x1234...');
    const metadata = new TextEncoder().encode(JSON.stringify({
      creator: '0xabcd...',
      salt: '0x1234...',
      version: 1
    }));

    const metaProxyBytecode = Proxy.generateErc3448(
      implementation,
      metadata
    );

    // Parse deployed MetaProxy
    const code = await eth_getCode(metaProxyAddress);
    const result = Proxy.parseErc3448(code);

    console.log('Implementation:', result.implementation.toHex());
    console.log('Metadata:', new TextDecoder().decode(result.metadata));
    ```
  </Tab>
</Tabs>

## Proxy Patterns Comparison

| Feature        | ERC-1967               | ERC-1167             | ERC-3448                           |
| -------------- | ---------------------- | -------------------- | ---------------------------------- |
| Purpose        | Storage slots          | Minimal clone        | Clone + metadata                   |
| Bytecode size  | Varies                 | 55 bytes (creation)  | 55 + metadata + 32                 |
| Runtime size   | Varies                 | 45 bytes             | 45 bytes (metadata not in runtime) |
| Gas cost       | Standard               | Minimal              | Minimal + metadata                 |
| Upgradeability | Yes (UUPS/Transparent) | No                   | No                                 |
| Metadata       | No                     | No                   | Yes                                |
| Use case       | Upgradeable proxies    | Gas-efficient clones | Factory patterns                   |

## API Documentation

<CardGroup cols={3}>
  <Card title="Constants" icon="hashtag" href="/primitives/proxy/constants">
    ERC-1967 storage slot constants
  </Card>

  <Card title="generateErc1167" icon="code" href="/primitives/proxy/generate-erc1167">
    Generate minimal proxy bytecode
  </Card>

  <Card title="parseErc1167" icon="magnifying-glass" href="/primitives/proxy/parse-erc1167">
    Parse minimal proxy implementation
  </Card>

  <Card title="isErc1167" icon="check" href="/primitives/proxy/is-erc1167">
    Check if bytecode is ERC-1167
  </Card>

  <Card title="generateErc3448" icon="gem" href="/primitives/proxy/generate-erc3448">
    Generate MetaProxy with metadata
  </Card>

  <Card title="parseErc3448" icon="magnifying-glass-plus" href="/primitives/proxy/parse-erc3448">
    Parse MetaProxy implementation and metadata
  </Card>

  <Card title="isErc3448" icon="shield-check" href="/primitives/proxy/is-erc3448">
    Check if bytecode is ERC-3448
  </Card>
</CardGroup>

## Usage Patterns

### UUPS Proxy Detection

```typescript theme={null}
import * as Proxy from '@tevm/voltaire/Proxy';
import { eth_getStorageAt } from '@tevm/voltaire/rpc';

async function detectUUPSProxy(address: string) {
  // Check if ERC-1967 implementation slot is set
  const implementation = await eth_getStorageAt(
    address,
    Proxy.IMPLEMENTATION_SLOT
  );

  if (implementation === '0x' + '00'.repeat(32)) {
    return null; // Not a proxy
  }

  return {
    type: 'UUPS',
    implementation,
    slot: Proxy.IMPLEMENTATION_SLOT
  };
}
```

### Clone Factory

```typescript theme={null}
import * as Proxy from '@tevm/voltaire/Proxy';
import { Address } from '@tevm/voltaire/Address';

class CloneFactory {
  implementation: Uint8Array;
  proxyBytecode: Uint8Array;

  constructor(implementationAddress: string) {
    this.implementation = Address.from(implementationAddress);
    this.proxyBytecode = Proxy.generateErc1167(this.implementation);
  }

  async deployClone(initData?: Uint8Array) {
    // Deploy proxy
    const address = await deploy(this.proxyBytecode);

    // Initialize if needed
    if (initData) {
      await call(address, initData);
    }

    return address;
  }

  isClone(bytecode: Uint8Array): boolean {
    if (!Proxy.isErc1167(bytecode)) {
      return false;
    }

    const impl = Proxy.parseErc1167(bytecode);
    return impl.equals(this.implementation);
  }
}
```

### MetaProxy Factory with Metadata

```typescript theme={null}
import * as Proxy from '@tevm/voltaire/Proxy';
import { Address } from '@tevm/voltaire/Address';
import { keccak256 } from '@tevm/voltaire/crypto';

class MetaProxyFactory {
  async deployWithMetadata(
    implementation: string,
    creator: string,
    salt: string
  ) {
    const metadata = new TextEncoder().encode(JSON.stringify({
      creator,
      salt,
      timestamp: Date.now(),
      chainId: 1
    }));

    const bytecode = Proxy.generateErc3448(
      Address.from(implementation),
      metadata
    );

    // Calculate deterministic address (CREATE2)
    const address = Address.calculateCreate2Address(
      Address.from(this.factoryAddress),
      keccak256(new TextEncoder().encode(salt)),
      bytecode
    );

    return { bytecode, address, metadata };
  }

  async readMetadata(proxyAddress: string) {
    const code = await eth_getCode(proxyAddress);

    if (!Proxy.isErc3448(code)) {
      throw new Error('Not a MetaProxy');
    }

    const { implementation, metadata } = Proxy.parseErc3448(code);
    const metadataObj = JSON.parse(
      new TextDecoder().decode(metadata)
    );

    return {
      implementation: implementation.toHex(),
      ...metadataObj
    };
  }
}
```

## Specification References

* [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) - Proxy Storage Slots
* [ERC-1167](https://eips.ethereum.org/EIPS/eip-1167) - Minimal Proxy Contract
* [ERC-3448](https://eips.ethereum.org/EIPS/eip-3448) - MetaProxy Standard
* [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822) - Universal Upgradeable Proxy Standard (UUPS)
* [EIP-1967](https://eips.ethereum.org/EIPS/eip-1967) - Standard storage slots specification

## Related

* [Storage](/primitives/storage) - Namespaced storage for upgradeable contracts
* [Address](/primitives/address) - Address utilities including CREATE2
* [Bytecode](/primitives/bytecode) - Bytecode analysis and manipulation
