Part 2

Zaros
PerpetualsDEXFoundrySolidity
70,000 USDC
View results
Submission Details
Severity: medium
Invalid

Incorrect Deadline Comparison in `checkLog()` Function in UsdTokenSwapKeeper.sol.

Summary

The checkLog function incorrectly verifies whether a swap request's deadline has expired. The current condition uses < (strictly less than), which does not account for cases where block.timestamp is exactly equal to request.deadline. This could lead to an unintended execution of expired requests in edge cases.

Vulnerability Details

The function checks whether request.deadline < block.timestamp before rejecting an expired request.

  • If request.deadline == block.timestamp, the request is still considered valid, even though it should be expired.

  • This can lead to race conditions where a request that has technically reached its deadline is still processed.

Permlink: https://github.com/Cyfrin/2025-01-zaros-part-2/blob/35deb3e92b2a32cd304bf61d27e6071ef36e446d/src/external/chainlink/keepers/usd-token-swap-keeper/UsdTokenSwapKeeper.sol#L79

Impact

Unintended execution of expired swap requests, potentially causing transactions to be processed when they should have been rejected.

  • Increased risk of stale or invalid trades, as users may exploit the narrow execution window to bypass intended constraints.

  • Could introduce inconsistencies in swap request handling, leading to unexpected results in the system.

Tools Used

Manual Review

Recommendations

Modify the deadline comparison to use <= instead of <:

function checkLog(
AutomationLog calldata log,
bytes memory
)
external
view
returns (bool upkeepNeeded, bytes memory performData)
{
// https://docs.chain.link/chainlink-automation/guides/log-trigger
// 0th index is the event signature hash
address caller = bytes32ToAddress(log.topics[1]);
uint128 requestId = uint128(uint256(log.topics[2]));
// load usd token swap storage
UsdTokenSwapKeeperStorage storage self = _getUsdTokenSwapKeeperStorage();
// load requiest for user by id
UsdTokenSwapConfig.SwapRequest memory request =
IMarketMakingEngine(self.marketMakingEngine).getSwapRequest(caller, requestId);
// if request dealine expired revert
- if (request.deadline < block.timestamp) {
+ if (request.deadline <= block.timestamp) {
return (false, new bytes(0));
}//...more code
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.