The audit of the DopplerERC20V1 contract identified a critical issue due to incomplete code, preventing a full assessment of the core vesting logic. The contract implements an ERC20 token with vesting schedules and a configurable balance limit. Key strengths include the use of battle-tested Solady libraries and robust input validation in the initialization process. However, the balance limit mechanism has several explicit exclusions, and the controller role introduces a point of centralization. A full security assessment requires the complete source code for the vesting functions.
On-chain security analysis — is it a scam or legit?
Is The White Wolf Safe?
Not verified
This record has not gone through deep verification and is not being monitored. The score is a dated snapshot — the token’s risk can change at any time.Own this token? Put it under verification →The audit of the DopplerERC20V1 contract identified a critical issue due to incomplete code, preventing a full assessment of the core vesting logic.
Read the full analysis- Ownership not renounced — owner is a contract
- Proxy contract
- Non-standard proxy storage
- Top-10 concentration > 30%
- Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
- LP top1 unlocked holder = 96.8%
- LP top3 unlocked holders = 99.1%
- 1 Critical finding(s) from audit
- 2 Medium finding(s) from audit
Exact factors
- Ownership NOT renounced — owner is a contract (governance/executor, not an EOA)
- Proxy contract (upgradeable — admin can replace logic)
- Non-standard proxy storage (Etherscan-confirmed)
- Top-10 concentration > 30% (69.5% total → 34.8% effective; 11.6% in EOAs, 57.9% in contracts — moderate)
- Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
- LP top1 unlocked holder = 96.8% (independent LP — depth risk, pool = 100% of DEX liquidity)
- LP top3 unlocked holders = 99.1% (independent LP — depth risk, pool = 100% of DEX liquidity)
- 1 Critical finding(s) from audit
- 2 Medium finding(s) from audit
Each factor is an on-chain fact recorded at the time of this analysis. The score is computed from them by a deterministic function, so the same contract returns the same score for anyone who runs the audit. How scores are computed
Security Checklist
as of audit · Sep 4Holders
as of audit · Sep 4, 2026- Contractstreasury, vesting, bridge, staking57.9%
- Walletsanonymous holders, free to sell11.6%
- Everyone elsethe rest of the supply30.5%
How holder types affect the score
Share held by contracts — treasury, vesting, bridge or staking — is discounted against share held by wallets when the score is computed: a contract cannot decide to sell the way an anonymous holder can, though it can still be drained or voted to sell. Effective concentration is the figure the risk score is actually calculated from.
Holder balances as recorded by the audit of Sep 4, 2026
Liquidity
as of audit · Sep 4The risk score reads depth across every pair.
The LP tokens of the analysed pool are not locked or burned, so whoever holds them can withdraw that liquidity.
0xefb3…44b60x3041…a3030x9259…60a60x72e5…8efe0xe6fc…71f10xfe54…b871No privileged address appears among these holders: the unlocked liquidity sits with independent providers, not with the deployer.
Security Findings
CriticalIncomplete Vesting Logic Source Code
The provided source code for the DopplerERC20V1 contract is truncated, specifically omitting the full implementation of the _available, _releaseFor, and _releaseAllFor functions. These functions are central to the contract's core vesting mechanism, responsible for calculating releasable amounts and executing token transfers. Without the complete code, a comprehensive security assessment of the vesting logic, including potential reentrancy vulnerabilities, incorrect calculations, or denial-of-service risks, cannot be performed.C-01
Issue
The provided source code for the DopplerERC20V1 contract is truncated, specifically omitting the full implementation of the _available, _releaseFor, and _releaseAllFor functions. These functions are central to the contract's core vesting mechanism, responsible for calculating releasable amounts and executing token transfers. Without the complete code, a comprehensive security assessment of the vesting logic, including potential reentrancy vulnerabilities, incorrect calculations, or denial-of-service risks, cannot be performed.
Fix
Provide the complete and untruncated source code for the DopplerERC20V1 contract, especially the _available, _releaseFor, and _releaseAllFor functions, to allow for a thorough security review of the vesting mechanism.
Status
Unresolved
MediumCentralized Control by Controller Role
The controller address has the exclusive privilege to call disableBalanceLimit(), which permanently deactivates the token's balance limit feature. If the controller address is controlled by a single External Owned Account (EOA), it represents a single point of failure. A compromise of this EOA could lead to the balance limit being disabled against the protocol's intent, potentially impacting the token's economic model (7.3 Access Control, 7.5 Governance). While the owner is a multisig, the controller's status is not specified.M-01
Issue
The controller address has the exclusive privilege to call disableBalanceLimit(), which permanently deactivates the token's balance limit feature. If the controller address is controlled by a single External Owned Account (EOA), it represents a single point of failure. A compromise of this EOA could lead to the balance limit being disabled against the protocol's intent, potentially impacting the token's economic model (7.3 Access Control, 7.5 Governance). While the owner is a multisig, the controller's status is not specified.
Fix
Consider assigning the controller role to a multi-signature wallet or a contract with a timelock mechanism. This would introduce a delay or require multiple approvals for critical actions, enhancing security and decentralization.
Status
Unresolved
MediumBalance Limit Bypass for Excluded Addresses
The initialize function explicitly excludes the owner, recipient, and all beneficiaries from the isBalanceLimitActive check by setting isExcludedFromBalanceLimit to true for these addresses. Additionally, the lockPool function excludes the designated pool address. This design choice means that these privileged addresses can hold token balances exceeding maxBalanceLimit even when the balance limit is active. While potentially intended, this significantly narrows the scope of the balance limit and should be clearly documented and understood as a core design decision impacting the token's economic security model (7.4 Economic).M-02
Issue
The initialize function explicitly excludes the owner, recipient, and all beneficiaries from the isBalanceLimitActive check by setting isExcludedFromBalanceLimit to true for these addresses. Additionally, the lockPool function excludes the designated pool address. This design choice means that these privileged addresses can hold token balances exceeding maxBalanceLimit even when the balance limit is active. While potentially intended, this significantly narrows the scope of the balance limit and should be clearly documented and understood as a core design decision impacting the token's economic security model (7.4 Economic).
Fix
Clearly document the rationale behind excluding these specific addresses from the balance limit. Ensure that this behavior aligns with the intended economic model and security assumptions. If the intent was for the balance limit to apply more broadly, reconsider these exclusions.
Status
Unresolved
InfoPotential for Front-running in releaseFor (Conditional)
The releaseFor(address beneficiary, uint256 scheduleId, uint256 amount) function is external, allowing any address to call it to release tokens for a specified beneficiary. Depending on the exact implementation of the truncated _available and _releaseFor functions, this could potentially open a window for front-running attacks. If the calculation of available tokens or the release process has a time-sensitive component that can be exploited, a malicious actor could observe a pending transaction and submit their own transaction with a higher gas price to claim tokens before the intended beneficiary or to grief the transaction (7.2 Code Security).I-01
releaseFor (Conditional)Issue
The releaseFor(address beneficiary, uint256 scheduleId, uint256 amount) function is external, allowing any address to call it to release tokens for a specified beneficiary. Depending on the exact implementation of the truncated _available and _releaseFor functions, this could potentially open a window for front-running attacks. If the calculation of available tokens or the release process has a time-sensitive component that can be exploited, a malicious actor could observe a pending transaction and submit their own transaction with a higher gas price to claim tokens before the intended beneficiary or to grief the transaction (7.2 Code Security).
Fix
Once the full source code for _available and _releaseFor is available, carefully review the logic for any time-sensitive dependencies or race conditions. Consider restricting releaseFor to only be callable by the beneficiary themselves, or by an authorized controller with appropriate safeguards, if front-running is deemed a significant risk.
Status
Unresolved
InfoAmbiguity in Vesting Duration for duration == 0
The initialize function's validation for vesting schedules allows s.duration == 0 or s.duration >= MIN_VESTING_DURATION. While MIN_VESTING_DURATION is set to 1 day, a duration of 0 implies immediate vesting. This dual condition is likely intended to support both immediate and time-locked vesting schedules. However, the naming MIN_VESTING_DURATION might suggest all vesting should have a minimum duration, which is not strictly enforced if duration is 0. This could lead to minor confusion or misinterpretation of the vesting schedule's behavior (7.2 Code Security).I-02
duration == 0Issue
The initialize function's validation for vesting schedules allows s.duration == 0 or s.duration >= MIN_VESTING_DURATION. While MIN_VESTING_DURATION is set to 1 day, a duration of 0 implies immediate vesting. This dual condition is likely intended to support both immediate and time-locked vesting schedules. However, the naming MIN_VESTING_DURATION might suggest all vesting should have a minimum duration, which is not strictly enforced if duration is 0. This could lead to minor confusion or misinterpretation of the vesting schedule's behavior (7.2 Code Security).
Fix
Clarify the intended behavior for vesting schedules with duration == 0 in the contract's documentation. Consider renaming MIN_VESTING_DURATION to something like MIN_NON_ZERO_VESTING_DURATION or adding a comment to explicitly state that duration == 0 signifies immediate vesting, distinct from the minimum duration for time-locked schedules.
Status
Unresolved
Analysis
AI Copilotas of audit · Sep 4The contract leverages Solady libraries for ERC20, Ownable, and Initializable functionalities, which contributes to a solid architectural foundation (7.1 Architecture). Input validation in the initialize function is robust, preventing common setup errors like array length mismatches or invalid vesting schedules (7.2 Code Security). However, a critical portion of the vesting logic (_available, _releaseFor) is missing, preventing a comprehensive security assessment of the core token release mechanism. The releaseFor function, which allows external calls to release tokens for any beneficiary, could be susceptible to front-running depending on the missing logic.
The contract's economic model includes a balance limit feature intended to restrict token holdings, and vesting schedules to control token distribution over time (7.4 Economic). The initialize function includes checks for maxPreMintPerAddress and maxTotalPreMint to manage initial token allocation. However, the balance limit is explicitly bypassed for the owner, initial recipient, all vesting beneficiaries, and the designated pool address, significantly reducing its scope. The controller role has the power to disable the balance limit entirely, introducing a centralized point of control (7.5 Governance). The owner, while a multisig according to prefill, still holds critical powers like locking the pool.
The contract is not identified as an upgradeable proxy, and therefore, upgrade safety considerations (7.7 Upgrades) are not applicable. The Initializable pattern is used, but _disableInitializers() in the constructor suggests it's intended as a standalone contract or a non-upgradeable implementation.
It is critical to provide the complete source code for the vesting calculation and release functions (_available, _releaseFor, _releaseAllFor) to enable a full security assessment of the core token functionality.
Review the design implications of the balance limit exclusions and ensure they align with the intended security model. Consider implementing a timelock for the controller role or making it a multisig to mitigate centralization risks.
Contract & Record
Free for any token on the record. It links to this page and always shows the current score and the date it was checked.
- Sep 4, 202674High
- Aug 11, 202678High
Score changes are recorded as dated snapshots — history is append-only and cannot be edited.
Would You Like a More Detailed Audit of The White Wolf?
Our AI-powered scanner gives you a deeper, real-time smart contract analysis — free, with every scoring factor shown.
Get Detailed Audit Is this your token? Publish your own audit on this page