Platform: Code4rena
Start Date: 23/06/2023
Pot Size: $60,500 USDC
Total HM: 31
Participants: 132
Period: 10 days
Judge: 0xean
Total Solo HM: 10
Id: 254
League: ETH
Rank: 36/132
Findings: 2
Award: $282.51
🌟 Selected for report: 0
🚀 Solo Findings: 0
281.1877 USDC - $281.19
Wrong assumption on the mint
function assumes that if sharesAmount
== 0, totalSupply
== 0.
if (sharesAmount == 0) { //EUSD totalSupply is 0: assume that shares correspond to EUSD 1-to-1 sharesAmount = _mintAmount; }
Meanwhile this is NOT the case.
If you look at the mint
function,
function mint(address _recipient, uint256 _mintAmount) external onlyMintVault MintPaused returns (uint256 newTotalShares) { require(_recipient != address(0), "MINT_TO_THE_ZERO_ADDRESS"); uint256 sharesAmount = getSharesByMintedEUSD(_mintAmount); if (sharesAmount == 0) { //EUSD totalSupply is 0: assume that shares correspond to EUSD 1-to-1 sharesAmount = _mintAmount; } newTotalShares = _totalShares.add(sharesAmount); _totalShares = newTotalShares; shares[_recipient] = shares[_recipient].add(sharesAmount); _totalSupply += _mintAmount; emit Transfer(address(0), _recipient, _mintAmount); }
The sharesAmount
is gotten from the getSharesByMintedEUSD
function.
function getSharesByMintedEUSD(uint256 _EUSDAmount) public view returns (uint256) { uint256 totalMintedEUSD = _totalSupply; if (totalMintedEUSD == 0) { return 0; } else { return _EUSDAmount.mul(_totalShares).div(totalMintedEUSD); } }
Assuming _totalSupply
= 1000; _totalShares
= 800; calling the mint
function with _mintAmount
= 1; would give sharesAmount
= 0; As 1 * 800/100 = 0.8 = 0 (Rounded down to 0).
In this case, a non-zero _totalSupply
would still give a sharesAmount
of 0.
Manual Review
Other
#0 - c4-pre-sort
2023-07-08T20:21:37Z
JeffCX marked the issue as duplicate of #106
#1 - c4-judge
2023-07-28T15:32:20Z
0xean marked the issue as satisfactory
#2 - c4-judge
2023-07-28T19:44:38Z
0xean changed the severity to 3 (High Risk)
🌟 Selected for report: bytes032
Also found by: 0xMAKEOUTHILL, 0xgrbr, 0xkazim, 0xnacho, Arz, Co0nan, CrypticShepherd, Cryptor, HE1M, Iurii3, LaScaloneta, LokiThe5th, LuchoLeonel1, MrPotatoMagic, Musaka, Qeew, RedTiger, SovaSlava, Toshii, Vagner, a3yip6, azhar, bart1e, devival, hl_, jnrlouis, kutugu, peanuts, pep7siup, qpzm, smaul
1.3247 USDC - $1.32
https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/LybraRETHVault.sol#L9-L11 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/LybraRETHVault.sol#L46-L48 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L58-L70 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L96-L100 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L125-L128 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L157-L168 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L212-L220 https://github.com/code-423n4/2023-06-lybra/blob/5d70170f2c68dbd3f7b8c0c8fd6b0b2218784ea6/contracts/lybra/pools/base/LybraPeUSDVaultBase.sol#L269-L270
Most of the critical functions would be broken in the RETH vault due to an error with a function name in the interface.
The error is from:
interface IRETH { function getExchangeRatio() external view returns (uint256); }
The main issue is the function name in the interface declaration getExchangeRatio()
. Looking at the RocketTokenRETH contract on etherscan: https://etherscan.io/address/0xae78736cd615f374d3085123a210448e74fc6393#code, the correct function name should be getExchangeRate()
as getExchangeRatio()
doesn't exist. This can be further seen in the RocketTokenRETHInterface.sol.
This would mean most of the critical functions would be broken as getAssetPrice()
uses this broken function here - This would in turn affect functions like depositAssetToMint()
, mint()
, liquidation()
, rigidRedemption()
and withdraw()
.
Manual review
Correct the spelling error in the interface to:
function getExchangeRate() external view returns (uint256);
Error
#0 - c4-pre-sort
2023-07-04T13:20:20Z
JeffCX marked the issue as duplicate of #27
#1 - c4-judge
2023-07-28T17:14:13Z
0xean changed the severity to 2 (Med Risk)
#2 - c4-judge
2023-07-28T17:15:44Z
0xean marked the issue as satisfactory