Back to Blog

~$3.87M Lost: Autheo Network, UNCX Hacks | BlockSec Weekly

Code Auditing
October 22, 2026
9 min read
Key Insights
  • This report covers 3 notable security incidents with approximately $3.87M in total estimated losses. The incidents involved a private key compromise, a vesting-accounting error, and weak wallet seed generation.

  • UNCX Network's Smart Token Vesting V2 incident affected 10 assets across Ethereum, BNB Chain, Base, and Robinhood Chain. A flawed aggregate share calculation mixed vesting tranches created at different token-to-share ratios, enabling approximately $807K in realized or routed value to be extracted.

  • Pooled accounting must preserve the relationship between each tranche's token amount, share basis, and vesting progress. Combining them under one ratio can let one position overdraw the shared balance, reducing the assets available to satisfy other positions.

During the past week (2026/10/12 - 2026/10/18), the following 3 notable security incidents are featured, with a total estimated loss of approximately $3.87M.

Date Incident Type Estimated Loss
2026/10/12 Autheo Network Private Key Compromise ~$1.76M
2026/10/14 UNCX Network Accounting Error ~$807K
2026/10/18 Qubic Wallet Weak Seed Generation ~$1.30M

The loss figures are estimates based on realized value.

  • UNCX Network: This incident is analyzed in detail because its flawed aggregate share calculation provides the week's clearest contract-accounting lesson.

Free Security Scan

A quick security pass with our in-house automated analysis engine.

Scan for free

Weekly Highlight: UNCX Network

On October 14, 2026, attackers exploited UNCX Network's Smart Token Vesting V2 contracts across Ethereum, BNB Chain, Base, and Robinhood Chain. The incident affected 10 assets in 11 confirmed drain transactions and resulted in approximately $807,609 in realized or routed value [1]. The root cause was a flawed aggregate share calculation that mixed vesting tranches created at different token-to-share ratios. This caused position-level records to diverge from the global share supply, allowing attacker-controlled positions to withdraw more tokens than the attackers had supplied.

Background

UNCX Network is a multi-chain DeFi infrastructure provider whose Smart Token Vesting V2 product lets projects lock ERC-20 tokens behind time-based vesting schedules. Each schedule is represented by a vesting ID and records the token, creator, beneficiary, total amount, amount already released, and one or more unlock tranches. A soft, top-up-enabled position can receive additional tranches after creation, while its creator can cancel the unvested portion.

Positions for the same token share one balance in the VestingManager, and the protocol uses shares to determine how much of that balance each position owns. Its accounting therefore has two related layers:

Global pool, per token
  create / topUp: receive tokens and mint shares
  release: convert releasable shares into tokens
  _totalTokenShares[token]: active shares across all positions

Position record, per vesting ID
  _depositedShares[id]: share basis assigned to the position
  totalAmount: token amount represented by its tranches
  released: shares already paid to the beneficiary

For a release, the manager first calculates how much of the schedule is vested. It converts that fraction of totalAmount into vested shares using _depositedShares[vestingId], subtracts released, and calls the result releasableShares. In the formula below, tokenBalance is the manager's current ERC-20 balance for the schedule's token, shared across every position for that token, while _totalTokenShares[token] is the corresponding global supply of active shares. The token payout depends on their ratio:

amount = releasableShares * tokenBalance / _totalTokenShares[token]

Depositing through the vesting functions increases both token balance and share supply. A direct ERC-20 transfer to the manager changes only the token balance, so it changes the number of tokens represented by each share. This share model can support pooled positions only if every lifecycle operation keeps the position records and global supply reconciled.

Vulnerability Analysis

The affected Ethereum VestingManager at 0xA98F...99F5 contains a flawed aggregate share calculation that becomes exploitable across release(), topUpVesting(), and cancel(). Equivalent affected deployments exist on the other three networks.

To make the state changes easier to compare, the analysis below introduces D, R, and V as shorthand. These symbols do not appear in the contract code; the table maps each one to the corresponding contract variable or expression. The mapped values fall into two quantity types:

Symbol Contract variable / expression Quantity type Meaning
D _depositedShares[vestingId] Share quantity Cumulative share basis assigned to all deposits recorded for the position
R schedule.released Share quantity Cumulative shares already paid out to the beneficiary
- schedule.totalAmount Token amount Total token amount recorded across the position's current tranches
- vestedAmount Token amount Portion of totalAmount that has vested under those tranches at the current time
V vestedShare Share quantity Cumulative vested shares computed by applying one blended vested-token ratio to D

In release(), the contract calculates releasableShares, increments schedule.released, and subtracts the same quantity from _totalTokenShares[schedule.token]. It does not reduce _depositedShares[vestingId]. After a release, the position therefore contributes only D - R live shares to the global supply, even though its stored basis remains D.

function release(uint256 vestingId) external nonReentrant {
    ...
    uint256 releasableShares = _getReleasableShares(vestingId);
    uint256 balance = IERC20(schedule.token).balanceOf(address(this));
    uint256 amount =
        (releasableShares * balance) / _totalTokenShares[schedule.token];

    schedule.released += releasableShares;
    _totalTokenShares[schedule.token] -= releasableShares;
    IERC20(schedule.token).safeTransfer(msg.sender, amount);
}

cancel() applies one blended vesting ratio to the position's aggregate share basis. It first calculates vestedAmount through getVestedAmount(vestingId), then converts the token-denominated vested fraction into shares as V = (vestedAmount * D) / totalAmount. Finally, the function treats D - V as the position's removable unvested shares. V is a cumulative value, not the vested shares remaining after previous payouts.

function cancel(uint256 vestingId) external nonReentrant {
    ...
    uint256 vestedAmount = getVestedAmount(vestingId);
    uint256 remainingAmount = schedule.totalAmount - vestedAmount;

    uint256 vestedShare =
        vestedAmount * _depositedShares[vestingId] / schedule.totalAmount;
    uint256 sharesToRemove =
        _depositedShares[vestingId] - vestedShare;
    _totalTokenShares[schedule.token] -= sharesToRemove;

    _depositedShares[vestingId] = vestedShare;
    schedule.totalAmount = vestedAmount;
    schedule.cancelled = true;

    IERC20(schedule.token).safeTransfer(schedule.creator, remainingAmount);
}

The flaw is the blended calculation itself. Each tranche has its own token amount, vesting progress, and number of shares minted at the pool ratio in effect when that tranche was added. Its vested shares should therefore be calculated separately and then summed. Instead, the contract aggregates the token amounts and share basis first, then applies one vesting ratio to the combined position because it stores only one D and one totalAmount. The two approaches are equivalent only when the tranches have the same share-per-token ratio or the same vesting progress. A direct token transfer changes the pool ratio before a top-up, so the new tranche receives far fewer shares per token than the original tranche. Applying one blended vesting ratio across both tranches can then produce a V that no longer represents their combined vested shares.

Because R has already been paid out from the position's cumulative vested shares, a consistent schedule must satisfy R <= V. Violating this inequality is the direct symptom of the blended calculation. The code does not maintain a separate live-share balance for the position; it subtracts D - V directly from the global _totalTokenShares. Suppose other positions contribute 1,000 shares, while this position has D = 100 and R = 80. Before cancellation, the global supply contains 1,000 + (D - R) = 1,020 shares. If the blended calculation produces V = 60, cancel() subtracts D - V = 40 and leaves only 980 global shares, 20 fewer than the 1,000 shares contributed by the other positions. If the global supply contained only this position's 20 live shares, subtracting 40 would underflow and revert; the excess deduction succeeds only because the shared pool contains shares contributed by other positions. The function then stores _depositedShares[vestingId] = 60 while schedule.released remains 80, leaving the position record in the impossible state D < R.

The code neither enforces R <= V nor caps sharesToRemove at the position's live shares. Cancellation can therefore subtract historical shares that are no longer part of the global supply. At the same time, it transfers totalAmount - vestedAmount directly in token units, without converting the refund through the pool's share ratio. Cancellation itself does not produce an excess payout; it only reduces the global share supply below the live shares recorded across positions, creating the condition for a later over-redemption.

Attack Analysis

The following analysis uses one representative Ethereum transaction, 0x352065...c23823. The attack contract executed the same core sequence against five tokens within the transaction, using flash liquidity for each token.

  • Step 1: The attacker created a small immediately vested position, #5058, and two much larger immediately vested, soft, top-up-enabled positions, #5059 and #5060. The small position would be retained for the final withdrawal, while the large positions supplied the historical share records needed to corrupt global accounting.

  • Step 2: The attacker released the two large positions. At the initial near-1:1 pool ratio, each release returned approximately its net deposit. The corresponding shares left _totalTokenShares, but the original values remained in the _depositedShares records for positions #5059 and #5060 and were recorded as released only in each schedule's separate released field.

  • Step 3: The attacker transferred tokens directly to the VestingManager. This restored token balance without restoring the released shares, so the amount of tokens represented by each remaining share rose sharply.

  • Step 4: The attacker topped up the already released large positions. Because the top-ups were priced at the newly elevated token-per-share ratio, substantial token deposits minted only a small number of new shares. The positions now combined a large stale historical basis with a small live share contribution.

  • Step 5: The attacker cancelled the two topped-up positions. Each cancellation applied one blended vesting ratio to the aggregate deposited-share history. The recomputed vestedShare fell below the shares already released, so sharesToRemove exceeded the position's live contribution. The global supply was reduced by roughly 5.0e25 phantom shares per position, even though each position had added only a small amount of live shares during the top-up.

  • Step 6: With the denominator severely understated, the attacker released the small retained position. In the worked token example, a net deposit of approximately 5.73e22 raw units withdrew approximately 1.07e26 raw units, about 1,873 times the deposit. The attacker repeated create-and-release cycles against the distorted ratio and repaid the flash liquidity.

The official incident report identified the same pattern across 11 confirmed drain transactions. Some variants completed atomically, while others performed the final release in a linked transaction. UNCX calculated the approximately $807,609 figure from realized or routed proceeds after excluding attacker principal, temporary flash volume, and returned assets [1].

Get Started with Phalcon Explorer

Dive into Transactions to Act Wisely

Try now for free

Conclusion

The root cause was flawed aggregate share accounting. The protocol combined tranches created at different token-to-share ratios, then applied one vesting ratio to their aggregate share basis. This miscalculated cumulative vested shares, allowed a position to remove more shares than it still contributed, and caused position-level records to diverge from the global share supply. The attackers exploited the understated global supply to withdraw tokens from the shared balance that remained necessary to satisfy other vesting positions.

An accounting model that permits later deposits at changing share ratios should preserve each tranche's token amount, share basis, and vesting progress instead of blending them under one ratio. It should also enforce that cumulative payouts never exceed cumulative vested shares and that a position cannot remove more than its live contribution.

References

[1] UNCX Network Smart Token Vesting V2 Incident Report

Best Security Auditor for Web3

Validate design, code, and business logic before launch

Sign up for the latest updates
~$542K Lost: MakerDaoBot Exploit | BlockSec Weekly
Security Insights

~$542K Lost: MakerDaoBot Exploit | BlockSec Weekly

This report covers 1 security incident on Ethereum from 2026/10/05 - 2026/10/11, with an estimated loss of approximately $542K. An attack contract deployed a malicious adapter and passed it to a MakerDaoBot function that lacked access control, causing the bot to grant the adapter permission over its internal MakerDAO balances. The adapter settled four legacy ETH-A auctions and converted 200 units of ETH-A collateral to WETH; the attack contract unwrapped it and sent 200 ETH to the attacker.

~$418M Lost: Bitget, NEAR Intents Exploits | BlockSec Weekly
Security Insights

~$418M Lost: Bitget, NEAR Intents Exploits | BlockSec Weekly

This biweekly security report records eight incidents from September 21 to October 4, 2026, with approximately $418.4M in losses across Ethereum, BNB Chain, Solana, Bitcoin, TRON, XRP Ledger, Zcash, Avalanche, NEAR, and related networks. Detailed analysis covers Bitget's $387.5M third-party security product vulnerability and NEAR Intents' $3.87M refund validation flaw and missing state rollback.

Bitget's $387.5M Off-Chain Breach: Beyond Keys and Contracts
Security Insights

Bitget's $387.5M Off-Chain Breach: Beyond Keys and Contracts

On September 24, 2026, attackers exploited a vulnerability in a third-party security product, obtained internal credentials, and forged withdrawal commands. The resulting transfers moved approximately $387.5M from some of Bitget's operational wallets across Ethereum, other EVM networks, XRP Ledger, Zcash, and TRON; private keys and cold wallets remained intact. This deep dive summarizes the disclosed incident path and fund flow, examines rapid conversion into native assets and the ecosystem recovery response, proposes a systematic defense-in-depth framework for institutions, and explains how authorized blockchain penetration testing can validate cross-layer assumptions.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit