Quantum Audit Logo

Is Dai Stablecoin Safe?

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

Dai Stablecoin DAI
0xda10…0da1
Arbitrum Not verifiedLast checked 3d ago 1 audit on record
Executive SummaryAI Copilot

The audit of the Dai Stablecoin contract revealed critical vulnerabilities related to unchecked arithmetic operations, which could lead to incorrect token balances and total supply. Additionally, significant centralization risks exist due to the 'ward' access control mechanism, particularly concerning the ability of authorized wards to burn any user's tokens without explicit approval. The contract implements standard ERC-20 functionality along with EIP-2612 permit, but inconsistent application of safe arithmetic functions poses a severe threat to the token's integrity. Recommendations focus on addressing these arithmetic flaws and mitigating centralization risks.

1 Critical1 High1 Medium3 Informational
Volume 24h
$222.4K
Liquidity
$94.6K
Price
$0.9997
Token Age
3y
Top 10 Holders
36.2%

Security Findings

Critical

Unchecked Arithmetic Operations Leading to Integer Overflow/Underflow

C-01Several critical arithmetic operations within the contract do not utilize the provided safe arithmetic functions (`_add`, `_sub`), exposing the contract to integer overflow and underflow vulnerabilities. Specifically: 1. Additions to `balanceOf[to]` in `mint`, `transfer`, and `transferFrom` (`balanceOf[to] = balanceOf[to] + value;`) are unchecked and can overflow. 2. Subtraction from `totalSupply` in `burn` (`totalSupply = totalSupply - value;`) is unchecked and can underflow if `totalSupply` is less than `value` (even if `balanceOf[from]` is sufficient). This can lead to incorrect token balances, total supply, and potentially loss of funds or system instability. (7.2 Code Security)
IssueSeveral critical arithmetic operations within the contract do not utilize the provided safe arithmetic functions (`_add`, `_sub`), exposing the contract to integer overflow and underflow vulnerabilities. Specifically: 1. Additions to `balanceOf[to]` in `mint`, `transfer`, and `transferFrom` (`balanceOf[to] = balanceOf[to] + value;`) are unchecked and can overflow. 2. Subtraction from `totalSupply` in `burn` (`totalSupply = totalSupply - value;`) is unchecked and can underflow if `totalSupply` is less than `value` (even if `balanceOf[from]` is sufficient). This can lead to incorrect token balances, total supply, and potentially loss of funds or system instability. (7.2 Code Security)
FixAll arithmetic operations involving token balances, total supply, and allowances must consistently use the `_add` and `_sub` internal functions or a battle-tested `SafeMath` library to prevent overflows and underflows. Ensure that every addition and subtraction is protected by these safe arithmetic checks.
StatusUnresolved
High

Centralized Ward Can Burn Any User's Tokens Without Approval

H-01The `burn` function's logic allows an authorized ward (`wards[msg.sender] == 1`) to bypass the allowance check when burning tokens from any address (`from`), even if `from` is not `msg.sender`. This means a ward can unilaterally burn tokens belonging to any user without their explicit approval, which is a significant centralization risk and deviates from standard ERC-20 `burnFrom` behavior. (7.3 Access Control, 7.4 Economic)
IssueThe `burn` function's logic allows an authorized ward (`wards[msg.sender] == 1`) to bypass the allowance check when burning tokens from any address (`from`), even if `from` is not `msg.sender`. This means a ward can unilaterally burn tokens belonging to any user without their explicit approval, which is a significant centralization risk and deviates from standard ERC-20 `burnFrom` behavior. (7.3 Access Control, 7.4 Economic)
FixModify the `burn` function to strictly enforce allowance checks for all `burnFrom` operations. If the intent is for wards to have privileged burning capabilities, this should be clearly documented, and a more robust governance mechanism (e.g., multi-signature approval) should be implemented for such sensitive actions to mitigate the risk of abuse or compromise.
StatusUnresolved
Medium

Centralized Access Control for Core Token Operations

M-01The contract utilizes a centralized access control mechanism based on a `wards` mapping and an `auth` modifier. The deployer is initially the sole ward, with the power to add or remove other wards via `rely` and `deny` functions. Critical operations like `mint` are restricted to these authorized wards. This centralization creates a single point of failure; a compromise of a ward's private key could lead to unauthorized token minting or administrative control. (7.3 Access Control, 7.5 Governance)
IssueThe contract utilizes a centralized access control mechanism based on a `wards` mapping and an `auth` modifier. The deployer is initially the sole ward, with the power to add or remove other wards via `rely` and `deny` functions. Critical operations like `mint` are restricted to these authorized wards. This centralization creates a single point of failure; a compromise of a ward's private key could lead to unauthorized token minting or administrative control. (7.3 Access Control, 7.5 Governance)
FixConsider implementing a multi-signature wallet (e.g., Gnosis Safe) for the `wards` addresses to distribute control and reduce the single point of failure risk. For highly sensitive operations like `mint`, explore adding time-locks or a more decentralized governance mechanism if aligned with the project's long-term vision.
StatusUnresolved
Info

Missing ERC-20 `decimals()` Function

I-01The contract defines `decimals` as a public constant `uint8`, which makes its value accessible. However, it does not implement the `decimals()` function as explicitly specified in the ERC-20 standard. While functionally equivalent for many applications, some tools or interfaces might expect the function call. (7.1 Architecture)
IssueThe contract defines `decimals` as a public constant `uint8`, which makes its value accessible. However, it does not implement the `decimals()` function as explicitly specified in the ERC-20 standard. While functionally equivalent for many applications, some tools or interfaces might expect the function call. (7.1 Architecture)
FixAdd a `function decimals() external view returns (uint8)` that simply returns the `decimals` constant to ensure full ERC-20 compliance and broader compatibility with ecosystem tools.
StatusUnresolved
Info

Redundant `_DOMAIN_SEPARATOR` Calculation in `permit` Function

I-02The `permit` function recalculates the EIP-712 domain separator using `_calculateDomainSeparator(chainId)` if the current `chainId` differs from `deploymentChainId`. While this handles chain forks correctly, the contract already stores `_DOMAIN_SEPARATOR` as an immutable variable and provides a public `DOMAIN_SEPARATOR()` view function that performs the same conditional check. The `permit` function could potentially reuse the existing `DOMAIN_SEPARATOR()` function or the stored `_DOMAIN_SEPARATOR` after its own `chainId` check, avoiding redundant computation. (7.2 Code Security)
IssueThe `permit` function recalculates the EIP-712 domain separator using `_calculateDomainSeparator(chainId)` if the current `chainId` differs from `deploymentChainId`. While this handles chain forks correctly, the contract already stores `_DOMAIN_SEPARATOR` as an immutable variable and provides a public `DOMAIN_SEPARATOR()` view function that performs the same conditional check. The `permit` function could potentially reuse the existing `DOMAIN_SEPARATOR()` function or the stored `_DOMAIN_SEPARATOR` after its own `chainId` check, avoiding redundant computation. (7.2 Code Security)
FixOptimize the `permit` function to reuse the `DOMAIN_SEPARATOR()` function or the stored `_DOMAIN_SEPARATOR` directly after its `chainId == deploymentChainId` check, to avoid unnecessary recalculation and improve gas efficiency.
StatusUnresolved
Info

Restrictive `transfer` and `transferFrom` to `address(this)` Check

I-03The `transfer` and `transferFrom` functions explicitly prevent transfers to `address(this)` (the token contract itself) with the check `require(to != address(0) && to != address(this), 'Dai/invalid-address');`. While preventing transfers to `address(0)` is standard, disallowing transfers to the token contract might be overly restrictive depending on future protocol designs. Some DeFi protocols or token mechanisms might intentionally send tokens to the token contract for specific purposes (e.g., burning, staking, or locking). (7.1 Architecture)
IssueThe `transfer` and `transferFrom` functions explicitly prevent transfers to `address(this)` (the token contract itself) with the check `require(to != address(0) && to != address(this), 'Dai/invalid-address');`. While preventing transfers to `address(0)` is standard, disallowing transfers to the token contract might be overly restrictive depending on future protocol designs. Some DeFi protocols or token mechanisms might intentionally send tokens to the token contract for specific purposes (e.g., burning, staking, or locking). (7.1 Architecture)
FixReview if the restriction `to != address(this)` is absolutely necessary for all current and anticipated use cases. If there are scenarios where sending tokens to the contract itself is desired or could be beneficial, this check should be removed or made conditional. Otherwise, clearly document this design choice and its implications.
StatusUnresolved

Category Ratings

TechnicalMedium5/10

The contract implements core ERC-20 functionalities and EIP-2612 permit, including a robust EIP-712 domain separator calculation. It also provides internal `_add` and `_sub` functions for safe arithmetic. However, a critical technical flaw is the inconsistent application of these safe arithmetic functions, leading to unchecked additions and subtractions in `balanceOf` and `totalSupply` updates (7.2 Code Security). This exposes the contract to integer overflow and underflow vulnerabilities, which can corrupt token balances and total supply. The `burn` function also contains an unchecked subtraction for `totalSupply` (7.2 Code Security).

GovernanceHigh1/10

The contract employs a centralized 'ward' access control system, where the deployer is initially the sole administrator, capable of adding or removing other wards (7.3 Access Control). This centralization extends to critical operations like `mint`, which is restricted to wards. A significant economic risk is present in the `burn` function, where an authorized ward can burn tokens from any address without requiring prior allowance, deviating from standard ERC-20 `burnFrom` behavior and creating a powerful, centralized control point over user funds (7.4 Economic, 7.5 Governance).

UpgradesHigh2/10

The contract is not designed as an upgradeable proxy and does not implement any upgrade mechanisms. Therefore, there are no specific upgrade-related risks inherent in its architecture (7.7 Upgrades). Any future changes would require a new deployment and migration.

Security Checklist

Contract VerifiedPass
Ownership Renounced?
No Mint FunctionFail
Liquidity LockedFail
Not a ProxyPass

Holder Composition

15.6% in wallets20.6% in contracts
Effective Concentration23.8%

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

Show 2 more pairsShow less

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 Holder78.5%
Top-3 Unlocked97.8%

Key Addresses

Deployer
0x075d…5250
Unlocked LP Held By
0xea32…010d0x9023…9d700x3750…0d7b0x47c0…596c0xbb96…7da20x671a…8b5e0xdd95…7c630x3086…30980x6c81…f94c0x2cd5…6d4c

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

What Raised This Score

  • Ownership status UNKNOWN (owner could not be resolved)
  • Mintable supply — no cap found, dilution unbounded
  • Top-10 concentration > 20% (36.2% total → 23.8% effective; 15.6% in EOAs, 20.6% in contracts — mild)
  • Liquidity not locked, but no owner/deployer address holds LP — market-depth risk, not rug risk
  • LP top1 unlocked holder = 78.5% (independent LP — depth risk, pool = 52% of DEX liquidity)
  • LP top3 unlocked holders = 97.8% (independent LP — depth risk, pool = 52% of DEX liquidity)
  • 1 Critical finding(s) from audit
  • 1 High finding(s) from audit
  • 1 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

Related Audits

Aethir Token (ATH)High RiskArbitrum Intern (INTERN)High RiskChipCritical RiskCurve DAO Token (CRV)High RiskCoinbase Wrapped BTC (CBBTC)Critical RiskODYSHigh Risk

Would You Like a More Detailed Audit of Dai Stablecoin?

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

Get Detailed Audit