Skip to content

Transparent proxy

A transparent proxy in Ethereum (ETH) refers to a specific type of proxy contract that acts as an intermediary between a user and the actual logic or functionality of a smart contract, while remaining “transparent” in the sense that users or other contracts are unaware that they are interacting with a proxy instead of the underlying contract directly.

Complex implementation

Ref - https://eips.ethereum.org/EIPS/eip-1967

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/transparent/TransparentUpgradeableProxy.sol

Using the Transparent Proxy pattern

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.22;
import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
contract StorageProxy is TransparentUpgradeableProxy {
constructor(
address _logic,
address initialOwner,
bytes memory _data
)
payable
TransparentUpgradeableProxy(_logic, initialOwner, _data)
{
// You can put custom constructor logic here if needed.
}
// If you MUST add new functionality, do so with caution,
// and ideally only internal or private functions to avoid
// creating new externally-callable selectors.
function _myInternalLogic() internal {
// Example internal logic
}
// If you need to intercept calls before they're forwarded, override `_fallback()`.
// But be aware that in the transparent pattern, the admin calls are routed here
// to do the upgrade.
function _fallback() internal virtual override {
// Custom pre-forwarding logic
// Then call the original fallback from TransparentUpgradeableProxy
super._fallback();
}
}
contract ImplementationV1 {
uint256 public num;
address public implementation;
function setNum(uint256 _num) public {
num = _num;
}
}
  1. Deploy ImplementationV1
  2. Deploy StorageProxy and give it the address of ImplementationV1
  3. Select ImplementationV1 and change the At address field to the address of the proxy contract
  4. Play with setNum and num
  5. Try updating the implementation via the ProxyAdmin contract

Problems

  1. Function collissions (across implementation contract and logic contract)
  2. Storage slot re-ordering

Simple Proxy vs Transparent proxy

A simple proxy (often called a basic proxy) typically uses delegatecall to forward calls to another contract (implementation). However, it doesn’t have the protections or additional features that come with the transparent proxy pattern:

  • Lack of transparency: If the user interacts with a basic proxy, they may have more visibility into the proxy behavior, or the proxy could expose implementation-specific details.
  • Admin visibility: In some proxies, the admin can interact with the contract through the same functions as the user, potentially making it more difficult to distinguish between admin-level functionality and regular contract behavior.