Verify Your Deployed Contracts
Deploying a smart contract to mainnet is a point of no return — any misconfiguration or overlooked mistake can lead to loss of funds or trust. A robust verification process after deployment ensures that the contract matches the audited code and behaves as expected. Below is a structured guide to verifying a smart contract deployment securely and thoroughly.
Why Deployment Verification?
Ensure Audit Relevance: Confirm that the deployed contract matches the version that was audited.
Prevent Silent Modifications: Detect unauthorized or accidental changes between audit and deployment.
Some Misconfigurations Are Invisible in Audit: There are misconfiguration issues that can't be caught in an audit — they must be verified in the context of a live deployment.
Steps for Deployment Verification
Verify Source Code and Compiler Settings
Match Bytecode: Ensure the deployed bytecode corresponds exactly to the audited source code.
Match Compiler Version & Settings: Confirm that the Solidity compiler version and optimization flags are identical to those used during the audit.
Upload to Etherscan: Upload the Solidity source code that matches the deployed bytecode to Etherscan for public verification. Use Etherscan’s contract verification UI or tools like
sourcify.dev
to verify the contract on-chain. Ensure the provided source code, constructor arguments, and compiler settings generate the exact bytecode deployed.
Verify Final Code Version
Post-Fix Deployment: Confirm that the deployed version contains all fixes and patches introduced during and after security reviews.
How: Cross-check the Git commit, release tag, or hash used for deployment against the version approved in the final audit report.
Check Constructor Arguments
What to Look For: Ensure initialization parameters (e.g., admin addresses, external token addresses, fee rates) are correctly set.
How: Decode the deployment transaction input or read constructor arguments from block explorers and compare them with audited config files.
Confirm Contract Ownership and Roles
Ownership, Admin Rights & Role Setup: Make sure privileged roles are held by the correct addresses or multisigs and that role permissions (
AccessControl
,owner()
, etc.) are correctly configured and verifiable on-chain.
Validate Upgradeability Setup
If Using Proxies: Check that the proxy points to the intended implementation and that the upgrade admin is properly configured.
How: Inspect storage slots manually or use tools like
openzeppelin-upgrades
to verify the proxy pattern.
Confirm Deployment Scripts Were Followed
Replay and Audit the Script: Ensure the deployment was executed via the approved and audited scripts.
Best Practice: Automate deployment with reproducible scripts (e.g., Foundry, Hardhat) and record the transaction hashes.
Match Deployed Addresses
For Multisigs, Tokens, Registries: Confirm that all deployed contract addresses match those expected in documentation, frontends, and audit reports.
Cross-check: Ensure integrations and monitoring systems use the correct addresses.
Enable Public Verification
Verified Source Code: Publish the verified source code to public block explorers.
Public README / Audit Link: Make the audit report and deployment configuration publicly accessible to build user confidence.
Tag the Commit Hash as a Release on GitHub
Why: This provides a public, immutable reference to the exact code version that was deployed.
Export Contract Addresses to Your GitHub Repo
Why: Keeping deployed addresses in your repository (e.g., as a JSON or markdown file) improves transparency and simplifies integration for users and partners.
Best Practice: Include network name, contract name, address, and optionally, verification links.
Last updated