Skip to content

Alert Bronze Donkey - User can set extremely short deadlines leading to failed transactions #200

@sherlock-admin4

Description

@sherlock-admin4

Alert Bronze Donkey

Medium

User can set extremely short deadlines leading to failed transactions

Summary

The lack of minimum deadline validation in PinlinkShop.sol will cause transaction failures for buyers as sellers can set deadlines just seconds ahead, making it impossible to execute purchases in high network activity.

Root Cause

In PinlinkShop.sol:_list() the deadline validation only checks if it's greater than current timestamp:

require(deadline > block.timestamp, DeadlineHasExpiredAlready());

This allows deadlines to be set just seconds into the future.

Internal Pre-conditions

  1. Seller needs to call list() with a deadline just seconds ahead of block.timestamp
  2. Number of concurrent buyers in the market to be at least 1
  3. The listing must have a reasonable price to attract buyers

External Pre-conditions

  1. Network must have normal or high congestion (>10 second block times)
  2. Gas price fluctuations causing transaction delays

Attack Path

  1. Malicious seller creates a listing with attractive price and deadline = block.timestamp + 5 seconds
  2. Legitimate buyers attempt to purchase but transactions fail with ListingDeadlineExpired()
  3. Seller repeats this pattern to:
    • Discourage buyers
    • Create false impression of market activity
    • Manipulate price discovery

Impact

The protocol suffers from market manipulation and reduced usability. Buyers waste gas on failed transactions. The attacker can control market price discovery through artificial scarcity.

PoC

PoC

function testShortDeadlineGriefing() public {
    // Setup
    uint256 listAmount = 100;
    uint256 pricePerToken = 10e18; // 10 USD per token
    
    vm.startPrank(alice);
    // Create listing with extremely short deadline
    bytes32 listingId = pshop.list(
        address(fractions),
        tokenId,
        listAmount,
        pricePerToken,
        block.timestamp + 5 // 5 second deadline
    );
    vm.stopPrank();

    // Bob attempts to buy
    vm.startPrank(bob);
    uint256 buyAmount = 50;
    uint256 pinAmount = pshop.getQuoteInTokens(listingId, buyAmount);
    PIN.approve(address(pshop), pinAmount);
    
    // Simulate network congestion
    vm.warp(block.timestamp + 6);
    
    // Purchase fails due to expired deadline
    vm.expectRevert(PinlinkShop.ListingDeadlineExpired.selector);
    pshop.purchase(listingId, buyAmount, pinAmount);
    vm.stopPrank();
}

Recommendation

Implement a minimum deadline duration of 15 minutes to:

  1. Allow sufficient time for transactions to execute
  2. Account for network congestion
  3. Prevent market manipulation through short deadlines
  4. Improve user experience by reducing failed transactions

Mitigation

https://github.com/sherlock-audit/2025-03-pinlink-rwa-tokenized-depin-marketplace/blob/main/marketplace-contracts/src/marketplaces/pinlinkShop.sol#L513

Add minimum deadline duration check in _list():

function _list(
    address fractionalAssets,
    uint256 tokenId,
    uint256 amount,
    uint256 usdPricePerFraction,
    uint256 deadline
) internal returns (bytes32 listingId) {
    require(deadline >= block.timestamp + 15 minutes, "Deadline too short");
    require(deadline > block.timestamp, DeadlineHasExpiredAlready());
    // ... rest of function
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions