Works on: Virtual Environments and public networks (mainnets and testnets). The same plugin handles both; point it at the right network in
hardhat.config.ts.@tenderly/hardhat-tenderly.
Requirements
Automatic proxy verification works out of the box on@tenderly/hardhat-tenderly:
>= 1.10.0(Ethers 5 line)>= 2.1.0(Ethers 6 line)
@openzeppelin/hardhat-upgrades. Hardhat Ignition is not supported for proxy verification yet.
If you’re on a lower plugin version and can’t upgrade, use the manual workaround below.
Automatic verification
The plugin verifies three proxy patterns:TransparentUpgradeableProxy, UUPSUpgradeableProxy, and BeaconProxy.
Workaround for lower versions
When using@tenderly/hardhat-tenderly at versions < 1.10.0 and < 2.1.0, this workaround will enable automatic verification.
You need to verify the following:
- The proxy contract (e.g. OpenZeppelin’s proxies)
- Implementation behind the proxy
- Any dependencies the implementation has
- New implementation instances deployed with upgrades
Overview
In this guide, we’ll use an example Hardhat project and the@tenderly/hardhat-tenderly plugin to demonstrate the verification of OpenZeppelin’s UUPSUpgradeable, TransparentUpgradeableProxy, and BeaconProxy alternatives.
To obtain the address of the deployed implementation, use the @openzeppelin/upgrades-core package and getImplementationAddress function.
Verifying the proxy implementation is usually straightforward; verify it just like any other contract.
example.ts
- Load the exact smart contract of the proxy depending on the type of proxy you’re using, so it gets compiled. You’ll need to import the proxy contracts through the compiler by creating a dummy .sol file.
- Modify
hardhat.config.tsto specify the settings OpenZepplin contracts were compiled with.
example.ts
Verify by proxy type
These code samples show how to verify the implementation and the proxy for OpenZeppelin’s three proxy patterns. The examples use a proxiedVault contract that references an ERC-20 token (TToken).
UUPS proxy
To verify the UUPS proxy and the underlying information, call thehardhat-tenderly plugin twice:
- To verify the implementation, you need to provide the following:
nameof your proxied contract (in our caseVault)- Address where the contract was deployed using the
getImplementationAddressmethod from@openzeppelin/upgrades-core.
- To verify the proxy, provide the following:
ERC1967Proxyas the proxy contractname- Address of the proxy
proxy.address
example.ts
Complete Code Sample
Here’s a complete Hardhat test that does the following:- Deploys the
TToken(needed for the vault) - Deploys
Vaultas a proxy, initialized with theTTokencontract - Verifies the proxy (
ERC1967Proxy) instance deployed atawait proxy.getAddress() - Verifies the implementation instance
Vault, deployed atgetImplementationAddress(ethers.provider, await proxy.getAddress()) - Upgrades the proxy to
VaultV2
example.ts
Transparent proxy
To verify the UUPS proxy and the underlying information, callhardhat-tenderly while passing two contracts: Vault for the implementation, and TransparentUpgradeableProxy for the proxy itself.
example.ts
- To verify the implementation, provide the following:
nameof your proxied contract (in our caseVault)- Address where the contract was deployed, using the
getImplementationAddressmethod from@openzeppelin/upgrades-core.
- To verify the proxy, provide the following:
TransparentUpgradeableProxyas the proxy contractname- Address of the proxy
await proxy.getAddress()
Complete Code Sample
example.ts
Beacon proxy
To verify the Beacon proxy and the underlying information, you have to verify two contracts: theVault (implementation) and OpenZepplin’s UpgradableBeacon:
example.ts
Complete Code Sample
example.ts