Vulnerability: zAuction, zNS - Bids cannot be cancelled, never expire, and the auction lifecycle is unclear
Severity: high

Description:
The lifecycle of a bid both for `zAuction` and `zNS` is not clear, and has many flaws.\\n`zAuction` - Consider the case where a bid is placed, then the underlying asset in being transferred to a new owner. The new owner can now force to sell the asset even though it's might not be relevant anymore.\\n`zAuction` - Once a bid was accepted and the asset was transferred, all other bids need to be invalidated automatically, otherwise and old bid might be accepted even after the formal auction is over.\\n`zAuction`, `zNS` - There is no way for the bidder to cancel an old bid. That might be useful in the event of a significant change in market trend, where the old pricing is no longer relevant. Currently, in order to cancel a bid, the bidder can either withdraw his ether balance from the `zAuctionAccountant`, or disapprove `WETH` which requires an extra transaction that might be front-runned by the seller.\\n```\\nfunction acceptBid(bytes memory signature, uint256 rand, address bidder, uint256 bid, address nftaddress, uint256 tokenid) external {\\n    address recoveredbidder = recover(toEthSignedMessageHash(keccak256(abi.encode(rand, address(this), block.chainid, bid, nftaddress, tokenid))), signature);\\n    require(bidder == recoveredbidder, 'zAuction: incorrect bidder');\\n    require(!randUsed[rand], 'Random nonce already used');\\n    randUsed[rand] = true;\\n    IERC721 nftcontract = IERC721(nftaddress);\\n    accountant.Exchange(bidder, msg.sender, bid);\\n    nftcontract.transferFrom(msg.sender, bidder, tokenid);\\n    emit BidAccepted(bidder, msg.sender, bid, nftaddress, tokenid);\\n}\\n```\\n\\n```\\n  function fulfillDomainBid(\\n  uint256 parentId,\\n  uint256 bidAmount,\\n  uint256 royaltyAmount,\\n  string memory bidIPFSHash,\\n  string memory name,\\n  string memory metadata,\\n  bytes memory signature,\\n  bool lockOnCreation,\\n  address recipient\\n) external {\\n  bytes32 recoveredBidHash = createBid(parentId, bidAmount, bidIPFSHash, name);\\n  address recoveredBidder = recover(recoveredBidHash, signature);\\n  require(recipient == recoveredBidder, "ZNS: bid info doesnt match/exist");\\n  bytes32 hashOfSig = keccak256(abi.encode(signature));\\n  require(approvedBids[hashOfSig] == true, "ZNS: has been fullfilled");\\n  infinity.safeTransferFrom(recoveredBidder, controller, bidAmount);\\n  uint256 id = registrar.registerDomain(parentId, name, controller, recoveredBidder);\\n  registrar.setDomainMetadataUri(id, metadata);\\n  registrar.setDomainRoyaltyAmount(id, royaltyAmount);\\n  registrar.transferFrom(controller, recoveredBidder, id);\\n  if (lockOnCreation) {\\n    registrar.lockDomainMetadataForOwner(id);\\n  }\\n  approvedBids[hashOfSig] = false;\\n  emit DomainBidFulfilled(\\n    metadata,\\n    name,\\n    recoveredBidder,\\n    id,\\n    parentId\\n  );\\n}\\n```\\n

Impact:

Recommended mitigation:
Consider adding an expiration field to the message signed by the bidder both for `zAuction` and `zNS`. Consider adding auction control, creating an `auctionId`, and have users bid on specific auctions. By adding this id to the signed message, all other bids are invalidated automatically and users would have to place new bids for a new auction. Optionally allow users to cancel bids explicitly.\\n