sherlock-audit / 2023-12-ubiquity-judging

2 stars 2 forks source link

blutorque - Underflow in `freeCollateralBalance()` may possibly DoS the AMO minters contract, #166

Closed sherlock-admin2 closed 7 months ago

sherlock-admin2 commented 8 months ago

blutorque

medium

Underflow in freeCollateralBalance() may possibly DoS the AMO minters contract,

Summary

File: IUbiquityPool.sol

/**
 * @notice Returns free collateral balance (i.e. that can be borrowed by AMO minters)
 * @param collateralIndex collateral token index
 * @return Amount of free collateral
 */
function freeCollateralBalance(
    uint256 collateralIndex
) external view returns (uint256);

It is mentioned in comment above that the freeCollateralBalance return the available collateral balance that can be borrowed by AMO minters. However, if the call encounters an underflow, it can potentially cause an issue with external protocol that utilize this value to borrow collateral out of ubiquity pool.

ok, so how it is possible that it'll underflow? there can be possibly more than one AMO minters for a collateral, and also there is no cap on their borrow amount. If even either one of them borrows collateral such that the current balance of collateral exceed unclaimedPoolCollateral, it'll results in underflow.

Vulnerability Detail

See above.

Impact

External AMO minters(smart contract) requiring freeCollateralBalance to be >0 will failed to borrow, bc of underrflow. Also the ubiquity pool collateralUsdBalance() using it internally, which will be DoS.

Code Snippet

https://github.com/sherlock-audit/2023-12-ubiquity/blob/main/ubiquity-dollar/packages/contracts/src/dollar/libraries/LibUbiquityPool.sol#L574-L598 https://github.com/sherlock-audit/2023-12-ubiquity/blob/main/ubiquity-dollar/packages/contracts/src/dollar/libraries/LibUbiquityPool.sol#L256 https://github.com/sherlock-audit/2023-12-ubiquity/blob/main/ubiquity-dollar/packages/contracts/src/dollar/libraries/LibUbiquityPool.sol#L268-L276

Tool used

Manual Review

Recommendation

Modify freeCollateralBalance to below;

function freeCollateralBalance(
    uint256 collateralIndex
) internal view returns (uint256) {
    UbiquityPoolStorage storage poolStorage = ubiquityPoolStorage();
    if(IERC20(poolStorage.collateralAddresses[collateralIndex]).balanceOf(address(this)) 
            <= poolStorage.unclaimedPoolCollateral[collateralIndex]) return 0; 
    return
        IERC20(poolStorage.collateralAddresses[collateralIndex])
            .balanceOf(address(this))
            .sub(poolStorage.unclaimedPoolCollateral[collateralIndex]);
}

Duplicate of #1