zAuction, zNS - gas griefing by spamming offchain fake bids  Acknowledged
The execution status of both `zAuction.acceptBid` and `StakingController.fulfillDomainBid` transactions depend on the bidder, as his approval is needed, his signature is being validated, etc. However, these transactions can be submitted by accounts that are different from the bidder account, or for accounts that do not have the required funds/deposits available, luring the account that has to perform the on-chain call into spending gas on a transaction that is deemed to fail (gas griefing). E.g. posting high-value fake bids for zAuction without having funds deposited or `WETH` approved.\\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\\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
Revert early for checks that depend on the bidder before performing gas-intensive computations.\\nConsider adding a dry-run validation for off-chain components before transaction submission.
```\\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