Case Study: BSC Dual-Token Burn System Audit — Unauthorized Token Destruction and Cascading Failure Risk
Executive Summary
This project implements a dual-token ecosystem with a 5-year automated burn schedule. Three contracts manage two ERC-20 tokens and a scheduled burn mechanism that progressively reduces supply over 60 monthly intervals with declining burn rates per year.
The architecture uses OpenZeppelin v5 (ERC20, ERC20Pausable, SafeERC20, Ownable2Step, AccessControl) and is generally well-structured. However, two high-severity findings emerged: a function that burns tokens from any holder's wallet without requiring ERC-20 allowance approval, and a cascading failure where one token hitting its burn floor blocks all burns for both tokens atomically.
29 raw findings were identified across two independent analysis passes. After deduplication, cross-checking, and adversarial falsification review, 13 were confirmed and 5 were disproved — including claims about a vesting bypass that referenced a previous contract version no longer deployed.
Risk Assessment
This is a well-intentioned project with sound tokenomics, but the two high-severity issues must be resolved before mainnet. The unauthorized burn mechanism is incompatible with trustless integrations, and the cascading burn failure could stall the entire token economy near the end of its 5-year schedule. Both fixes are straightforward.
Key Findings
Token Burns Without ERC-20 Allowance — Unauthorized Token Destruction
What We Found
A privileged function can burn tokens directly from any holder's wallet without requiring the standard approve/transferFrom flow. The holder never consents. The owner can unilaterally destroy anyone's tokens at any time, with no on-chain record of the holder agreeing.
Why It Matters
Token holders have zero on-chain protection against unauthorized burns. This makes the token incompatible with any trustless integration — DEX listings, lending protocols, or bridge contracts would all be at risk. Institutional holders and auditors will flag this as a deal-breaker.
What Should Be Done
Require the holder to approve a specific amount before any burn can execute. Use _spendAllowance before _burn so the standard ERC-20 allowance mechanism governs all token destruction. Alternatively, document prominently that this is a custodial-authority token where the operator retains burn control.
Cascading Burn Failure — One Token's Floor Blocks Both Burns
What We Found
The burn schedule executes burns for both tokens in a single transaction, one after the other. If the second token hits its minimum supply floor and reverts, the entire transaction fails — including the first token's burn that would have succeeded. Near the end of the 5-year schedule, this will reliably stall all burns.
Why It Matters
With approximately 10 months remaining in the schedule, the second token will approach its floor. Once it reverts, all remaining burns for both tokens stop. The deflationary mechanism — the core value proposition — breaks permanently.
What Should Be Done
Wrap each burn call in a try/catch block so one token hitting its floor does not block the other. Log the failure with an event so operators can see which token was skipped and why.
Dual Access Control — Role Transfer Not Synchronized with Ownership
What We Found
The contracts use two separate permission systems: one for ownership and one for role-based access. Transferring ownership does not automatically transfer the admin role, so the new owner may not have full control until roles are manually reassigned.
Why It Matters
During ownership transitions, there is a window where the new owner lacks administrative capability. If the previous owner becomes unavailable, critical role management could be permanently locked.
What Should Be Done
Override the ownership transfer function to automatically reassign the default admin role to the new owner.
Schedule Completes 25 Days Early — 1,800 Days, Not 5 Calendar Years
What We Found
The burn schedule runs 60 intervals of 30 days each. That is 1,800 days — 4 years, 11 months, and 5 days — not exactly 5 calendar years. Token holders expecting a full 5-year schedule will see it end earlier than communicated.
Why It Matters
Minor discrepancy between marketing materials claiming '5 years' and the on-chain reality of 1,800 days. Could create confusion or claims of misrepresentation.
What Should Be Done
Document that the schedule is 1,800 days (60 × 30-day intervals). This is an acceptable design choice — just ensure communications match.
Allowance Exhaustion Over Multi-Year Schedule
What We Found
The burn mechanism requires a pre-set allowance to burn tokens from the supply source. Over 60 months, this allowance can be exhausted if not set high enough, silently stalling all future burns.
Why It Matters
If the initial allowance is insufficient, burns will stop without warning. The deflationary mechanism fails silently.
What Should Be Done
Approve the maximum possible amount (type(uint256).max) or calculate and document the exact total approval needed for all 60 intervals.
Inline Access Check Instead of Modifier — Inconsistent Pattern
What We Found
One critical function checks permissions with an inline require statement instead of using the standard role-based modifier used everywhere else in the codebase.
Why It Matters
Functional behavior is identical, but the inconsistency makes the code harder to review and increases the chance of a permission check being missed in future modifications.
What Should Be Done
Acceptable for now. Document the reason for the dual-role check pattern.
Array Index Fragile If Schedule Constants Changed
What We Found
A year index calculation assumes exactly 60 months. If the total month constant were ever changed, the array access could go out of bounds and revert.
Why It Matters
Not exploitable with current constants, but a future developer modifying the schedule could trigger an unexpected revert.
What Should Be Done
Add a bounds check (require year < array length) as defense-in-depth.
Owner Can Pause All Transfers Indefinitely
What We Found
The pause mechanism has no timelock or automatic expiry. The owner can freeze all token transfers permanently with no on-chain recourse for holders.
Why It Matters
In an emergency this is the correct behavior, but without a timelock, holders must trust the owner not to abuse the pause.
What Should Be Done
Deploy with a multisig wallet as owner. Consider adding a maximum pause duration.
Single EOA Owner — Single Point of Failure
What We Found
The contract owner is a single wallet address. If the private key is lost or compromised, all administrative functions are permanently lost or stolen.
Why It Matters
Loss of the key means the contract can never be updated, paused, or administered again. Compromise means an attacker gains full control.
What Should Be Done
Deploy with a multisig wallet (e.g., Safe 2-of-3) as the owner.
Burn Math Rounding — 4 Tokens Off Over 60 Months
What We Found
Integer division rounding means the actual tokens burned differ from the target by exactly 4 tokens over the full 5-year schedule.
Why It Matters
Negligible — 4 tokens out of trillions. The final supply is within acceptable tolerance.
What Should Be Done
No fix needed. Document the rounding behavior.
No Emergency Stop for Burn Schedule
What We Found
Once the burn schedule starts, there is no pause button. The only way to stop burns in an emergency is to revoke the burn role on each token contract individually.
Why It Matters
In a critical situation, the emergency procedure requires multiple transactions across multiple contracts, increasing response time.
What Should Be Done
Document the emergency procedure clearly. Consider adding a single-transaction pause.
Missing Event Emission for Initial Configuration
What We Found
The constructor sets an important configuration value but does not emit an event, making it invisible to off-chain monitoring tools.
Why It Matters
No security risk. Slight inconvenience for monitoring and indexing.
What Should Be Done
Emit the configuration event in the constructor.
Privileged Burn Incompatible with DEX Liquidity Pools
What We Found
The unauthorized burn mechanism could theoretically burn liquidity pool tokens, which would drain a DEX pair. This is not applicable to this project's current design (no DEX listing planned), but would become critical if listing plans change.
Why It Matters
No current risk. Would become critical if the project adds exchange listings without redesigning the burn mechanism.
What Should Be Done
Document that any future DEX listing requires a redesign of the burn function.
What a Secure Contract Should Have
Disclaimer: This case study is published for educational purposes only. It reflects the state of the analyzed contract at the time of audit and does not constitute investment advice, an endorsement, or a guarantee of security. Smart contracts may be modified after an audit. HyperAudit is not liable for losses arising from interaction with any contract referenced in this report. Project names and addresses have been removed to protect ongoing remediation efforts. For a full audit of your own contracts, visit hyperaudit.io.
Building a project?
Get the same depth of analysis on your own contracts before you deploy. Reports delivered in hours, not weeks.
Audit Your ContractThinking about buying a token?
Before you buy, find out if the contract is safe. We can audit any token on any EVM chain and tell you exactly what risks you're taking — in plain language you can act on.
Check a Token Before You Buy