Skip to main content

ERC-1967 Storage Slots

Standard storage slots for proxy contracts as defined in ERC-1967.

IMPLEMENTATION_SLOT

const IMPLEMENTATION_SLOT =
  "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"
Storage slot for implementation address in UUPS and transparent proxies. Calculation:
bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
Example:
import { IMPLEMENTATION_SLOT } from '@tevm/voltaire/Proxy';
import { eth_getStorageAt } from '@tevm/voltaire/rpc';

const implementation = await eth_getStorageAt(
  proxyAddress,
  IMPLEMENTATION_SLOT
);
console.log('Implementation:', implementation);

ADMIN_SLOT

const ADMIN_SLOT =
  "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103"
Storage slot for admin address in transparent proxies. Calculation:
bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1)
Example:
import { ADMIN_SLOT } from '@tevm/voltaire/Proxy';
import { eth_getStorageAt } from '@tevm/voltaire/rpc';

const admin = await eth_getStorageAt(proxyAddress, ADMIN_SLOT);
console.log('Admin:', admin);

BEACON_SLOT

const BEACON_SLOT =
  "0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50"
Storage slot for beacon address in beacon proxies. Calculation:
bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)
Example:
import { BEACON_SLOT } from '@tevm/voltaire/Proxy';
import { eth_getStorageAt } from '@tevm/voltaire/rpc';

const beacon = await eth_getStorageAt(proxyAddress, BEACON_SLOT);
console.log('Beacon:', beacon);

ROLLBACK_SLOT

const ROLLBACK_SLOT =
  "0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143"
Storage slot for rollback tests in upgradeable proxies. Calculation:
bytes32(uint256(keccak256('eip1967.proxy.rollback')) - 1)
Example:
import { ROLLBACK_SLOT } from '@tevm/voltaire/Proxy';
import { eth_getStorageAt } from '@tevm/voltaire/rpc';

const rollback = await eth_getStorageAt(proxyAddress, ROLLBACK_SLOT);

Usage Pattern: Proxy Detection

import * as Proxy from '@tevm/voltaire/Proxy';
import { eth_getStorageAt } from '@tevm/voltaire/rpc';

async function analyzeProxy(address: string) {
  const [implementation, admin, beacon] = await Promise.all([
    eth_getStorageAt(address, Proxy.IMPLEMENTATION_SLOT),
    eth_getStorageAt(address, Proxy.ADMIN_SLOT),
    eth_getStorageAt(address, Proxy.BEACON_SLOT)
  ]);

  const hasImpl = implementation !== '0x' + '00'.repeat(32);
  const hasAdmin = admin !== '0x' + '00'.repeat(32);
  const hasBeacon = beacon !== '0x' + '00'.repeat(32);

  if (hasImpl && hasAdmin) {
    return { type: 'Transparent Proxy', implementation, admin };
  } else if (hasImpl) {
    return { type: 'UUPS Proxy', implementation };
  } else if (hasBeacon) {
    return { type: 'Beacon Proxy', beacon };
  }

  return { type: 'Not a proxy' };
}

Specification

Defined in: src/primitives/Proxy/constants.js See also: