Quantum Audit Logo

Is ICP Safe?

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

ICP ICP
0x00f3…8917
Base Not verifiedLast checked 3d ago 1 audit on record
How is this score calculated? → Critical Risk
Executive SummaryAI Copilot

The Token contract implements an ERC20 token with custom burning, minting, and ETH withdrawal functionalities, leveraging OpenZeppelin's ERC20, Ownable, and ERC20Permit standards. While the contract benefits from well-tested OpenZeppelin components and clear access control for critical operations, a significant logical error in the `withdrawEth` function severely restricts the owner's ability to manage contract ETH. Additionally, unchecked external call results in minting functions pose a risk of silent failures, and several code redundancies were identified.

1 High1 Medium1 Low2 Informational
Volume 24h
$601.7K
Liquidity
$594.9K
Price
$2.5500
Token Age
1y
Top 10 Holders
73.2%

Security Findings

High

Critical Logic Error in `withdrawEth` Function

H-01The `withdrawEth` function contains a logical error in its `require` statement: `require(amount >= address(this).balance, "Balance too low");`. This condition incorrectly checks if the requested `amount` is greater than or equal to the contract's total ETH balance. As a result, the owner can only successfully withdraw the *exact total balance* of the contract, or attempts to withdraw more will revert due to insufficient funds during the `transfer` call. This prevents the owner from withdrawing partial amounts of ETH, severely hindering fund management.
IssueThe `withdrawEth` function contains a logical error in its `require` statement: `require(amount >= address(this).balance, "Balance too low");`. This condition incorrectly checks if the requested `amount` is greater than or equal to the contract's total ETH balance. As a result, the owner can only successfully withdraw the *exact total balance* of the contract, or attempts to withdraw more will revert due to insufficient funds during the `transfer` call. This prevents the owner from withdrawing partial amounts of ETH, severely hindering fund management.
FixChange the `require` statement to `require(amount <= address(this).balance, "Amount exceeds contract balance");` to allow the owner to withdraw any amount up to the contract's current ETH balance.
StatusUnresolved
Medium

Unchecked Return Value from External Calls

M-01The `mint` and `batchMint` functions perform external ETH transfers using `to.call{value: msg.value, gas: 2300}("")` and `recipients[i].call{value: ethAmounts[i], gas: 2300}("")` respectively. While the `success` boolean is assigned, it is not checked (`success;`). If the external call fails (e.g., the recipient contract reverts or runs out of the provided gas), the transaction will continue without reverting, potentially leading to a loss of ETH or an inconsistent state where tokens are minted but ETH is not transferred.
IssueThe `mint` and `batchMint` functions perform external ETH transfers using `to.call{value: msg.value, gas: 2300}("")` and `recipients[i].call{value: ethAmounts[i], gas: 2300}("")` respectively. While the `success` boolean is assigned, it is not checked (`success;`). If the external call fails (e.g., the recipient contract reverts or runs out of the provided gas), the transaction will continue without reverting, potentially leading to a loss of ETH or an inconsistent state where tokens are minted but ETH is not transferred.
FixAlways check the `success` boolean returned by low-level `call` functions and revert if the call was unsuccessful. For example: `(bool success,) = to.call{value: msg.value, gas: 2300}(""); require(success, "ETH transfer failed");`
StatusUnresolved
Low

Redundant `burn` Functions

L-01The contract includes four separate `burn` functions (`burn1`, `burn2`, `burn3`, `burn4`) that differ only by the number of `bytes32` data parameters they accept. The core logic within each function (checking `minAmount`, calling `_burn`, and emitting an event) is identical. This redundancy increases contract size, deployment costs, and reduces code maintainability without adding unique functionality.
IssueThe contract includes four separate `burn` functions (`burn1`, `burn2`, `burn3`, `burn4`) that differ only by the number of `bytes32` data parameters they accept. The core logic within each function (checking `minAmount`, calling `_burn`, and emitting an event) is identical. This redundancy increases contract size, deployment costs, and reduces code maintainability without adding unique functionality.
FixConsolidate these functions into a single `burn` function that accepts a dynamic array of `bytes32` or a single `bytes` parameter for the data, allowing for more flexible and efficient burning operations. For example: `function burn(uint256 amount, bytes calldata data) public { ... emit Burn(msg.sender, amount, data); }`
StatusUnresolved
Info

Low Gas Limit for External ETH Transfers

I-01The `mint` and `batchMint` functions use a fixed `gas: 2300` limit for external ETH transfers via `call`. While this low gas limit helps prevent reentrancy attacks, it also severely restricts the amount of computation a recipient smart contract can perform in its `receive` or `fallback` function. If a recipient contract requires more than 2300 gas to process the incoming ETH, the transfer will fail.
IssueThe `mint` and `batchMint` functions use a fixed `gas: 2300` limit for external ETH transfers via `call`. While this low gas limit helps prevent reentrancy attacks, it also severely restricts the amount of computation a recipient smart contract can perform in its `receive` or `fallback` function. If a recipient contract requires more than 2300 gas to process the incoming ETH, the transfer will fail.
FixEnsure that all intended recipients of ETH transfers are either EOAs or simple smart contracts that can handle incoming ETH with minimal gas. If interaction with complex smart contracts is expected, consider increasing the gas limit or using a different transfer mechanism, while carefully mitigating reentrancy risks.
StatusUnresolved
Info

Redundant `_decimals` Storage Variable

I-02The contract declares a `uint8 _decimals;` storage variable and sets it in the constructor. It then overrides the `decimals()` function to return this custom `_decimals`. While functional, the `ERC20` base contract from OpenZeppelin already manages an internal `_decimals` variable (defaulting to 18 if not specified). This creates a slight redundancy where the base contract's `_decimals` might be initialized but then ignored in favor of the custom one.
IssueThe contract declares a `uint8 _decimals;` storage variable and sets it in the constructor. It then overrides the `decimals()` function to return this custom `_decimals`. While functional, the `ERC20` base contract from OpenZeppelin already manages an internal `_decimals` variable (defaulting to 18 if not specified). This creates a slight redundancy where the base contract's `_decimals` might be initialized but then ignored in favor of the custom one.
FixTo avoid potential confusion or redundancy, consider if the custom `_decimals` variable is strictly necessary. If the intent is to simply set the decimals for the ERC20 token, it can often be done by passing the desired decimals to the `ERC20` constructor directly if it supports it, or by ensuring the overridden `decimals()` function correctly interacts with the inherited `_decimals` if it's exposed or intended to be used.
StatusUnresolved

Category Ratings

TechnicalMedium6/10

The contract utilizes robust OpenZeppelin libraries for ERC20, Ownable, and ERC20Permit, providing a solid foundation for token functionality (7.2 Code Security). Access control for minting, ETH withdrawal, and ownership transfers is correctly implemented using `onlyOwner` (7.3 Access Control). However, a critical logical flaw in the `withdrawEth` function prevents the owner from withdrawing arbitrary amounts of ETH, only allowing withdrawal of the exact total balance (7.8 Operations). Furthermore, the `mint` and `batchMint` functions do not check the success of external ETH transfers, potentially leading to silent failures (7.2 Code Security). Redundant `burn` functions also increase contract size and complexity (7.1 Architecture).

GovernanceHigh1/10

The contract's economic model is straightforward, with an owner-controlled `minAmount` for burning and owner-only minting capabilities (7.4 Economic). The `Ownable` pattern provides clear administrative control over critical functions, including token supply management and ETH withdrawal (7.5 Governance). The owner can update the `minAmount` and transfer ownership, which are standard and expected privileges for an `Ownable` token (7.5 Governance).

UpgradesHigh3/10

The contract is not designed with an upgrade mechanism (e.g., proxy pattern), meaning its logic is immutable once deployed (7.7 Upgrades). This eliminates upgrade-specific risks such as proxy misconfigurations or logic bugs introduced during upgrades. Any future changes would require a new deployment and migration.

Security Checklist

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

Holder Composition

8.1% in wallets65.1% in contracts
Effective Concentration34.1%

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 Holder99.1%
Top-3 Unlocked100.0%

Key Addresses

Deployer
0xb5b0…8fd8
Unlocked LP Held By
0x7d27…fd550x7a0c…6154

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 an EOA (single private key)
  • Mintable supply — no cap found, dilution unbounded
  • Top-10 concentration > 30% (73.2% total → 34.1% effective; 8.1% in EOAs, 65.1% in contracts — moderate)
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • LP top1 unlocked holder = 99.1% (independent LP — depth risk, pool = 96% of DEX liquidity)
  • LP top3 unlocked holders = 100.0% (independent LP — depth risk, pool = 96% of DEX liquidity)
  • 1 High finding(s) from audit
  • 1 Medium finding(s) from audit
  • 1 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

XMAQUINA (DEUS)Critical RiskTownsCritical RiskGAME by Virtuals (GAME)Critical RiskRecallCritical RiskVANRYCritical RiskRIZEHigh Risk

Would You Like a More Detailed Audit of ICP?

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

Get Detailed Audit