Closed c4-submissions closed 9 months ago
the collateral amount is already in shares
bytes032 marked the issue as insufficient quality report
Seems invalid, cannot understand this
The function uses shares
to
invalid
jhsagd76 marked the issue as unsatisfactory: Invalid
to
invalid
The first parameter of computeCR
function is misleading. It's named _coll
, and the NatSpec documentation states @param _coll The collateral amount, in shares
. I've categorized this bug as medium risk because the computeCR
function yields an incorrect CR. The accurate computation should be stEthBalance * price / debt
. Therefore, return EbtcMath._computeCR(_coll, _debt, _price);
should be changed to return EbtcMath._computeCR(collateral.getPooledEthByShares(_coll), _debt, _price);
. It's evident that the return value of _getCdpStEthBalance
represents the collateral amount in steth balance, not in shares, so the result of that test case is right.
A simpler approach might be to directly modify the parameter and NatSpec, changing _coll
to _stEthBalance
and @param _coll The collateral amount, in shares
to @param _stEthBalance The collateral amount, in stETH balance
.
Can't understand whats your point. You mean that the param name is ambiguous, so it should be a MED?
Negative, based on rules speculated from future code.
I didn't find this test case when submitting the report. If the first parameter is meant to represent the collateral amount in shares, then the return value of this function is indeed incorrect. That's why I categorized it as a medium-risk issue when submitting the report. Based on this test case and the C4 rules, your judgment is more reasonable. Lastly, it would be advisable for the Badger team to modify the name of this parameter and updates the NatSpec accordingly.
Lines of code
https://github.com/code-423n4/2023-10-badger/blob/f2f2e2cf9965a1020661d179af46cb49e993cb7e/packages/contracts/contracts/HintHelpers.sol#L207-L218
Vulnerability details
Impact
HintHelpers.sol includes three helper functions: getRedemptionHints, getApproxHint, and computeNominalCR. These functions help users in operating CDPs. However, the logic of the
computeCR
function is incorrect and will result in users depositing more collateral than necessary.The
computeCR
function is designed to calculate ICR. This function takes three parameters: _coll, _debt, and _price. According to the comments,_coll
representsThe collateral amount in shares
.https://github.com/code-423n4/2023-10-badger/blob/f2f2e2cf9965a1020661d179af46cb49e993cb7e/packages/contracts/contracts/HintHelpers.sol#L207-L218
However, the first parameter of the
_computeCR
function is_stEthBalance
, indicatingthe amount of stETH tokens
. https://github.com/code-423n4/2023-10-badger/blob/f2f2e2cf9965a1020661d179af46cb49e993cb7e/packages/contracts/contracts/Dependencies/EbtcMath.sol#L103-L108The keyword
_coll
are used in many functions and events. In all of those contexts,_coll
consistently representsthe collateral amount, in shares
. Therefore, it can be confirmed that in thecomputeCR
function,_coll
indeed meansthe collateral amount in shares
. Here are some scenarios where_coll
is used: https://github.com/code-423n4/2023-10-badger/blob/f2f2e2cf9965a1020661d179af46cb49e993cb7e/packages/contracts/contracts/Interfaces/ICdpManager.sol#L58-L64 https://github.com/code-423n4/2023-10-badger/blob/f2f2e2cf9965a1020661d179af46cb49e993cb7e/packages/contracts/contracts/Interfaces/IActivePool.sol#L10-L13 https://github.com/code-423n4/2023-10-badger/blob/f2f2e2cf9965a1020661d179af46cb49e993cb7e/packages/contracts/contracts/Dependencies/EbtcBase.sol#L83-L85Therefore, the ICR calculated through the
computeCR
function is incorrect. If a user calls this function to estimate the required amount of stETH tokens before creating a CDP, they will get a value higher than the actual amount they should deposit. This results in two consequences:(1) The user deposits more stETH tokens than necessary, and these excess tokens could have been used elsewhere. (2) stETH is Lido staking ETH, generating staking rewards. The eBTC project extracts 50% of the staking rewards as protocol fees. Hence, the user incurs a loss of 50% of the staking rewards. (The default value of
stakingRewardSplit
is 50%)https://github.com/code-423n4/2023-10-badger/blob/f2f2e2cf9965a1020661d179af46cb49e993cb7e/packages/contracts/contracts/CdpManagerStorage.sol#L552-L558
Proof of Concept
Here is a test case. In this testing scenario, the value of eth per share,
1146574285570086126
, is obtained from the stETH contract. Alice wants to borrow 1392750000000000000 eBTC tokens, aiming for an ICR of 160%. Upon calling thecomputeCR
function, it is found that when the value of_coll
is30000000000000000000
, the ICR is precisely 160%. Subsequently, the stETH token quantity is calculated throughstEthBalance = collateral.getPooledEthByShares(coll)
, and finally, theopencdp function
is invoked to create the CDP.The test result shows that the actual ICR value is 183.4%. Alice has deposited an excess of 4397228567102583780 stETH tokens. Additionally, Alice will incur a loss of 50% of the staking rewards generated by these tokens.
Tools Used
Foundry
Recommended Mitigation Steps
Calculate the amount of stETH balance based on
_coll
and then proceed to calculate the ICR.Assessed type
Context