Platform: Code4rena
Start Date: 29/03/2024
Pot Size: $36,500 USDC
Total HM: 5
Participants: 72
Period: 5 days
Judge: 3docSec
Total Solo HM: 1
Id: 357
League: ETH
Rank: 8/72
Findings: 2
Award: $646.09
🌟 Selected for report: 1
🚀 Solo Findings: 0
637.8133 USDC - $637.81
The InstantManager contract restricts deposits and withdrawals to certain minimum amounts. Users can deposit a minimum of 100k USDC tokens, and withdraw a minimum of 50k USDC tokens.
The issue is that the minimum withdrawal limit can lead to users losing access to part of their funds. Say a user deposits 100k USDC tokens and then later withdraws 60k USDC tokens. Now, the user only has 40kUSDC worth holdings in their account, and cannot withdraw the full amount. This is because it falls below the minimum withdrawal limit of 50k USDC tokens. The user is now stuck with 40k USDC tokens in their account, and cannot withdraw them.
The only option the user has is to deposit 100k USDC more, and then withdraw the whole 140k USDC amount. This will incur fees on the extra 100k USDC the user brings as well. Thus this is a medium severity issue.
The scenario can be recreated in the following steps:
Manual Review
Allow users to remove all their funds from the contract even if it is below the minimum limit. Since the protocol now uses a more liquid system such as the BUIDL token, this should be possible and should not affect the protocol's functioning.
Other
#0 - c4-pre-sort
2024-04-04T23:49:50Z
0xRobocop marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-04-04T23:49:53Z
0xRobocop marked the issue as primary issue
#2 - 0xRobocop
2024-04-04T23:54:56Z
The worst impact is a temporary DoS over some users funds, admin can always change the limit. Leaving for sponsor review.
#3 - cameronclifton
2024-04-05T22:14:42Z
This is an obvious design decision and also assumes that there is no other ways for investors to redeem OUSG/rOUSG, which is not incorrect.
#4 - c4-sponsor
2024-04-05T22:14:44Z
cameronclifton (sponsor) disputed
#5 - 3docSec
2024-04-09T11:25:57Z
I acknowledge this behavior is a design decision.
I however would keep this as a valid medium for an audit report, because:
Allow users to remove all their funds from the contract even if it is below the minimum limit.
this mitigation seems feasible and difficult to exploit for systematic, abusive bypasses of minimumRedemptionAmount
, because both OUSG and rOUSG have a KYC requirement on token holders
#6 - c4-judge
2024-04-09T11:27:13Z
3docSec marked the issue as selected for report
#7 - c4-judge
2024-04-09T11:27:25Z
3docSec marked the issue as satisfactory
#8 - cameronclifton
2024-04-10T16:45:14Z
This finding is a feature suggestion to remove the minimum redemption amount. Having explicit minimum redemption and subscription amounts clearly implies that there could be conditions in which users would have a balance below the minimum and be unable to transact. Users are made well aware of these minimums. Users are also able to contact us directly should they need to redeem via other mechanisms.
Regarding the mitigation suggestion:
Allow users to remove all their funds from the contract even if it is below the minimum limit. Since the protocol now uses a more liquid system such as the BUIDL token, this should be possible and should not affect the protocol's functioning.
- I don't understand how this is can be assumed to be a reasonable mitigation without knowing the reason for why the minimum subscription and redemption amounts exists.
#9 - Henrychang26
2024-04-12T08:27:33Z
In setMinimumRedemptionAmount()
, minimumRedemptionAmount
can be set as low as FEE_GRANULARITY == 10_000
.
The max amount that can potentially be locked is 9,999 which is less than $0.1 approx $0.09999
To provide more context:
In setMinimumDepositAmount()
, minimumDepositAmount
can also be set as low as FEE_GRANULARITY
. The highest possible additional fee that may incur to put user over the minimumRedemptionAmount
in order to redeem()
, is 1.99%.
$0.1 x 0.0199 = $0.00199
#10 - thebrittfactor
2024-04-23T18:44:36Z
Per further discussion with the sponsor team, adding this final input on their behalf for inclusion in the report:
We will not be removing minimum redemption requirement from the smart contract as there are other means in which users can redeem OUSG or rOUSG tokens from Ondo Finance.
🌟 Selected for report: immeas
Also found by: 0xAkira, 0xCiphky, 0xGreyWolf, 0xJaeger, 0xMosh, 0xabhay, 0xlemon, 0xmystery, 0xweb3boy, Aamir, Abdessamed, Aymen0909, Breeje, DanielArmstrong, DarkTower, Dots, EaglesSecurity, FastChecker, HChang26, Honour, IceBear, JC, K42, Krace, MaslarovK, Omik, OxTenma, SAQ, Shubham, Stormreckson, Tigerfrake, Tychai0s, VAD37, ZanyBonzy, albahaca, arnie, ast3ros, asui, b0g0, bareli, baz1ka, btk, caglankaan, carrotsmuggler, cheatc0d3, dd0x7e8, grearlake, igbinosuneric, jaydhales, kaden, kartik_giri_47538, m4ttm, ni8mare, niser93, nonn_ac, oualidpro, pfapostol, pkqs90, popeye, radev_sw, samuraii77, slvDev, zabihullahazadzoi
8.2807 USDC - $8.28
The InstantManager
contract has a hardcoded MINIMUM_OUSG_PRICE
value of 105e18. The current price of OUSG tokens on coingecko is 105.63 USD, which is only 0.6% above the hardcoded value. The assumption is that the value of the token does not ever fall below 105 USD, below which the oracle is assumed to be misbehaving, and thus all operations are stopped.
function getOUSGPrice() public view returns (uint256 price) { (price,) = oracle.getPriceData(); require(price > MINIMUM_OUSG_PRICE, "OUSGInstantManager::getOUSGPrice: Price unexpectedly low"); }
The issue is that this is a very small margin of error. The funds in the contract will be deposited to the BUIDL fund. The contract already assumes that some USDC will remain unused in the contract, thus the APY realized by OUSG will be lower than the BUIDL fund.
Te BUIDL fund, according to the details available here, will invest 100% of its total assets in cash, U.S. Treasury bills, notes and other obligations issued or guaranteed as to principal and interest by the U.S. Treasury, and repurchase agreements secured by such obligations or cash. The Fund will invest, in both the primary and secondary markets, in U.S. Treasury bills, notes or other obligations that mature in three months or less from the settlement of the purchase.
While cash, notes and treasury bills are saef and can be assumed to never go down in value, repo (repurchase agreements) on secondary markets can have some level of risk associated with it, albeit very low. So there is a possibility that in the short term the fund can lose some value, enough to trigger the MINIMUM_OUSG_PRICE
check on the protocol here built on top of it. This would then lead to a DOS of the protocol, since all price operations will stop.
Assume the blackrock fund loses 0.6% of its value due to some unforseen circumstances. That will be enough to trigger the MINIMUM_OUSG_PRICE
check and stop all operations on the protocol. It is very unlikely that the fund will lose this value in the long term, however volatility in repo agreements in the short term are definitely possible.
Manual Review
Consider making the hardcoded value programmable. Or a lower more conservative limit like 104 USD would be more appropriate, which was the price of OUSG at the beginning of this year.
Other
#0 - c4-pre-sort
2024-04-04T05:51:42Z
0xRobocop marked the issue as duplicate of #245
#1 - c4-judge
2024-04-09T13:01:21Z
3docSec changed the severity to QA (Quality Assurance)
#2 - c4-judge
2024-04-09T13:02:06Z
3docSec marked the issue as grade-b