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: 90/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.0105 USDC - $0.01
User shouldn't be able to reduce lock duration // check they are not setting lock time before current unlocktime
.
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) { // check they are not setting lock time before current unlocktime 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); }
However it is possible that user reduces his lock duration, using setLockDuration
function, due to wrong calulation of new unlock time. block.timestamp + _duration
should be greater or equal to unlockTime
.
if ( uint32(block.timestamp) + uint32(_duration) < lockedTokens[msg.sender][tokenContract].unlockTime ) { revert LockDurationReducedError(); }
New unlockTime
is calculated based on lastLockTime
not block.timestamp
.
block.timestamp
= 100 (lastLockTime
= 100) and his unlockTime
= 150.block.timestamp
= 125 user calls setLockDuration
with 25
as an duration
argument.unlockTime
(150).unlockTime
is set to => lastLockTime
(100) + duration
(25) = 125, which is lower than 150. User reduced his lock duration and can unlock his tokens.User can bypass core protocol functionality. He can reduce lock duration and withdraw his tokens earlier than he should.
Fix calculation of new unlockTime
in setLockDuration
function.
You can do it by replacing lastLockTime
with block.timestamp
.
Other
#0 - c4-judge
2024-06-04T12:41:02Z
alex-ppg marked the issue as duplicate of #89
#1 - c4-judge
2024-06-05T12:53:27Z
alex-ppg marked the issue as partial-75
#2 - c4-judge
2024-06-05T12:54:34Z
alex-ppg changed the severity to 3 (High Risk)