- October 1, 2025

OpenZeppelin Security

OpenZeppelin Security
Security Audits
Summary
Type: Governance
Timeline: September 22, 2025 → September 23, 2025
Languages: Solidity
Findings
Total issues: 4 (3 resolved)
Critical: 0 (0 resolved) · High: 0 (0 resolved) · Medium: 0 (0 resolved) · Low: 0 (0 resolved)
Notes & Additional Information
4 notes raised (3 resolved)
Scope
OpenZeppelin audited pull request #10 of the AcronymFoundation/anvil-contracts repository at commit 606d5de. As part of this audit, the implementation of the new Anvil governance token and its integration with the governance system were reviewed. Previously, in May 2024, an audit of the AcronymFoundation/anvil-contracts repository was performed at commit be6bd02.
In scope were the following files:
contracts
└── governance
├── Anvil.sol
└── AnvilGovernorDelegate.sol
System Overview
The new Anvil (ANVL) token has been designed to follow the standard ERC20Votes
pattern, providing a more streamlined and broadly compatible voting mechanism. This is in contrast to the legacy Anvil token, which had custom logic to account for the delegated voting power of unclaimed airdropped tokens. By adopting the conventional ERC20Votes
approach, the new design aligns the token with established governance standards. The total supply of the new Anvil token is capped at 100 billion, and all tokens are minted during deployment to a specified destinationAddress
provided in the constructor.
In parallel, the AnvilGovernorDelegate
contract will be upgraded, to introduce the reinitializeGovernanceToken
function, which allows the governor contract to be connected to the new Anvil token. Protected by the onlyGovernance
modifier, this function can only be invoked through a governance proposal.
Trust Assumptions
During the audit, the following trust assumptions were made:
-
During the construction of the Anvil governance token, the token's total supply is immediately minted to a specified
destinationAddress
. It is assumed that this amount will be fairly distributed to the existing token holders during the funds migration process. -
The migration from the legacy
ANVL
token contract to the new token contract will be carried out through an airdrop, based on a snapshot of current token holder balances. The migration logic itself was not part of this audit. It is assumed that the airdrop mechanism will be correctly implemented and executed, and that it will accurately reflect the intended balances of existing token holders. Both the legacy and new Anvil tokens will remain active in circulation. However, only the new token will be recognized by the governor contract for voting purposes. -
As a result of token migration, token holders will need to re-delegate their new tokens in order for their voting power to be reflected, even if they had already delegated in the legacy system. This redelegation requirement represents a functional change in governance behavior and is assumed to be clearly communicated to token holders as part of the migration process to avoid confusion or unintended gaps in voting power.
-
It is assumed that users will be properly informed about the existence of two tokens in circulation. While both the legacy and new tokens may continue to be held or traded, only the new token will be valid for governance.
Notes & Additional Information
Non-Explicit Imports
The use of non-explicit imports in the codebase can decrease code clarity and may create naming conflicts between locally defined and imported variables. This is particularly relevant when multiple contracts exist within the same Solidity file or when inheritance chains are long.
In the Anvil
and AnvilGovernorDelegate
contracts, global imports are being used. For example, import "@openzeppelin/contracts/token/ERC20/ERC20.sol"
is used in line 4 of the Anvil
contract.
Following the principle that clearer code is better code, consider using the named import syntax (import {A, B, C} from "X"
) to explicitly declare which contracts are being imported, such as, import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"
.
Update: Resolved in pull request #11 at commit ed882f4.
Use Custom Errors
Since Solidity version 0.8.4, custom errors provide a cleaner and more cost-efficient way to explain to users why an operation failed.
The AnvilGovernorDelegate
contract currently contains one revert("Cannot upgrade the timelock")
statement.
For conciseness, consider replacing revert
message with custom errors.
Update: Resoved in pull request #12 at commit d5bcd0b.
EIP-712 Version Consistency in New ANVL
Token Deployment
A new version of the ANVL token is planned for deployment at a new contract address. Since the verifyingContract
field in the EIP-712 domain separator will change, signature replay from the previous deployment is not possible. However, keeping the same EIP-712 version value may cause confusion when distinguishing between the legacy and the new contract. For clarity and stronger semantic versioning, it is advisable to increment the EIP-712 version in the new deployment.
Consider updating the EIP-712 version field in the newly deployed ANVL token to explicitly indicate the new release and avoid ambiguity in off-chain integrations.
Update: Resolved in pull request #13 at commit 172522a.
Incomplete Docstring
Within AnvilGovernorDelegate.sol
, the initialize
function has an incomplete docstring. For example, the timelock_
, governanceToken_
, votingPeriod_
, votingDelay_
, proposalThreshold_
parameters are not documented.
Consider thoroughly documenting all functions/events (and their parameters or return values) that are part of a contract's public API. When writing docstrings, consider following the Ethereum Natural Specification Format (NatSpec).
Update: Resolved in pull request #14 at commit a0661e7.
Conclusion
The audited code changes introduce a new version of the Anvil (ANVL) governance token. The legacy implementation relied on custom extensions to OpenZeppelin’s ERC20Votes
contract to support airdrop claims and delegated voting during vesting. In contrast, the new version is a simplified implementation that directly extends the ERC20Votes
contract, with all existing funds to be migrated to token holders, treating all tokens as fully vested.
Throughout the engagement, the Anvil Team has been highly responsive and cooperative, providing the audit team with clear explanations and valuable context regarding the planned migration process.
Ready to secure your code?