Decurity Logo

2025 Recap:
A Year of Old Hacks and Rounding Exploits

Defimon monitors blockchain activity 24/7, catching malicious on-chain behavior that signals potential exploits. Throughout 2025, we observed that Defimon detected hundreds of incidents - ranging from low-impact issues to major losses.

This recap covers 10 major DeFi exploits that caught our attention. We looked back at each case to see why 2025 turned out to be a year of old code and rounding issues. We'll also highlight the most unusual hack of the year and share insights from Defimon's public Telegram channel.

Here's what went down in 2025.

Notable Incidents

1

Balancer V2

$121M

On November 3, 2025, Balancer V2 suffered the largest smart contract exploit of the year - approximately $121M were stolen across Ethereum, Arbitrum, Base, Optimism, and Polygon.

The vulnerability was in the _swapGivenOut() function, which called _upscale() to normalize token amounts for decimal precision. The problem was that _upscale() used FixedPoint.mulDown(), always rounding down regardless of swap direction.

function _upscale(uint256 amount, uint256 scalingFactor) internal pure returns (uint256) {
    return FixedPoint.mulDown(amount, scalingFactor);
}
In normal pools, this rounding is barely noticeable. But Composable Stable Pools embedded dynamic token rates from rate providers (like wstETH → stETH conversions) into the scaling factor. This turned negligible rounding into exploitable precision loss.

The key rule was violated: rounding is supposed to favor the protocol, not the user. By rounding down the output amount, the pool understated the required input payment. Each swap reduced the pool's invariant without the pool realizing the user had taken more.

The attacker deployed a calculation contract to identify precise token amounts where rounding errors compounded most severely. They then flash-minted BPT tokens through Balancer's composability, drained pools to minimal liquidity (pushing balances to extreme edge cases), and executed micro-swaps targeting these precision cliffs. Swaps of minimal token amounts caused substantial precision loss. By repeating micro-swaps within single transactions, they compounded tiny errors into massive invariant collapse without triggering safeguards.

2

Resupply.fi

$9.8M

On June 26, 2025, Resupply lost nearly $9.8M in an ERC-4626 first deposit attack. The attack unfolded in just 95 minutes after a new cvcrvUSD vault was deployed.

The newly deployed wstUSR market went live at 00:18 UTC with an empty crvUSD Curve Vault. Just 95 minutes later at 01:53 UTC, an attacker using a 4,000 USDC flash loan from Morpho, converted the funds to crvUSD and exploited the empty vault's initialization bug. The attack flow was to donate 2,000 crvUSD directly to the empty vault contract, then deposit 2 crvUSD to mint just 1 wei of cvcrvUSD shares.

This single wei of shares now represented the entire 2,000+ crvUSD deposit, creating a massively inflated price-per-share of approximately 2e36.

The vulnerability was in the ResupplyPair contract's _updateExchangeRate() function. It calculated the exchange rate using:

_exchangeRate = 1e36 / IOracle(_exchangeRateInfo.oracle).getPrices(address(collateral))
When the oracle returned the inflated price (exceeding 1e36), Solidity's integer division rounded down the result to zero. The contract didn't check that the exchange rate was greater than zero, which allowed an invalid value to be stored.

The zero exchange rate was used by the _isSolvent() function, which calculates the LTV ratio by:

_ltv = ((_borrowAmount * _exchangeRate * LTV_PRECISION) / EXCHANGE_PRECISION) / _collateralAmount
A zero exchange rate broke the LTV check, making every position look solvent. Using just 1 wei of collateral, the attacker borrowed 10 million reUSD tokens.

Apparently the attacker monitored governance proposals and noticed an empty vault in the configuration parameters of the new market - the same pattern as in Compound fork hacks, e.g. Sonne Finance and Onyx.

3

Yearn finance

$9M

On November 30, 2025, Yearn Finance's yETH pool was exploited for approximately $9M. The attack targeted a specialized liquidity pool designed for trading liquid staking tokens. By depositing only 16 wei, the attacker was able to mint an abnormally large amount of yETH due to a calculation flaw.

The vulnerability stemmed from numerical instability in the pool's Newton-Raphson solver used to calculate the AMM invariant. When the attacker executed extreme imbalanced deposits, the solver's iteration logic failed - the product term collapsed to zero while the invariant remained inflated, breaking the fundamental mathematical relationship between these values.

This allowed the attacker to drain the pool to near-zero supply while actual token balances remained. They then deposited just 16 wei. This triggered the supply calculation with corrupted state variables. Because the contract's cached balance variables still held stale values from before the drain, the calculation treated the 16 wei as if it represented millions in liquidity.

The fatal blow came in the supply calculation function, which used unchecked subtraction assuming one term would always exceed another. Instead of reverting, the subtraction underflowed, wrapping to the maximum uint256 value and minting an abnormally large amount of yETH shares to the attacker.

4

Bunni V2

$8.3M

On September 2, 2025, Bunni V2 was exploited, losing $2.4M on Ethereum and $5.9M on UniChain. The vulnerability was in precision accounting within BunniHook's liquidity rebalancing logic.

Bunni V2 functions as a liquidity hook built on top of Uniswap V4, using a custom Liquidity Distribution Function (LDF) to rebalance pools after trades and maintain correct token ratios. This extra complexity made precision bugs possible.

The bug was in the LDF's swap rebalancing calculations. During swaps, the function miscalculated balance deltas due to rounding errors. These errors accumulated with each trade, giving the attacker an advantage.

The attacker used flash loans to perform precisely sized exact-input swaps on token pairs. Each swap triggered the LDF logic, which accumulated small miscalculations. By repeating trades that triggered rebalancing, the attacker made these errors grow.

5

KiloEx

$7.5M

On April 14, 2025, an attacker exploited an access control vulnerability in KiloEx's MinimalForwarder contract. The bug allowed the attacker to impersonate a trusted Keeper and manipulate oracle prices.

The exploit hit multiple chains - Base ($3.3M), opBNB ($3.1M), and BSC ($1M), draining in total $7.5M.

The core vulnerability was a missing access control check in the MinimalForwarder contract. The execute() function allowed users to pass a from address and a signature, but failed to validate that the recovered signer matched the from address in the payload. This allowed the attacker to forge signatures while specifying a trusted Keeper's address in the from field.

function setPrices(address[] calldata tokens, uint256[] calldata prices) external onlyKeeper {
	require(tokens.length == prices.length, "KiloPriceFeed: length not match");
	for (uint256 i; i < tokens.length; ) {
		address token = tokens [i];
		priceMap[token] = prices[i];
		lastUpdatedTimes[token] = block.timestamp;
		emit PriceSet(token, prices[i], block.timestamp);
		unchecked {
			++i;
		}
	}
	lastUpdatedTime = block.timestamp;
}

KiloEx's price oracle system had layered access controls requiring setPrices() to be called through multiple contracts. By bypassing the forwarder's authentication, the attacker chained privileged calls through all contracts with Keeper-level privileges. The attacker manipulated ETH prices - dropping them to ~$100, opening leveraged long positions, inflating prices to ~$10,000, then immediately closing positions for profit. The attacker used this same approach on all affected chains.

6

1inch

$5M

On March 5, 2025, an attacker exploited a vulnerability in the old 1inch Settlement contract. The bug was in the order suffix processing - a calldata corruption issue that let the attacker overwrite the resolver address and call arbitrary resolver.

At 05:31 PM UTC, an alert appeared in the Defimon Telegram channel. The exploit targeted Fusion V1, deprecated since mid-2023 but left active for backward compatibility. TrustedVolumes, a market maker, lost funds when the attacker manipulated order data to swap 6 wei USDT for 1,000,000 USDC with the victim's contract unknowingly footing the bill.

The vulnerability was in the _settleOrder function where the suffix offset was calculated in an unsafe manner: ptr + interactionOffset + interactionLength. The attacker set interactionLength to an invalid value (0xffff...fe00 = -512), causing an overflow. This decreased the pointer, writing the suffix to a different place. The attacker padded the order with null-bytes and added a fake suffix structure as an interaction. As a result, the real suffix was written to the padding before the fake suffix, and the interaction structure was treated as a suffix. This allowed the attacker to overwrite the resolver address field, call the victim's resolveOrders function, and transfer arbitrary amounts of arbitrary tokens to complete the fraudulent swap.

After Defimon's alert at 05:31 PM, Decurity joined 1inch's war room by 06:10 PM. The attacker sent an on-chain message asking for a bounty at 06:34 PM. By 11:59 PM, negotiations concluded successfully, and by 04:12 AM on March 6, nearly all funds were returned, with the attacker keeping a bounty.

A detailed post-mortem is available in our blog: https://blog.decurity.io/yul-calldata-corruption-1inch-postmortem-a7ea7a53bfd9

7

Arcadia

$3.6M

On July 15, 2025, Arcadia Finance lost $3.6M on Base blockchain.

The vulnerability was in _swapViaRouter() function, which accepted arbitrary router address through the swapData parameter without any validation. The function performed a low-level call to the provided router:

(bool success, bytes memory result) = router.call(data);

Because this call executed from within the Rebalancer contract, the router saw msg.sender == Rebalancer. In Arcadia's architecture, ArcadiaAccount contracts maintain a whitelist of authorized AssetManager addresses - typically including the Rebalancer. As a result, any contract called from the Rebalancer's context inherited elevated privileges.

The attacker exploited this trust assumption by registering their own malicious contract as both the router and a whitelisted Arcadia account. They then called rebalance() with controllable swapData pointing to their malicious router. When router.call(data) executed, the attacker's contract gained Rebalancer-level privileges and could perform unauthorized operations.

8

Shibarium bridge

$2.7M

On September 12, 2025, the Shibarium bridge connecting Shiba Inu's Layer 2 network to Ethereum was exploited for approximately $2.7M.

The attacker used a flash loan to borrow 4.6M BONE tokens and temporarily gained control over 10 out of 12 network validator keys. With a two-thirds majority secured, they could approve any transaction they wanted. Shibarium's bridge required only 8 validator signatures to approve state checkpoints - the attacker had 10.

The exploit drained various assets: ETH, SHIB, KNINE, LEASH, and smaller amounts of other tokens. The attack was executed in two transactions, methodically extracting funds across multiple token types.

However, the attack was poorly executed. K9 Finance DAO blacklisted the attacker's address, freezing about $700K in KNINE tokens. The 4.6M BONE used in the flash loan remained locked in validator staking. About half of the stolen funds became permanently unspendable.

9

Abracadabra

$1.8M

On October 4, 2025, Abracadabra Money's old Cauldron V4 contracts on Ethereum were exploited for approximately $1.8M. At 13:30 UTC, an alert appeared in the Defimon Telegram channel. This was the protocol's third attack in less than two years, after $6.5M in January 2024 and $13M in March 2025.

The core of the vulnerability lies in the cook() function in the PrivilegedCauldronV4 and PrivilegedCheckpointCauldronV4 contracts. This function is a multi-action batching mechanism that allowed users to perform multiple operations (deposits, borrows, repayments) within a single transaction. But the way it handled these steps (actions) had a bug, which the attacker used to bypass the usual solvency checks and drain funds.

The cook() function processed an array of encoded actions sequentially, using a CookStatus struct to track whether a solvency check was needed:

struct CookStatus {
    bool needsSolvencyCheck;
    bool hasAccrued;
}

Each action is identified by a unique numeric id (e.g., ACTION_CUSTOM = 0, ACTION_BORROW = 5). When Action 5 executed, it correctly set needsSolvencyCheck = true to enforce collateral verification. However, the vulnerability was in _additionalCookAction(), which handled undefined or custom actions like Action 0. For unknown action IDs, this function returned a default-initialized CookStatus struct, resetting needsSolvencyCheck to false. This meant any prior borrow flag was cleared.

The attacker called cook() with actions [5, 0] across several CauldronV4 contracts. Action 5 borrowed funds from protocol and set the solvency flag, then Action 0 reset the flag through the _additionalCookAction() function. The final solvency check was skipped, allowing the attacker to borrow funds without any collateral.

10

Silo Finance

$545K

On June 25, 2025, an attacker exploited a vulnerability in Silo Finance's LeverageUsingSiloFlashloanWithGeneralSwap contract. The bug allowed borrowing funds without any actual collateral by providing a fake Silo contract address.

The vulnerability was in the openLeveragePosition() function, which contained user-controllable input without proper validation. The function allowed users to specify a Silo contract address that was controllable by anyone. By providing a fake Silo contract, the attacker borrowed funds without any actual collateral.

function openLeveragePosition(
	FlashArgs calldata _flashArgs,
        bytes calldata _swapArgs,
        DepositArgs calldata _depositArgs
    )
        public
        payable
        virtual
        whenNotPaused
        nonReentrant
        setupTxState(_depositArgs.silo, LeverageAction.Open, _flashArgs.flashloanTarget)
    {
        _txMsgValue = msg.value;

        require(IERC3156FlashLender(_flashArgs.flashloanTarget).flashLoan({
            _receiver: this,
            _token: ISilo(_flashArgs.flashloanTarget).asset(),
            _amount: _flashArgs.amount,
            _data: abi.encode(_swapArgs, _depositArgs)
        }), FlashloanFailed());
    }

The Most Unusual Hack of the Year

We also wanted to highlight the Synthetics Implemented Right (SIR) hack as one of the most interesting this year.

On March 30, 2025, Synthetics Implemented Right has been hacked for $355k. The vulnerability was in the Vault contract's uniswapV3SwapCallback function, which used transient storage to verify caller. The function loaded a Uniswap pool address from storage slot 0x1 and checked it against msg.sender.

At the end of execution, uniswapV3SwapCallback stores the value of the variable in the same slot 0x1.

/**
* @dev This callback function is required by Uniswap pools when making a swap.\n
* This function is exectuted when the user decides to mint TEA or APE with debt token.\n
* This function is in charge of sending the debt token to the uniswwap pool.\n
* It will revert if any external actor that is not a Uniswap pool calls this function.
*/
function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external {
    // Check caller is the legit Uniswap pool
    address uniswapPool;
    assembly {
        uniswapPool := tload(1)
    }
    require(msg.sender == uniswapPool);

. . .

    // Rest of the mint logic
    require(collateralToDeposit <= type(uint144).max);
    uint256 amount = _mint(minter, ape, vaultParams, uint144(collateralToDeposit), vaultState, reserves);

    // Transfer debt token to the pool
    // This is done last to avoid reentrancy attack from a bogus debt token contract
    if (!isETH) {
        TransferHelper.safeTransferFrom(vaultParams.debtToken, minter, uniswapPool, debtTokenToSwap);
    }

    // Use the transient storage to return amount of tokens minted to the mint function
    assembly {
        tstore(1, amount)
    }

Since the value of amount can be controlled externally, one has to find such an amount that will point to a controllable address. The attacker had to bruteforce a specific address, mint an exact token amount and manipulate transient storage.



The hacker bruteforced a vanity address 0x00000000001271551295307acc16ba1e7e0d4281 (corresponding to amount=95759995883742311247042417521410689) and minted precisely this number of tokens. They then manipulated the execution flow so this amount value overwrote the Uniswap pool address in slot 0x1. Finally, they deployed a contract at the bruteforced address using CREATE2 and called uniswapV3SwapCallback from it, passing the verification check and draining the vault.

This attack involved a new EVM feature - the transient storage which was meant to be used in the reentrancy guards. It's the kind of exploit that demonstrates why security in DeFi requires thinking out of the box.

Community Insights:
A Year in the Defimon Channel

Beyond catching exploits, Defimon's public Telegram channel has become a real hub for security folks to discuss threats, share analysis, and exchange insights in real-time. In 2025, we posted 1,958 messages that racked up 734,192 views and thousands of reactions, comments, and forwards.

Here's what captured the community's attention this year.

Total Activity

  • 📝 1,958 messages posted
  • 👁️ 734,192 total views
  • 😊 1,633 reactions
  • 💬 1,228 comments
  • ↗️ 2,442 forwards

Top Community Reactions

  • 😁 (262 times)
  • 🤣 (172 times)
  • 😈 (124 times)
  • ❤️ (113 times)
  • 🔥 (69 times)

Most Discussed Incidents

Most Forwarded Alerts

Most Reacted Messages

Zooming out

Looking back at 2025's exploit landscape, several patterns stand out clearly.

Consider the timeline: Abracadabra's vulnerable code was audited in November 2023. Yearn's yETH pool received its audit in June 2023. Balancer's attack vector existed since July 2021. These protocols weren't unaudited - they were audited years ago when the threat landscape looked completely different.

Back in 2021-2023, audits focused heavily on access control and reentrancy vulnerabilities. Rounding issues were reported, but rarely flagged as critical. Why? Because there were no major exploits demonstrating their severity. That changed in 2023-2024 when Hundred Finance and Onyx were exploited through first-deposit and donation attacks exploiting precision loss. Rounding errors that seemed small at first became vulnerabilities with multi-million dollar impact.

Deprecated code remains a significant risk. The 1inch and Abracadabra exploits targeted contracts that were no longer actively maintained but still operational. These old contracts continued processing transactions, leaving them exposed to attacks.

Precision-related vulnerabilities are increasingly exploited. As protocols implement more complex mathematical operations, such as weighted stableswaps, liquidity distribution functions, and dynamic rate providers - small rounding errors can result in significant losses.

There is a high chance that AI tools have become increasingly popular among the hackers to uncover these bugs. The pattern suggests that hackers meticulously analyze old contracts using AI which may explain the spike of the hacks of the old contracts.

Stay safe onchain!

For real-time security monitoring and incident alerts, follow Defimon on Telegram.