Closed c4-bot-4 closed 3 months ago
OOS
Rebasing Precision Issue - rOUSG is a rebasing tokens and some precision can be lost when wrapping and unwrapping. We expect this to only result in extremely small precision discrepancies. However, if one can find a realistic usage of the contracts that results in a non-trivial amount of imprecision, it would be valid.
0xRobocop marked the issue as insufficient quality report
3docSec marked the issue as unsatisfactory: Out of scope
Lines of code
https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/rOUSG.sol#L431-L443
Vulnerability details
Users can wrap
OUSG
tokens intorOUSG
tokens by callingrOUSG::wrap
and unwrap them by callingrOUSG::unwrap
. The functionunwrap()
will convert the amount given on the argument, i.e.rOUSG
tokens, to shares in order to burn those shares and transfer theOUSG
tokens to the user. The calculations are the following:$$ \begin{aligned} \text{ousgSharesAmount} &= rOUSGAmount \times \frac{sharesMultiplier \times 1e18}{oUSGPrice} \\ \text{ousgTokensAmount} &= \frac{ousgSharesAmount}{sharesMultiplier} \end{aligned} $$
The value of
ousgTokensAmount
will be the amount ofOUSG
tokens that the contract will send the user that is unwrapping therOUSG
tokens.Because solidity rounds down by default, the value of
ousgTokensAmount
will be rounded down. This is because the value ofoUSGPrice
will always be higher than1e18
, in fact, will always be higher than105e18
, as per theousgInstantManager
contract indicates.Therefore, after a user wraps and unwraps some tokens, some tokens will be left at the
rOUSG
contract. This amount may be tiny in a single unwrap operation, but it will become increasingly large over time. This will lead to a significant amount ofoUSG
tokens being stuck at therOUSG
contract as time passes.Impact
Over time,
OUSG
tokens will get stuck on therOUSG
contract.Proof of Concept
The
unwrap
function, the two indicated lines of code is where the rounding down happens:https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/rOUSG.sol#L431-L443
And the
getSharesByROUSG
function is always rounding down because theOUSG
price will always be bigger than1e18
. In fact, it will always be higher than105e18
, as per theousgInstantManager
contract.https://github.com/code-423n4/2024-03-ondo-finance/blob/main/contracts/ousg/rOUSG.sol#L363-L368
Tools Used
Manual Review
Recommended Mitigation Steps
It's recommended to create a special function for the protocol team to rescue the stuck
OUSG
tokens from therOUSG
contract.Assessed type
Math