Resupply crvUSD-wstUSR Market Post Mortem
June 28th, 2025

Summary

  • A sophisticated exploit against Resupply's crvUSD-wstUSR pair created $10M of reUSD bad debt.

  • The vulnerability was unique to that specific pair. No other pairs are affected, and all Resupply markets continue to operate as usual.

  • The protocol guardian has set the debt limit to 0 on the affected pair and paused insurance pool withdrawals, with a formal governance vote required to unpause.

  • The exploit flow involved inflation of the CurveLend collateral shares, but differed from a classical "inflation attack" as it was carefully designed to nullify a borrower solvency check.

  • The section of code containing the issue was within scope for multiple security audits and independent researchers who were hired to review the codebase. None reported the issue.

  • Users are encouraged to visit the Resupply governance forums for updates on next steps.

Background

  • Resupply accepts ERC-4626 vault shares (CurveLend / FraxLend) as CDP collateral.

  • Oracles price vault shares via convertToAssets(), treating crvUSD and frxUSD as 1:1 with reUSD.

  • Resupply makes use of an Insurance Pool (IP) designed to facilitate liquidations and backstop bad debt across all pairs.

Attack Timeline

  • 2025-06-26 00:18:47 UTC — crvUSD-wstUSR pair deployed with a $10M debt limit; underlying CurveLend vault held 0 deposits.

  • 2025-06-26 01:53:59 UTC — Attack contract deployed and exploit executed (~1 h 35 m later).

  • 2025-06-26 02:53:23 UTC - Protocol guardian pauses affected pair.

Exploit Flow

  • Because the Curvelend vault had no deposits, it made it possible for the attacker to dramatically manipulate the share price, making 1 wei of shares worth 2e18 crvUSD by:

    • donating 2,000e18 crvUSD to the vault's controller (which holds vault funds)

    • depositing 2e18 crvUSD to mint 1 wei of vault shares

  • While share price manipulation is a critical step in this attack, it alone is not a problem for the Resupply oracle, as the true value of the shares is tracked correctly.

  • Unlike a traditional "inflation attack", the attack relied on triggering the following edge case in the smart contract logic:

    1. The oracle uses a hardcoded 1e18 shares parameter to correctly price the shares:

      _price = IERC4626(_vault).convertToAssets(1e18); // returns 2e36
      
      
    2. The pair then calculates the reUSD exchangeRate using the following evm math, which rounds to 0.

      exchangeRate = 1e36 / oracle.getPrices(collateral); // 1e36 / 2e36 floors to 0
      
      
      
    3. While an exchange rate of 0 in the previous step may appear harmless, it is relied upon in the following solvency check during each borrow operation:

      function _isSolvent(address _borrower, uint256 _exchangeRate) internal view returns (bool) {
          ...
          uint256 _ltv = ((_borrowerAmount * _exchangeRate * LTV_PRECISION) / EXCHANGE_PRECISION) / _collateralAmount;
          return _ltv <= _maxLTV; // _ltv = 0 ➔ always solvent
      }
      
      
      

      The multiplication by 0 breaks solvency check by causing the user's LTV to resolve to 0, thus causing _isSolvent() to return true regardless of the attacker's actual loan to value ratio.

  • This sequence of logic allowed the attacker to borrow up to the pair's full 10M reUSD debt limit.

Actions

  • The protocol guardian has paused the affected pair, setting its borrow limit to 0.

  • The Resupply treasury has used treasury funds to repay 643,051 reUSD debt

  • A new interest rate calculator was added to the pair to set its interest rate to 0%, preventing interest from accumulating on the bad debt.

  • The withdrawal timer window has been set to zero, temporarily blocking insurance pool assets from exiting until a governance proposal is passed.

  • A permissionless share burner contract has been deployed, funded, and used to trustlessly ensure all Resupply pairs are safe from a similar attack.

Next Steps

  • A formal governance proposal will facilitate the disposition of insurance pool assets, and to unblock the funds.

  • Stolen funds remain on-chain. The situation is being monitored and necessary steps are being taken.

  • Patch ResupplyPairCore.sol and ResupplyPairDeployer.sol to permanently defend against this form of attack.

References

Subscribe to Resupply
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.
More from Resupply

Skeleton

Skeleton

Skeleton