Platform: Code4rena
Start Date: 11/01/2023
Pot Size: $60,500 USDC
Total HM: 6
Participants: 69
Period: 6 days
Judge: Trust
Total Solo HM: 2
Id: 204
League: ETH
Rank: 36/69
Findings: 1
Award: $36.24
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: CodingNameKiki
Also found by: 0x1f8b, 0x52, 0x5rings, 0xAgro, 0xSmartContract, 0xcm, 0xkato, 2997ms, Aymen0909, BClabs, BPZ, BRONZEDISC, Bauer, Bnke0x0, Deekshith99, IllIllI, Josiah, Kaysoft, RaymondFam, Rolezn, SaeedAlipoor01988, Tajobin, Udsen, Viktor_Cortess, adriro, arialblack14, betweenETHlines, btk, chaduke, chrisdior4, cryptphi, csanuragjain, cygaar, defsec, descharre, erictee, gzeon, hansfriese, horsefacts, joestakey, koxuan, lukris02, luxartvinsec, nicobevi, oyc_109, pavankv, peanuts, rbserver, scokaf, shark, tnevler, tsvetanovv, zaskoh
36.2377 USDC - $36.24
Where: [CTokenCash.sol]
(https://github.com/code-423n4/2023-01-ondo/blob/main/contracts/lending/tokens/cCash/CTokenCash.sol#L357). In turn this means all the pTokens have this bug.
When: cToken.totalSupply == 0.
This attack has two implications
The "first" deposit can be front run and stolen Let's assume there is a first user trying to mint some cToken using their k*z underlying tokens
An attacker can see this transaction and carry out the above-described attack making sure that k<1. This leads to the first depositor getting zero cTokens for their k*z underlying tokens. All the tokens are redeemable by the attacker using their 1 wei of cToken.
Now, the attacker can treat the second deposit as the first one and repeat the same attack untill the second scenario mentioned below happens.
Implicit minimum Amount and funds lost due to rounding errors. If an attacker is successful in making 1 wei of pToken worth z underlying tokens and a user tries to mint pTokens using k* z underlying tokens then,
If k<1, then the user gets zero pTokens and all of their underlying tokens get proportionally divided between pToken holders This leads to an implicitminimum amount for a user at the attacker's discretion.
If k>1, then users still get some pTokens but they lose (k- floor(k)) * z) of underlying tokens which get proportionally divided between pToken holders due to rounding errors.
This means that for users to not lose value, they have to make sure that k is an integer. Attacker can listen to [MarketListed] from Unitroller to front-run.
When: cToken.totalSupply == 0.
Code Review
For new cTokens, I like how BalancerV2 and [UniswapV2] (https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol#L119-L121) do it.
Some minimum amount of pool tokens get burnt when the first mint happens.
#0 - c4-judge
2023-01-22T19:12:10Z
trust1995 changed the severity to QA (Quality Assurance)
#1 - c4-judge
2023-01-22T19:12:19Z
trust1995 marked the issue as grade-b
#2 - ypatil12
2023-01-24T00:18:50Z
Should be a duplicate with: https://github.com/code-423n4/2023-01-ondo-findings/issues/247