Core Contracts

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

Deposit Failure in Stability Pool Due to Fee-On-Transfer Token and Strict Balance Check

Summary

The depositRAACFromPool function in the Stability Pool fails when transferring RAAC tokens because RAAC is a fee-on-transfer token. The current implementation assumes that the entire amount will be transferred, but due to swap and burn taxes applied during the transfer, the actual amount received is lower. This discrepancy triggers the strict balance check, causing the transaction to revert every time.

Vulnerability Details

Root Cause:
The RAACToken applies a 1% swap tax and 0.5% burn tax during transfers:

function _update(
address from,
address to,
uint256 amount
) internal virtual override {
uint256 baseTax = swapTaxRate + burnTaxRate;
// Skip tax for whitelisted addresses or when fee collector disabled
if (baseTax == 0 || from == address(0) || to == address(0) || whitelistAddress[from] || whitelistAddress[to] || feeCollector == address(0)) {
super._update(from, to, amount);
return;
}
// All other cases where tax is applied
uint256 totalTax = amount.percentMul(baseTax);
uint256 burnAmount = totalTax * burnTaxRate / baseTax;
@-> super._update(from, feeCollector, totalTax - burnAmount);
@-> super._update(from, address(0), burnAmount);
@-> super._update(from, to, amount - totalTax);
}

Issue in depositRAACFromPool:
The post-transfer balance check expects the full amount:

function depositRAACFromPool(uint256 amount) external onlyLiquidityPool validAmount(amount) {
uint256 preBalance = raacToken.balanceOf(address(this));
raacToken.safeTransferFrom(msg.sender, address(this), amount);
uint256 postBalance = raacToken.balanceOf(address(this));
@-> if (postBalance != preBalance + amount) revert InvalidTransfer();
// TODO: Logic for distributing to managers based on allocation
emit RAACDepositedFromPool(msg.sender, amount);
}

However, since the RAACToken contract deducts the tax during the transfer, the actual tokens received by the Stability Pool are amount - totalTax. This mismatch causes the InvalidTransfer() revert.

Impact

  • Liquidity Disruption:
    The inability to deposit RAAC tokens hampers the liquidity provisioning process, affecting the overall protocol stability.

  • Complete Deposit Failure:

    All deposit attempts revert due to the strict equality check, rendering the Stability Pool non-functional for RAAC token deposits.

Tools Used

Manual Review

Recommendations

  • Adjust Balance Check to Use Actual Received Amount :

Instead of assuming the full amount is received, compare pre- and post-transfer balances dynamically:

function depositRAACFromPool(uint256 amount) external onlyLiquidityPool validAmount(amount) {
uint256 preBalance = raacToken.balanceOf(address(this));
raacToken.safeTransferFrom(msg.sender, address(this), amount);
uint256 postBalance = raacToken.balanceOf(address(this));
-- if (postBalance != preBalance + amount) revert InvalidTransfer();
++ uint256 actualReceived = postBalance - preBalance;
++ if (actualReceived == 0) revert InvalidTransfer(); // Ensure some amount was received
// Proceed with actualReceived instead of amount
emit RAACDepositedFromPool(msg.sender, actualReceived);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!