Skip to main content

Proxy

The proxy utilities module provides tools for inspecting and interacting with EIP-1967 and EIP-173 proxy contracts used in CoW Protocol deployments.

Functions

implementationAddress

Retrieves the implementation contract address from an EIP-1967 proxy.
async function implementationAddress(
  provider: Provider,
  proxyAddress: string
): Promise<string>;

ownerAddress

Fetches the admin/owner address from an EIP-1967 proxy.
async function ownerAddress(
  provider: Provider,
  proxyAddress: string
): Promise<string>;

proxyInterface

Generates an ethers.js contract instance configured with the EIP-173 proxy admin interface.
function proxyInterface(
  proxyAddress: string,
  signerOrProvider: Signer | Provider
): Contract;

Constants

EIP173_PROXY_ABI

const EIP173_PROXY_ABI = [
  "function owner() view returns (address)",
  "function transferOwnership(address newOwner)",
  "event OwnershipTransferred(address indexed previousOwner, address indexed newOwner)",
];

EIP-1967 Storage Slots

EIP-1967 compliance uses standardized storage slots:
SlotPurposeComputation
ImplementationLogic contract addresskeccak256("eip1967.proxy.implementation") - 1
AdminProxy owner addresskeccak256("eip1967.proxy.admin") - 1

Examples

Proxy Verification

import { implementationAddress, ownerAddress } from "@cowprotocol/contracts";
import { ethers } from "ethers";

const provider = new ethers.providers.JsonRpcProvider("YOUR_RPC_URL");
const proxyAddress = "0x2c4c28DDBdAc9C5E7055b4C863b72eA0149D8aFE";

const impl = await implementationAddress(provider, proxyAddress);
console.log("Implementation:", impl);

const owner = await ownerAddress(provider, proxyAddress);
console.log("Owner:", owner);

Ownership Transfer

import { proxyInterface } from "@cowprotocol/contracts";

const proxy = proxyInterface(proxyAddress, signer);
await proxy.transferOwnership(newOwnerAddress);
Last modified on March 4, 2026