Core Contracts

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

A user can be forced to repay his loan by an attacker by frontrunning his call to (deposit new nft)depositNFT when he his slightly below the Collateral health factor

Summary

User are allowed to depositNFT tokens as collaterals for their loan but in an extreme case when a users collateral price drops and he is slightly below the 1e18 health factor, the user can try to deposit a new NFT to increase his collateral ratio but an attacker can front run this call and make users account marked for liquidation and this cannot be unremoved unless the user repays this loan or face liquidation.

Vulnerability Details

Attacker can frontrun user's deposit to initiate liquidation

// LIQUIDATION FUNCTIONS
/**
* @notice Allows anyone to initiate the liquidation process if a user's health factor is below threshold
* @param userAddress The address of the user to liquidate
*/
function initiateLiquidation(address userAddress) external nonReentrant whenNotPaused {
if (isUnderLiquidation[userAddress]) revert UserAlreadyUnderLiquidation();
// update state
ReserveLibrary.updateReserveState(reserve, rateData);
UserData storage user = userData[userAddress];
uint256 healthFactor = calculateHealthFactor(userAddress); // good
@audit>> if (healthFactor >= healthFactorLiquidationThreshold) revert HealthFactorTooLow(); // very good
@audit>> isUnderLiquidation[userAddress] = true;
@audit>> liquidationStartTime[userAddress] = block.timestamp;
emit LiquidationInitiated(msg.sender, userAddress);
}

Even though the user is able to deposit and get his health factor above the liquidation point the position still remain marked as liquidatablea and only debt repayment alone can reverse this action. Forcing the user to repay to avoid losing his collateral.

/**
* @notice Allows a user to repay their debt and close the liquidation within the grace period
*/
function closeLiquidation() external nonReentrant whenNotPaused {
address userAddress = msg.sender;
@audit>> if (!isUnderLiquidation[userAddress]) revert NotUnderLiquidation();
// update state
ReserveLibrary.updateReserveState(reserve, rateData);
if (block.timestamp > liquidationStartTime[userAddress] + liquidationGracePeriod) {
revert GracePeriodExpired();
}
UserData storage user = userData[userAddress];
uint256 userDebt = user.scaledDebtBalance.rayMul(reserve.usageIndex);
@audit>> if (userDebt > DUST_THRESHOLD) revert DebtNotZero();
isUnderLiquidation[userAddress] = false;
liquidationStartTime[userAddress] = 0;
emit LiquidationClosed(userAddress);
}

Without repaying the debt to a value below DUST user will face liquidation .

Impact

Attacker can force a user to repay his loan by frontrunning his call to deposit funds

Tools Used

Manual Review

Recommendations

When a user deposits if they have a position check to ensure the health factor is now above 1e18 and set the liquidation mapping to set and time to 0.

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Design choice
inallhonesty Lead Judge about 1 month ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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