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: 37/72
Findings: 1
Award: $8.28
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 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 function mintRebasingOUSG()
invokes an internal function _mint()
which returns ousgAmountOut
which then is converted to rousgAmountOut
and transferred to the msg.sender
in exchange of usdcAmountIn
. Since there is an exchange / conversion of assets, users must be protected from slippage.
function mintRebasingOUSG( uint256 usdcAmountIn ) external override nonReentrant whenMintNotPaused returns (uint256 rousgAmountOut) { uint256 ousgAmountOut = _mint(usdcAmountIn, address(this)); ousg.approve(address(rousg), ousgAmountOut); rousg.wrap(ousgAmountOut); rousgAmountOut = rousg.getROUSGByShares( ousgAmountOut * OUSG_TO_ROUSG_SHARES_MULTIPLIER ); // @audit there should be slippage protection after this line rousg.transfer(msg.sender, rousgAmountOut); emit InstantMintRebasingOUSG( msg.sender, usdcAmountIn, ousgAmountOut, rousgAmountOut ); }
It is important to note that the minimum deposit amount is 100_000
USDC. Hence, recurring slippages of small percentages is a huge issue.
// Minimum amount of USDC that must be deposited to mint OUSG or rOUSG // Denoted in 6 decimals for USDC uint256 public minimumDepositAmount = 100_000e6;
Manual Review
Parameterize rousgAmountOutMin
and if rousg.getROUSGByShares()
returns rousgAmountOut
that is lower than rousgAmountOutMin
, the function should revert.
function mintRebasingOUSG( uint256 usdcAmountIn, ++ uint256 rousgAmountOutMin ) external override nonReentrant whenMintNotPaused returns (uint256 rousgAmountOut) { uint256 ousgAmountOut = _mint(usdcAmountIn, address(this)); ousg.approve(address(rousg), ousgAmountOut); rousg.wrap(ousgAmountOut); rousgAmountOut = rousg.getROUSGByShares( ousgAmountOut * OUSG_TO_ROUSG_SHARES_MULTIPLIER ); ++ if (rousgAmountOut < rousgAmountOutMin) revert SlippageProtection(); rousg.transfer(msg.sender, rousgAmountOut); emit InstantMintRebasingOUSG( msg.sender, usdcAmountIn, ousgAmountOut, rousgAmountOut ); }
Also, there should be a calculation preview of what amount of rousgAmountOut
to expect so that the user can input the acceptable rousgAmountOutMin
value.
Other
#0 - c4-pre-sort
2024-04-04T03:04:28Z
0xRobocop marked the issue as duplicate of #250
#1 - c4-pre-sort
2024-04-04T23:00:04Z
0xRobocop marked the issue as duplicate of #156
#2 - c4-judge
2024-04-09T07:55:29Z
3docSec marked the issue as satisfactory
#3 - 3docSec
2024-04-11T07:02:10Z
Does not mention the redeem flow, and the mint function, 25% credit
#4 - c4-judge
2024-04-11T07:02:15Z
3docSec marked the issue as partial-25
#5 - c4-judge
2024-04-11T15:13:13Z
3docSec changed the severity to QA (Quality Assurance)
#6 - c4-judge
2024-04-11T15:14:59Z
3docSec marked the issue as grade-b