Open code423n4 opened 2 years ago
I would argue this is intended functionality. See EIP 4266 which tries to formalize this some. It is known that only the Reserve Ratio (%) of the pool will be available.
Agree with sponsor in this case. The user can at least redeem some shares if he wanted to. Would be a bank run scenario. Downgrading to QA.
Warden doesn't have QA report.
Lines of code
https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathToken.sol#L597-L605
Vulnerability details
https://github.com/code-423n4/2022-05-rubicon/blob/8c312a63a91193c6a192a9aab44ff980fbfd7741/contracts/rubiconPools/BathToken.sol#L756-L759
In the current implementation,
totalAssets
isIERC20(underlyingToken).balanceOf(address(this))
+outstandingAmount
.However, when there are some
outstandingAmount
, the actual redeemable amount of underlyingToken is less thanunderlyingBalance()
.As a result, when a user tries to redeem a larger amounts of shares, the transaction can revert due to insufficient balance.
PoC
Given:
BathTokenA
= USDTBathTokenA
Pool, got10,000 * 1e18
sharesBathTokenA
= 10,000 USDTplaceMarketMakingTrades
on Pair, place a offer:pay_amt
= 1,000 1e18,buy_gem
= USDC,buy_amt
= 1,000 1e6BathTokenA
= 9,000 USDToutstandingAmount
= 1,000 * 1e189,500 * 1e18
shares, the transaction will revert.Recommendation
Consider allowing the caller to trigger order cancelling when the balance in the contract is not enough for the withdrawal.
Furthermore, consider find a way to make the rebalancing permissionless so that the stake holders can always get back what they are owned without any centrialized roles.