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: 87/126
Findings: 1
Award: $0.01
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: SpicyMeatball
Also found by: 0rpse, 0xMosh, 0xblack_bird, 0xdice91, 0xhacksmithh, 0xleadwizard, 0xmystery, Audinarey, AvantGard, Bigsam, Dots, EPSec, Eeyore, Janio, Limbooo, LinKenji, Mahmud, MrPotatoMagic, Myd, Oxsadeeq, Sabit, SovaSlava, Stefanov, Tychai0s, Utsav, Varun_05, Walter, adam-idarrha, ahmedaghadi, araj, aslanbek, ayden, bigtone, c0pp3rscr3w3r, carrotsmuggler, crypticdefense, dhank, fyamf, gajiknownnothing, gavfu, itsabinashb, jasonxiale, joaovwfreire, ke1caM, leegh, merlinboii, mitko1111, n4nika, pfapostol, prapandey031, rouhsamad, sandy, snakeeaterr, stakog, steadyman, swizz, tedox, th3l1ghtd3m0n, trachev, turvy_fuzz, xyz, yashgoel72, zhaojohnson
0.014 USDC - $0.01
https://github.com/code-423n4/2024-05-munchables/blob/57dff486c3cd905f21b330c2157fe23da2a4807d/src/managers/LockManager.sol#L257 https://github.com/code-423n4/2024-05-munchables/blob/57dff486c3cd905f21b330c2157fe23da2a4807d/src/managers/LockManager.sol#L258
The logic check in the setLockDuration function of the LockManager contract has a problem, which allows the lock duration to be decreased.
In the setLockDuration function's logic check, there is a verification for the new _duration, requiring uint32(block.timestamp) + uint32(_duration) < lockedTokens[msg.sender][tokenContract].unlockTime. However, the new unlockTime is set to lastLockTime + uint32(_duration). This results in the new unlockTime being less than the old unlockTime.
Example: Bob locks tokens with a duration of 10 days, making the unlockTime the 11th day. On the 4th day, Bob calls the setLockDuration function with _duration set to 7 days. This check passes, and the new unlockTime becomes the 8th day, thus reducing the lock duration.
Manual Audit
function setLockDuration(uint256 _duration) external notPaused { if (_duration > configStorage.getUint(StorageKey.MaxLockDuration)) revert MaximumLockDurationError(); playerSettings[msg.sender].lockDuration = uint32(_duration); // update any existing lock uint256 configuredTokensLength = configuredTokenContracts.length; for (uint256 i; i < configuredTokensLength; i++) { address tokenContract = configuredTokenContracts[i]; if (lockedTokens[msg.sender][tokenContract].quantity > 0) { + uint32 lastLockTime = lockedTokens[msg.sender][tokenContract] + .lastLockTime; // check they are not setting lock time before current unlocktime if ( + uint32(lastLockTime) + uint32(_duration) < + lockedTokens[msg.sender][tokenContract].unlockTime + ) { + revert LockDurationReducedError(); + } - if ( - uint32(block.timestamp) + uint32(_duration) < - lockedTokens[msg.sender][tokenContract].unlockTime - ) { - revert LockDurationReducedError(); - } - uint32 lastLockTime = lockedTokens[msg.sender][tokenContract] - .lastLockTime; lockedTokens[msg.sender][tokenContract].unlockTime = lastLockTime + uint32(_duration); } } emit LockDuration(msg.sender, _duration); }
Other
#0 - c4-judge
2024-06-04T12:40:56Z
alex-ppg marked the issue as duplicate of #89
#1 - c4-judge
2024-06-05T12:53:41Z
alex-ppg marked the issue as satisfactory
#2 - c4-judge
2024-06-05T12:54:34Z
alex-ppg changed the severity to 3 (High Risk)