Platform: Code4rena
Start Date: 18/10/2023
Pot Size: $36,500 USDC
Total HM: 17
Participants: 77
Period: 7 days
Judge: MiloTruck
Total Solo HM: 5
Id: 297
League: ETH
Rank: 77/77
Findings: 1
Award: $8.30
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: MrPotatoMagic
Also found by: 0xMosh, 0xPsuedoPandit, 0xhacksmithh, 8olidity, Al-Qa-qa, Baki, Bughunter101, Krace, Stormreckson, T1MOH, Tendency, eeshenggoh, fibonacci, hals, immeas, kutugu, lsaudit, m4k2, mrudenko, okolicodes, phoenixV110, spark, twicek, xAriextz
8.3007 USDC - $8.30
_safeSrc equal to _safeDst will cause system exception
moveSAFE()
does not limit whether _safeSrc
is the same as _safeDst
. If _safeDst==_safeSrc
, it will execute normally
function moveSAFE(uint256 _safeSrc, uint256 _safeDst) external safeAllowed(_safeSrc) safeAllowed(_safeDst) { SAFEData memory _srcData = _safeData[_safeSrc]; SAFEData memory _dstData = _safeData[_safeDst]; if (_srcData.collateralType != _dstData.collateralType) revert CollateralTypesMismatch(); ISAFEEngine.SAFE memory _safeInfo = ISAFEEngine(safeEngine).safes(_srcData.collateralType, _srcData.safeHandler); int256 _deltaCollateral = _safeInfo.lockedCollateral.toInt(); int256 _deltaDebt = _safeInfo.generatedDebt.toInt(); ISAFEEngine(safeEngine).transferSAFECollateralAndDebt( _srcData.collateralType, _srcData.safeHandler, _dstData.safeHandler, _deltaCollateral, _deltaDebt ); // Remove safe from owner's list (notice it doesn't erase safe ownership) _usrSafes[_srcData.owner].remove(_safeSrc); _usrSafesPerCollat[_srcData.owner][_srcData.collateralType].remove(_safeSrc); emit MoveSAFE(msg.sender, _safeSrc, _safeDst); }
But the problem occurs later. The function will delete _safeSrc
from _usrSafes[_srcData.owner]
and _usrSafesPerCollat[_srcData.owner][_srcData.collateralType]
, but since _safeSrc == _safeDst
, it should not be deleted here.
_usrSafes[_srcData.owner].remove(_safeSrc); _usrSafesPerCollat[_srcData.owner][_srcData.collateralType].remove(_safeSrc);
vscode
function moveSAFE(uint256 _safeSrc, uint256 _safeDst) external safeAllowed(_safeSrc) safeAllowed(_safeDst) { + require(_safeSrc != _safeDst); SAFEData memory _srcData = _safeData[_safeSrc]; SAFEData memory _dstData = _safeData[_safeDst]; if (_srcData.collateralType != _dstData.collateralType) revert CollateralTypesMismatch(); ISAFEEngine.SAFE memory _safeInfo = ISAFEEngine(safeEngine).safes(_srcData.collateralType, _srcData.safeHandler); int256 _deltaCollateral = _safeInfo.lockedCollateral.toInt(); int256 _deltaDebt = _safeInfo.generatedDebt.toInt(); ISAFEEngine(safeEngine).transferSAFECollateralAndDebt( _srcData.collateralType, _srcData.safeHandler, _dstData.safeHandler, _deltaCollateral, _deltaDebt ); // Remove safe from owner's list (notice it doesn't erase safe ownership) _usrSafes[_srcData.owner].remove(_safeSrc); _usrSafesPerCollat[_srcData.owner][_srcData.collateralType].remove(_safeSrc); emit MoveSAFE(msg.sender, _safeSrc, _safeDst); }
Other
#0 - c4-pre-sort
2023-10-26T02:58:08Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2023-10-26T02:59:08Z
raymondfam marked the issue as duplicate of #91
#2 - c4-judge
2023-11-02T05:32:31Z
MiloTruck marked the issue as not a duplicate
#3 - c4-judge
2023-11-02T05:35:51Z
MiloTruck changed the severity to QA (Quality Assurance)
#4 - MiloTruck
2023-11-02T05:37:29Z
If a user does call moveSAFE()
with his own safe as _safeSrc
and _safeDst
, he removes the safe from his own mappings, which causes problems for himself only. Therefore, this is considered a user mistake. Additionally, _usrSafes
and _usrSafesPerCollat
is only used in view functions for UI purposes, so the impact of this finding is extremely low.
#5 - c4-judge
2023-11-03T17:14:42Z
MiloTruck marked the issue as grade-c
#6 - c4-judge
2023-11-03T18:02:52Z
MiloTruck marked the issue as grade-b