AmoMinterBorrow can DoS the pool by causing an underflow state
Summary
The amoMinterBorrow function in the UbiquityPool contract can lead to a underflow state in the pool's collateral balance.
Vulnerability Detail
This function allows an AMO minter to borrow collateral from the pool without accounting for the unclaimedPoolCollateral, which is increased everytime a user redeem Dollar tokens.
This can create a scenario where the total collateral balance collateral.balanceOf(address(this)) becomes less than the unclaimedPoolCollateral.
This discrepancy leads to an arithmetic underflow in functions like redeemDollar, mintDollar, and collateralUsdBalance.
Impact
Once this underflow state is entered, there's 2 ways to exit it:
1) directly transfer collateral tokens to the contract to make its balance > unclaimedPoolCollateral
2) Users who redeemed call collectRedemption until unclaimedPoolCollateral < balance. Until then, its not possible to mint or redeem.
Add this test to UbuiquityPoolFacet.t.sol to reproduce the issue
function test_auditAmoBrickPool() public {
address alice = makeAddr("alice");
uint256 collateralIndex = 0;
// vm.prank(address(dollarAmoMinter));
//setting read-convenient configuration
vm.startPrank(admin);
ubiquityPoolFacet.setPriceThresholds(
1000000, // mint threshold
1000000 // redeem threshold
);
ubiquityPoolFacet.setFees(
0, // collateral index
0, // 1% mint fee
0 // 2% redeem fee
);
vm.stopPrank();
// balance setup of users
uint256 depositAlice = 1000;
collateralToken.mint(alice, depositAlice);
vm.prank(alice);
collateralToken.approve(address(ubiquityPoolFacet), type(uint).max);
//Alice borrows, she sends collateral to the which increase the collateral balance of the pool
vm.prank(alice);
(uint256 totalDollarMintAlice, /*uint256 collateralNeeded*/) =
ubiquityPoolFacet.mintDollar(collateralIndex, depositAlice, 0, type(uint).max);
//Alice redeem its Dollars, which increases the unclaimedPoolCollateral
vm.prank(alice);
ubiquityPoolFacet.redeemDollar(collateralIndex, totalDollarMintAlice, 0);
//AmoMinter borrow some collateral, which decrease the collateral balance of the pool
vm.prank(address(dollarAmoMinter));
ubiquityPoolFacet.amoMinterBorrow(1);
//this set a state where collateral.balanceOf(address(this)) < (poolStorage.unclaimedPoolCollateral[collateralIndex])
//creating a situation of underflow in redeemCollateral, mintDollar and collateralUsdBalance
bytes memory arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11);
vm.expectRevert(arithmeticError);
vm.prank(alice);
ubiquityPoolFacet.redeemDollar(collateralIndex, 0, 0);
vm.expectRevert(arithmeticError);
vm.prank(alice);
ubiquityPoolFacet.mintDollar(collateralIndex, depositAlice, 0, type(uint).max);
vm.expectRevert(arithmeticError);
ubiquityPoolFacet.collateralUsdBalance();
}
Tool used
Manual Review
Recommendation
Make sure AmoMinter can only borrow amounts up to balance - unclaimedPoolCollateral
infect3d
high
AmoMinterBorrow can DoS the pool by causing an underflow state
Summary
The
amoMinterBorrow
function in the UbiquityPool contract can lead to a underflow state in the pool's collateral balance.Vulnerability Detail
This function allows an AMO minter to borrow collateral from the pool without accounting for the
unclaimedPoolCollateral
, which is increased everytime a user redeem Dollar tokens.This can create a scenario where the total collateral balance
collateral.balanceOf(address(this))
becomes less than theunclaimedPoolCollateral
. This discrepancy leads to an arithmetic underflow in functions likeredeemDollar
,mintDollar
, andcollateralUsdBalance
.Impact
Once this underflow state is entered, there's 2 ways to exit it: 1) directly transfer collateral tokens to the contract to make its
balance > unclaimedPoolCollateral
2) Users who redeemed callcollectRedemption
untilunclaimedPoolCollateral < balance
. Until then, its not possible to mint or redeem.Code Snippet
https://github.com/sherlock-audit/2023-12-ubiquity/blob/main/ubiquity-dollar/packages/contracts/src/dollar/libraries/LibUbiquityPool.sol#L438-L443 https://github.com/sherlock-audit/2023-12-ubiquity/blob/main/ubiquity-dollar/packages/contracts/src/dollar/libraries/LibUbiquityPool.sol#L372 https://github.com/sherlock-audit/2023-12-ubiquity/blob/main/ubiquity-dollar/packages/contracts/src/dollar/libraries/LibUbiquityPool.sol#L268-L276 https://github.com/sherlock-audit/2023-12-ubiquity/blob/main/ubiquity-dollar/packages/contracts/src/dollar/libraries/LibUbiquityPool.sol#L256
Add this test to UbuiquityPoolFacet.t.sol to reproduce the issue
Tool used
Manual Review
Recommendation
Make sure AmoMinter can only borrow amounts up to
balance - unclaimedPoolCollateral
Duplicate of #1