Platform: Code4rena
Start Date: 07/04/2022
Pot Size: $100,000 USDC
Total HM: 20
Participants: 62
Period: 7 days
Judge: LSDan
Total Solo HM: 11
Id: 107
League: ETH
Rank: 43/62
Findings: 1
Award: $168.43
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Dravee
Also found by: 0x1f8b, 0xDjango, 0xkatana, AuditsAreUS, Cityscape, Foundation, Funen, Hawkeye, IllIllI, JC, JMukesh, Jujic, Kthere, PPrieditis, Picodes, Ruhum, TerrierLover, TrungOre, WatchPug, berndartmueller, catchup, cccz, cmichel, delfin454000, dy, ellahi, hickuphh3, horsefacts, hubble, hyh, ilan, jayjonah8, kebabsec, kenta, minhquanym, pauliax, rayn, reassor, rfa, robee, samruna
168.4282 USDC - $168.43
If the protocol wants to override the oracle with a custom floor value, it will use the function overrideFloor(uint256 _newFloor) However there is no input validation and the values can be set to any value. To mitigate any misuse or error, there should be some lower and upper bound values defined, say wrt to the oracle price.
Contract : NFTVault.sol
Function : overrideFloor(uint256 _newFloor)
One solution is to take the oracle price as reference and check if the newFloor value is within some range, like
oracle_price = _normalizeAggregatorAnswer(useFallbackOracle ? fallbackOracle : floorOracle); require(_newFloor > 0.5*oracle_price && _newFloor < 1.5*oracle_price);
The function setNFTTypeValueETH() can be used to set the value for any NFTType,
nftTypeValueETH[_type] = _amountETH;
Similarly the overrideFloor(uint256 _newFloor) is also used to set set the value
nftTypeValueETH[bytes32(0)] = _newFloor;
The cause of concern is that once a value is set for bytes32(0) using overrideFloor function, the value of bytes32(0) can be changed via setNFTTypeValueETH() function also, which should be prohibited.
Contract : NFTVault.sol Function : setNFTTypeValueETH(bytes32 _type, uint256 _amountETH)
Add a check in setNFTTypeValueETH() for filtering out values of _type = bytes32(0)
require(_type != bytes32(0), "cannot update value for type = 0");
_validationRate() does a very basic check for denominator >0 and denominator > numerator so that the variable value is not > 1. However there needs to be additional check so as to prevent rugpull, malicious activity or changes by mistake. Example, currently its possible to set the organizationFeeRate to 100%, the debtInterestApr to 100% or the insurancePurchaseRate to 100%
There should be additional check for the values to be within some max values. This will give some confidence to the users, and protection against some malicious events.
Contract : NFTVault.sol Function : _validateRate()
Define MAX values for each of the rate, and check them additionally during change.
There are some important functions, like below, line#232 : function setCreditLimitRate(Rate memory _creditLimitRate) line#247 : function setLiquidationLimitRate(Rate memory _liquidationLimitRate)
These should ideally generate events.
Add relevant events during changing important values.