Auction creators have the ability to lock bidders' funds.
`Auction creators` have the ability to cancel an `auction` before it starts. However, once the `auction` begins, they should not be allowed to cancel it. During the `auction`, `bidders` can place `bids` and send `quote` tokens to the `auction` house. After the `auction` concludes, `bidders` can either receive `base` tokens or retrieve their `quote` tokens. Unfortunately, batch `auction` creators can cancel an `auction` when it ends. This means that `auction` creators can cancel their `auctions` if they anticipate `losses`. This should not be allowed. The significant risk is that `bidders' funds` could become locked in the `auction` house.\\n`Auction creators` can not cancel an `auction` once it concludes.\\n```\\nfunction cancelAuction(uint96 lotId_) external override onlyInternal {\\n    _revertIfLotConcluded(lotId_);\\n}\\n```\\n\\nThey also can not cancel it while it is active.\\n```\\nfunction _cancelAuction(uint96 lotId_) internal override {\\n    _revertIfLotActive(lotId_);\\n\\n    auctionData[lotId_].status = Auction.Status.Claimed;\\n}\\n```\\n\\nWhen the `block.timestamp` aligns with the `conclusion` time of the `auction`, we can bypass these checks.\\n```\\nfunction _revertIfLotConcluded(uint96 lotId_) internal view virtual {\\n    if (lotData[lotId_].conclusion < uint48(block.timestamp)) {\\n        revert Auction_MarketNotActive(lotId_);\\n    }\\n\\n    if (lotData[lotId_].capacity == 0) revert Auction_MarketNotActive(lotId_);\\n}\\nfunction _revertIfLotActive(uint96 lotId_) internal view override {\\n    if (\\n        auctionData[lotId_].status == Auction.Status.Created\\n            && lotData[lotId_].start <= block.timestamp\\n            && lotData[lotId_].conclusion > block.timestamp\\n    ) revert Auction_WrongState(lotId_);\\n}\\n```\\n\\nSo `Auction creators` can cancel an `auction` when it concludes. Then the `capacity` becomes `0` and the `auction` status transitions to `Claimed`.\\n`Bidders` can not `refund` their `bids`.\\n```\\nfunction refundBid(\\n    uint96 lotId_,\\n    uint64 bidId_,\\n    address caller_\\n) external override onlyInternal returns (uint96 refund) {\\n    _revertIfLotConcluded(lotId_);\\n}\\n function _revertIfLotConcluded(uint96 lotId_) internal view virtual {\\n    if (lotData[lotId_].capacity == 0) revert Auction_MarketNotActive(lotId_);\\n}\\n```\\n\\nThe only way for `bidders` to reclaim their tokens is by calling the `claimBids` function. However, `bidders` can only claim `bids` when the `auction status` is `Settled`.\\n```\\nfunction claimBids(\\n    uint96 lotId_,\\n    uint64[] calldata bidIds_\\n) {\\n    _revertIfLotNotSettled(lotId_);\\n}\\n```\\n\\nTo `settle` the `auction`, the `auction` status should be `Decrypted`. This requires submitting the `private key`. The `auction` creator can not submit the `private key` or submit it without decrypting any `bids` by calling `submitPrivateKey(lotId, privateKey, 0)`. Then nobody can decrypt the `bids` using the `decryptAndSortBids` function which always reverts.\\n```\\nfunction decryptAndSortBids(uint96 lotId_, uint64 num_) external {\\n    if (\\n        auctionData[lotId_].status != Auction.Status.Created     // @audit, here\\n            || auctionData[lotId_].privateKey == 0\\n    ) {\\n        revert Auction_WrongState(lotId_);\\n    }\\n\\n    _decryptAndSortBids(lotId_, num_);\\n}\\n```\\n\\nAs a result, the `auction status` remains unchanged, preventing it from transitioning to `Settled`. This leaves the `bidders'` `quote` tokens locked in the `auction house`.\\nPlease add below test to the `test/modules/Auction/cancel.t.sol`.\\n```\\nfunction test_cancel() external whenLotIsCreated {\\n    Auction.Lot memory lot = _mockAuctionModule.getLot(_lotId);\\n\\n    console2.log("lot.conclusion before   ==> ", lot.conclusion);\\n    console2.log("block.timestamp before  ==> ", block.timestamp);\\n    console2.log("isLive                  ==> ", _mockAuctionModule.isLive(_lotId));\\n\\n    vm.warp(lot.conclusion - block.timestamp + 1);\\n    console2.log("lot.conclusion after    ==> ", lot.conclusion);\\n    console2.log("block.timestamp after   ==> ", block.timestamp);\\n    console2.log("isLive                  ==> ", _mockAuctionModule.isLive(_lotId));\\n\\n    vm.prank(address(_auctionHouse));\\n    _mockAuctionModule.cancelAuction(_lotId);\\n}\\n```\\n\\nThe log is\\n```\\nlot.conclusion before   ==>  86401\\nblock.timestamp before  ==>  1\\nisLive                  ==>  true\\nlot.conclusion after    ==>  86401\\nblock.timestamp after   ==>  86401\\nisLive                  ==>  false\\n```\\n
```\\nfunction _revertIfLotConcluded(uint96 lotId_) internal view virtual {\\n-     if (lotData[lotId_].conclusion < uint48(block.timestamp)) {\\n+     if (lotData[lotId_].conclusion <= uint48(block.timestamp)) {\\n        revert Auction_MarketNotActive(lotId_);\\n    }\\n\\n    // Capacity is sold-out, or cancelled\\n    if (lotData[lotId_].capacity == 0) revert Auction_MarketNotActive(lotId_);\\n}\\n```\\n
Users' funds can be locked.
```\\nfunction cancelAuction(uint96 lotId_) external override onlyInternal {\\n    _revertIfLotConcluded(lotId_);\\n}\\n```\\n