Quantum Audit Logo

Is evo Safe?

On-chain security analysis — is it a scam or legit?

evo EVO
0x721b…bba3
Base Not verifiedLast checked 3d ago 1 audit on record
Executive SummaryAI Copilot

The DERC20 token contract implements standard ERC20 functionalities along with custom features for vesting, inflation, and a pool locking mechanism. The contract leverages OpenZeppelin libraries for robust base implementations. However, the audit identified two high-severity issues: an inverted logic for pool locking with a misleading error message, and the complete absence of a function to release vested tokens, rendering a core feature non-functional. Minor issues include precision loss in inflation calculations and a restrictive constructor check. The contract also exhibits a high degree of centralization under the owner's control.

2 High2 Low2 Informational
Volume 24h
$2.2K
Liquidity
$88.8K
Price
$0.000001408
Token Age
3mo
Top 10 Holders
64.5%

Security Findings

High

Inverted Logic and Misleading Error Message for Pool Locking

H-01The `_beforeTokenTransfer` hook contains logic `if (from == pool && !isPoolUnlocked) { revert PoolLocked(); }`. This prevents tokens from being transferred *from* the `pool` address when the pool is locked. However, the associated error message `PoolLocked()` states: 'Thrown when trying to transfer tokens into the pool while it is locked'. This discrepancy indicates either an inverted logic (if the intent was to prevent transfers *into* the pool) or a misleading error message (if the intent was to prevent transfers *from* the pool). If the former, the intended protection against transfers *into* the pool is completely bypassed.
IssueThe `_beforeTokenTransfer` hook contains logic `if (from == pool && !isPoolUnlocked) { revert PoolLocked(); }`. This prevents tokens from being transferred *from* the `pool` address when the pool is locked. However, the associated error message `PoolLocked()` states: 'Thrown when trying to transfer tokens into the pool while it is locked'. This discrepancy indicates either an inverted logic (if the intent was to prevent transfers *into* the pool) or a misleading error message (if the intent was to prevent transfers *from* the pool). If the former, the intended protection against transfers *into* the pool is completely bypassed.
FixClarify the intended behavior for pool locking. If the goal is to prevent transfers *into* the pool, modify the condition to `if (to == pool && !isPoolUnlocked)`. If the goal is to prevent transfers *from* the pool, update the `PoolLocked()` error message to accurately reflect this, e.g., 'Thrown when trying to transfer tokens from the pool while it is locked'.
StatusUnresolved
High

Missing Vesting Token Release Functionality

H-02The contract defines a comprehensive vesting mechanism, including `vestingStart`, `vestingDuration`, `vestedTotalAmount`, and a `getVestingDataOf` mapping to track individual vesting data. However, the crucial `releaseVestedTokens` function (or any equivalent public/external function allowing beneficiaries to claim their vested tokens) is entirely absent from the provided source code. This renders the entire vesting system non-functional, preventing beneficiaries from accessing their vested tokens after the vesting period.
IssueThe contract defines a comprehensive vesting mechanism, including `vestingStart`, `vestingDuration`, `vestedTotalAmount`, and a `getVestingDataOf` mapping to track individual vesting data. However, the crucial `releaseVestedTokens` function (or any equivalent public/external function allowing beneficiaries to claim their vested tokens) is entirely absent from the provided source code. This renders the entire vesting system non-functional, preventing beneficiaries from accessing their vested tokens after the vesting period.
FixImplement a `releaseVestedTokens` function that allows users to claim their vested tokens based on the `vestingStart`, `vestingDuration`, and `getVestingDataOf` records. This function should calculate the releaseable amount, transfer tokens from the contract's balance to the claimant, and update the `releasedAmount` in `getVestingDataOf`.
StatusUnresolved
Low

Precision Loss in Inflation Calculation

L-01The `mintInflation` function calculates `yearMint` and `partialYearMint` using integer division: `(supply * yearlyMintRate_ * timeLeftInCurrentYear) / (1 ether * 365 days)`. Integer division truncates any fractional token amounts, leading to a slight under-minting of tokens compared to a precise floating-point calculation. While common in Solidity, this precision loss can accumulate over time and result in a minor deviation from the intended inflation schedule.
IssueThe `mintInflation` function calculates `yearMint` and `partialYearMint` using integer division: `(supply * yearlyMintRate_ * timeLeftInCurrentYear) / (1 ether * 365 days)`. Integer division truncates any fractional token amounts, leading to a slight under-minting of tokens compared to a precise floating-point calculation. While common in Solidity, this precision loss can accumulate over time and result in a minor deviation from the intended inflation schedule.
FixConsider using a fixed-point math library or adjusting the calculation methodology to minimize precision loss if exact inflation amounts are critical. Alternatively, acknowledge this behavior as an acceptable trade-off for gas efficiency and simplicity in the project's documentation.
StatusUnresolved
Low

Constructor Vesting Limit Logic

L-02The constructor includes a check `require(vestedTokens < initialSupply, MaxTotalVestedExceeded(vestedTokens, initialSupply));`. This condition prevents the entire `initialSupply` from being allocated to vested tokens, requiring at least one wei to be sent to the `recipient` via `_mint(recipient, initialSupply - vestedTokens)`. If the intention was to allow full initial supply vesting, this check imposes an unnecessary restriction. Additionally, the error message 'MaxTotalVestedExceeded' implies `vestedTokens > initialSupply` rather than `>= initialSupply`, which could be confusing.
IssueThe constructor includes a check `require(vestedTokens < initialSupply, MaxTotalVestedExceeded(vestedTokens, initialSupply));`. This condition prevents the entire `initialSupply` from being allocated to vested tokens, requiring at least one wei to be sent to the `recipient` via `_mint(recipient, initialSupply - vestedTokens)`. If the intention was to allow full initial supply vesting, this check imposes an unnecessary restriction. Additionally, the error message 'MaxTotalVestedExceeded' implies `vestedTokens > initialSupply` rather than `>= initialSupply`, which could be confusing.
FixReview the project's token distribution strategy to confirm if `vestedTokens` should be allowed to equal `initialSupply`. If so, change the condition to `vestedTokens <= initialSupply`. Also, consider refining the error message for clarity if the current behavior is intended.
StatusUnresolved
Info

Centralized Control by Owner

I-01The contract's `Ownable` pattern grants the deployer (owner) significant control over critical functions. The owner can `lockPool`, `unlockPool`, `burn` tokens, and `updateMintRate`. While `mintInflation` is public, it mints all inflation tokens directly to the owner. This centralization introduces a single point of failure and relies heavily on the owner's trustworthiness and operational security.
IssueThe contract's `Ownable` pattern grants the deployer (owner) significant control over critical functions. The owner can `lockPool`, `unlockPool`, `burn` tokens, and `updateMintRate`. While `mintInflation` is public, it mints all inflation tokens directly to the owner. This centralization introduces a single point of failure and relies heavily on the owner's trustworthiness and operational security.
FixFor enhanced decentralization and security, consider implementing a multi-signature wallet for ownership or transitioning to a decentralized autonomous organization (DAO) governance model for critical functions. If centralization is intended, ensure robust operational security measures are in place for the owner's private key.
StatusUnresolved
Info

BUSL-1.1 License Usage

I-02The contract is licensed under the Business Source License 1.1 (BUSL-1.1). This is a non-open-source license with specific usage restrictions, typically allowing free use for non-production purposes but requiring a commercial license for production use after a certain time period. While not a security vulnerability, this has significant implications for project adoption, integration, and legal compliance for users and developers.
IssueThe contract is licensed under the Business Source License 1.1 (BUSL-1.1). This is a non-open-source license with specific usage restrictions, typically allowing free use for non-production purposes but requiring a commercial license for production use after a certain time period. While not a security vulnerability, this has significant implications for project adoption, integration, and legal compliance for users and developers.
FixEnsure all users and integrators of the DERC20 contract are fully aware of the BUSL-1.1 licensing terms and their implications. Clearly communicate the licensing model in project documentation and any public-facing materials.
StatusUnresolved

Category Ratings

TechnicalLow8/10

The contract utilizes well-audited OpenZeppelin libraries for ERC20, ERC20Votes, ERC20Permit, and Ownable, providing a strong foundation (7.2 Code Security). Custom error messages enhance clarity. However, a critical flaw exists in the `_beforeTokenTransfer` hook where the pool locking logic is inverted, failing to prevent transfers *into* the pool as implied by its error message (7.3 Access Control). Furthermore, the core vesting functionality is rendered unusable due to the complete absence of a `releaseVestedTokens` function (7.1 Architecture). Precision loss in inflation calculations (7.4 Economic) and a restrictive constructor check (7.1 Architecture) are also noted.

GovernanceHigh2/10

The contract's economic model includes a capped yearly inflation rate, preventing excessive token dilution (7.4 Economic). The owner has control over critical parameters like `yearlyMintRate` and can `lockPool`/`unlockPool`, which is a centralized design choice (7.5 Governance). While `mintInflation` is public, it mints tokens directly to the owner, centralizing inflation distribution. The BUSL-1.1 license (7.6 External) introduces legal restrictions, which is an important consideration for adoption.

UpgradesLow7/10

The DERC20 contract is implemented as a standalone, non-upgradeable contract. Therefore, it does not introduce any specific upgrade-related risks (7.7 Upgrades). Any future changes would require a new deployment and migration.

Security Checklist

Contract VerifiedPass
Ownership RenouncedFail
No Mint FunctionPass
Liquidity LockedFail
Not a ProxyPass

Holder Composition

23.2% in wallets41.2% in contracts
Effective Concentration39.7%

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.

Liquidity Depth

The risk score reads depth across every pair. The volume figure and the volume-to-liquidity ratio elsewhere on this page describe only the pair this audit analysed, so the two are not directly comparable.

LP Distribution

Top-1 Unlocked Holder64.0%
Top-3 Unlocked90.2%

Key Addresses

Deployer
0xb1bc…ea1a
Unlocked LP Held By
0xe17c…11020x2777…a0360xf6fe…83a80x8160…287d0xf900…098c

No privileged address appears among these holders: the unlocked liquidity sits with independent providers, not with the deployer.

What Raised This Score

  • Ownership NOT renounced — owner is a contract (governance/executor, not an EOA)
  • Top-10 concentration > 30% (64.5% total → 39.7% effective; 23.2% in EOAs, 41.2% in contracts — moderate)
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • LP top1 unlocked holder = 64.0% (independent LP — depth risk)
  • LP top3 unlocked holders = 90.2% (independent LP — depth risk)
  • 2 High finding(s) from audit
  • 2 Low 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

Related Audits

Morpho Token (MORPHO)High RiskTether USD (USDT)High RiskBIOHigh RiskHydrex (HYDX)High RiskAavegotchi GHST Token (GHST)High RiskFree Bots (BOTS)High Risk

Would You Like a More Detailed Audit of evo?

Our AI-powered scanner gives you a deeper, real-time smart contract analysis — free, with every scoring factor shown.

Get Detailed Audit