diff --git a/contracts/diamond/ProtocolDiamond.sol b/contracts/diamond/ProtocolDiamond.sol index 8d455e3d7..2a7c44dbf 100644 --- a/contracts/diamond/ProtocolDiamond.sol +++ b/contracts/diamond/ProtocolDiamond.sol @@ -38,7 +38,7 @@ contract ProtocolDiamond { IDiamondCut.FacetCut[] memory _facetCuts, bytes4[] memory _interfaceIds ) { - require(address(_accessController) != address(0), INVALID_ADDRESS); + require(address(_accessController) != address(0), "Invalid address"); // Get the DiamondStorage struct DiamondLib.DiamondStorage storage ds = DiamondLib.diamondStorage(); diff --git a/contracts/domain/BosonConstants.sol b/contracts/domain/BosonConstants.sol index fcd78eea7..b6a86644c 100644 --- a/contracts/domain/BosonConstants.sol +++ b/contracts/domain/BosonConstants.sol @@ -11,180 +11,23 @@ bytes32 constant CLIENT = keccak256("CLIENT"); // Role for clients of the Protoc bytes32 constant UPGRADER = keccak256("UPGRADER"); // Role for performing contract and config upgrades bytes32 constant FEE_COLLECTOR = keccak256("FEE_COLLECTOR"); // Role for collecting fees from the protocol -// Revert Reasons: Pause related -string constant NOT_PAUSED = "Protocol is not currently paused"; -string constant REGION_PAUSED = "This region of the protocol is currently paused"; - +// Pause Handler uint256 constant ALL_REGIONS_MASK = (1 << (uint256(type(BosonTypes.PausableRegion).max) + 1)) - 1; -// Revert Reasons: General -string constant INVALID_ADDRESS = "Invalid address"; -string constant INVALID_STATE = "Invalid state"; -string constant ARRAY_LENGTH_MISMATCH = "Array length mismatch"; - // Reentrancy guard -string constant REENTRANCY_GUARD = "ReentrancyGuard: reentrant call"; uint256 constant NOT_ENTERED = 1; uint256 constant ENTERED = 2; -// Revert Reasons: Protocol initialization related -string constant ALREADY_INITIALIZED = "Already initialized"; -string constant PROTOCOL_INITIALIZATION_FAILED = "Protocol initialization failed"; -string constant VERSION_MUST_BE_SET = "Version cannot be empty"; -string constant ADDRESSES_AND_CALLDATA_LENGTH_MISMATCH = "Addresses and calldata must be same length"; -string constant WRONG_CURRENT_VERSION = "Wrong current protocol version"; -string constant DIRECT_INITIALIZATION_NOT_ALLOWED = "Direct initializtion is not allowed"; -string constant TWINS_ALREADY_EXIST = "Should not have any twins yet"; - -// Revert Reasons: Access related -string constant ACCESS_DENIED = "Access denied, caller doesn't have role"; -string constant NOT_ASSISTANT = "Not seller's assistant"; -string constant NOT_ADMIN = "Not admin"; -string constant CLERK_DEPRECATED = "Clerk is deprecated and must be set to address 0"; -string constant NOT_ADMIN_AND_ASSISTANT = "Not admin and assistant"; -string constant NOT_BUYER_OR_SELLER = "Not buyer or seller"; -string constant NOT_VOUCHER_HOLDER = "Not current voucher holder"; -string constant NOT_BUYER_WALLET = "Not buyer's wallet address"; -string constant NOT_AGENT_WALLET = "Not agent's wallet address"; -string constant NOT_DISPUTE_RESOLVER_ASSISTANT = "Not dispute resolver's assistant address"; - -// Revert Reasons: Account-related -string constant NO_SUCH_SELLER = "No such seller"; -string constant MUST_BE_ACTIVE = "Account must be active"; -string constant SELLER_ADDRESS_MUST_BE_UNIQUE = "Seller address cannot be assigned to another seller Id"; -string constant BUYER_ADDRESS_MUST_BE_UNIQUE = "Buyer address cannot be assigned to another buyer Id"; -string constant DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE = "Dispute resolver address cannot be assigned to another dispute resolver Id"; -string constant AGENT_ADDRESS_MUST_BE_UNIQUE = "Agent address cannot be assigned to another agent Id"; -string constant NO_SUCH_BUYER = "No such buyer"; -string constant NO_SUCH_AGENT = "No such agent"; -string constant WALLET_OWNS_VOUCHERS = "Wallet address owns vouchers"; -string constant NO_SUCH_DISPUTE_RESOLVER = "No such dispute resolver"; -string constant INVALID_ESCALATION_PERIOD = "Invalid escalation period"; -string constant INEXISTENT_DISPUTE_RESOLVER_FEES = "Dispute resolver fees are not present"; -string constant DUPLICATE_DISPUTE_RESOLVER_FEES = "Duplicate dispute resolver fee"; -string constant FEE_AMOUNT_NOT_YET_SUPPORTED = "Non-zero dispute resolver fees not yet supported"; -string constant DISPUTE_RESOLVER_FEE_NOT_FOUND = "Dispute resolver fee not found"; -string constant SELLER_ALREADY_APPROVED = "Seller id is approved already"; -string constant SELLER_NOT_APPROVED = "Seller id is not approved"; -string constant INEXISTENT_ALLOWED_SELLERS_LIST = "Allowed sellers are not present"; -string constant INVALID_AUTH_TOKEN_TYPE = "Invalid AuthTokenType"; -string constant ADMIN_OR_AUTH_TOKEN = "An admin address or an auth token is required"; -string constant AUTH_TOKEN_MUST_BE_UNIQUE = "Auth token cannot be assigned to another entity of the same type"; -string constant INVALID_AGENT_FEE_PERCENTAGE = "Sum of agent fee percentage and protocol fee percentage should be <= max fee percentage limit"; -string constant NO_PENDING_UPDATE_FOR_ACCOUNT = "No pending updates for the given account"; -string constant UNAUTHORIZED_CALLER_UPDATE = "Caller has no permission to approve this update"; -string constant NO_UPDATE_APPLIED = "No update applied or requested approval"; -string constant CLONE_CREATION_FAILED = "Clone creation failed"; -string constant SELLER_SALT_NOT_UNIQUE = "Seller salt not unique"; - -// Revert Reasons: Offer related -string constant NO_SUCH_OFFER = "No such offer"; -string constant OFFER_PERIOD_INVALID = "Offer period invalid"; -string constant OFFER_PENALTY_INVALID = "Offer penalty invalid"; -string constant OFFER_MUST_BE_ACTIVE = "Offer must be active"; -string constant OFFER_MUST_BE_UNIQUE = "Offer must be unique to a group"; -string constant OFFER_HAS_BEEN_VOIDED = "Offer has been voided"; -string constant OFFER_HAS_EXPIRED = "Offer has expired"; -string constant OFFER_NOT_AVAILABLE = "Offer is not yet available"; -string constant OFFER_SOLD_OUT = "Offer has sold out"; -string constant CANNOT_COMMIT = "Caller cannot commit"; -string constant EXCHANGE_FOR_OFFER_EXISTS = "Exchange for offer exists"; -string constant AMBIGUOUS_VOUCHER_EXPIRY = "Exactly one of voucherRedeemableUntil and voucherValid must be non zero"; -string constant REDEMPTION_PERIOD_INVALID = "Redemption period invalid"; -string constant INVALID_DISPUTE_PERIOD = "Invalid dispute period"; -string constant INVALID_RESOLUTION_PERIOD = "Invalid resolution period"; -string constant INVALID_DISPUTE_RESOLVER = "Invalid dispute resolver"; -string constant INVALID_QUANTITY_AVAILABLE = "Invalid quantity available"; -string constant DR_UNSUPPORTED_FEE = "Dispute resolver does not accept this token"; -string constant AGENT_FEE_AMOUNT_TOO_HIGH = "Sum of agent fee amount and protocol fee amount should be <= offer fee limit"; -string constant NO_SUCH_COLLECTION = "No such collection"; - -// Revert Reasons: Group related -string constant NO_SUCH_GROUP = "No such group"; -string constant OFFER_NOT_IN_GROUP = "Offer not part of the group"; -string constant NOTHING_UPDATED = "Nothing updated"; -string constant INVALID_CONDITION_PARAMETERS = "Invalid condition parameters"; -string constant GROUP_HAS_NO_CONDITION = "Offer belongs to a group without a condition. Use commitToOffer instead"; -string constant GROUP_HAS_CONDITION = "Offer belongs to a group with a condition. Use commitToConditionalOffer instead"; -string constant MAX_COMMITS_REACHED = "Max commits reached"; -string constant TOKEN_ID_NOT_IN_CONDITION_RANGE = "Token id not in condition range"; -string constant INVALID_TOKEN_ID = "ERC721 and ERC20 require zero tokenId"; - -// Revert Reasons: Exchange related -string constant NO_SUCH_EXCHANGE = "No such exchange"; -string constant DISPUTE_PERIOD_NOT_ELAPSED = "Dispute period has not yet elapsed"; -string constant VOUCHER_NOT_REDEEMABLE = "Voucher not yet valid or already expired"; -string constant VOUCHER_EXTENSION_NOT_VALID = "Proposed date is not later than the current one"; -string constant VOUCHER_STILL_VALID = "Voucher still valid"; -string constant VOUCHER_HAS_EXPIRED = "Voucher has expired"; -string constant EXCHANGE_IS_NOT_IN_A_FINAL_STATE = "Exchange is not in a final state"; -string constant EXCHANGE_ALREADY_EXISTS = "Exchange already exists"; -string constant INVALID_RANGE_LENGTH = "Range length is too large or zero"; - -// Revert Reasons: Sequential commit related -string constant UNEXPECTED_ERC721_RECEIVED = "Unexpected ERC721 received"; -string constant FEE_AMOUNT_TOO_HIGH = "Fee amount is too high"; -string constant VOUCHER_NOT_RECEIVED = "Voucher not received"; -string constant NEGATIVE_PRICE_NOT_ALLOWED = "Negative price not allowed"; - -// Revert Reasons: Twin related +// Twin handler uint256 constant SINGLE_TWIN_RESERVED_GAS = 160000; uint256 constant MINIMAL_RESIDUAL_GAS = 230000; -string constant NO_SUCH_TWIN = "No such twin"; -string constant NO_TRANSFER_APPROVED = "No transfer approved"; -string constant TWIN_TRANSFER_FAILED = "Twin could not be transferred"; -string constant UNSUPPORTED_TOKEN = "Unsupported token"; -string constant BUNDLE_FOR_TWIN_EXISTS = "Bundle for twin exists"; -string constant INVALID_SUPPLY_AVAILABLE = "supplyAvailable can't be zero"; -string constant INVALID_AMOUNT = "Invalid twin amount"; -string constant INVALID_TWIN_PROPERTY = "Invalid property for selected token type"; -string constant INVALID_TWIN_TOKEN_RANGE = "Token range is already being used in another twin"; -string constant INVALID_TOKEN_ADDRESS = "Token address is a contract that doesn't implement the interface for selected token type"; -// Revert Reasons: Bundle related -string constant NO_SUCH_BUNDLE = "No such bundle"; -string constant TWIN_NOT_IN_BUNDLE = "Twin not part of the bundle"; -string constant OFFER_NOT_IN_BUNDLE = "Offer not part of the bundle"; -string constant BUNDLE_OFFER_MUST_BE_UNIQUE = "Offer must be unique to a bundle"; -string constant BUNDLE_TWIN_MUST_BE_UNIQUE = "Twin must be unique to a bundle"; -string constant EXCHANGE_FOR_BUNDLED_OFFERS_EXISTS = "Exchange for the bundled offers exists"; -string constant INSUFFICIENT_TWIN_SUPPLY_TO_COVER_BUNDLE_OFFERS = "Insufficient twin supplyAvailable to cover total quantity of bundle offers"; -string constant BUNDLE_REQUIRES_AT_LEAST_ONE_TWIN_AND_ONE_OFFER = "Bundle must have at least one twin and one offer"; +// Config related +bytes32 constant VOUCHER_PROXY_SALT = keccak256(abi.encodePacked("BosonVoucherProxy")); -// Revert Reasons: Funds related -string constant NATIVE_WRONG_ADDRESS = "Native token address must be 0"; -string constant NATIVE_WRONG_AMOUNT = "Transferred value must match amount"; -string constant TOKEN_NAME_UNSPECIFIED = "Token name unavailable"; +// Funds related string constant NATIVE_CURRENCY = "Native currency"; -string constant TOKEN_AMOUNT_MISMATCH = "Number of amounts should match number of tokens"; -string constant NOTHING_TO_WITHDRAW = "Nothing to withdraw"; -string constant NOT_AUTHORIZED = "Not authorized to withdraw"; -string constant TOKEN_TRANSFER_FAILED = "Token transfer failed"; -string constant INSUFFICIENT_VALUE_RECEIVED = "Insufficient value received"; -string constant INSUFFICIENT_AVAILABLE_FUNDS = "Insufficient available funds"; -string constant NATIVE_NOT_ALLOWED = "Transfer of native currency not allowed"; -string constant ZERO_DEPOSIT_NOT_ALLOWED = "Zero deposit not allowed"; - -// Revert Reasons: Meta-Transactions related -string constant NONCE_USED_ALREADY = "Nonce used already"; -string constant FUNCTION_CALL_NOT_SUCCESSFUL = "Function call not successful"; -string constant SIGNER_AND_SIGNATURE_DO_NOT_MATCH = "Signer and signature do not match"; -string constant INVALID_FUNCTION_NAME = "Invalid function name"; -string constant INVALID_SIGNATURE = "Invalid signature"; -string constant FUNCTION_NOT_ALLOWLISTED = "Function can not be executed via meta transaction"; - -// Revert Reasons: Dispute related -string constant DISPUTE_PERIOD_HAS_ELAPSED = "Dispute period has already elapsed"; -string constant DISPUTE_HAS_EXPIRED = "Dispute has expired"; -string constant INVALID_BUYER_PERCENT = "Invalid buyer percent"; -string constant DISPUTE_STILL_VALID = "Dispute still valid"; -string constant INVALID_DISPUTE_TIMEOUT = "Invalid dispute timeout"; -string constant ESCALATION_NOT_ALLOWED = "Disputes without dispute resolver cannot be escalated"; - -// Revert Reasons: Config related -string constant FEE_PERCENTAGE_INVALID = "Percentage representation must be less than 10000"; -string constant VALUE_ZERO_NOT_ALLOWED = "Value must be greater than 0"; -bytes32 constant VOUCHER_PROXY_SALT = keccak256(abi.encodePacked("BosonVoucherProxy")); +string constant TOKEN_NAME_UNSPECIFIED = "Token name unavailable"; // EIP712Lib string constant PROTOCOL_NAME = "Boson Protocol"; @@ -196,22 +39,13 @@ bytes32 constant EIP712_DOMAIN_TYPEHASH = keccak256( // BosonVoucher string constant VOUCHER_NAME = "Boson Voucher (rNFT)"; string constant VOUCHER_SYMBOL = "BOSON_VOUCHER_RNFT"; -string constant EXCHANGE_ID_IN_RESERVED_RANGE = "Exchange id falls within a pre-minted offer's range"; -string constant NO_RESERVED_RANGE_FOR_OFFER = "Offer id not associated with a reserved range"; -string constant OFFER_RANGE_ALREADY_RESERVED = "Offer id already associated with a reserved range"; -string constant INVALID_RANGE_START = "Range start too low"; -string constant INVALID_AMOUNT_TO_MINT = "Amount to mint is greater than remaining un-minted in range"; -string constant NO_SILENT_MINT_ALLOWED = "Only owner's mappings can be updated without event"; -string constant OFFER_EXPIRED_OR_VOIDED = "Offer expired or voided"; -string constant OFFER_STILL_VALID = "Offer still valid"; -string constant AMOUNT_EXCEEDS_RANGE_OR_NOTHING_TO_BURN = "Amount exceeds the range or there is nothing to burn"; -string constant OWNABLE_ZERO_ADDRESS = "Ownable: new owner is the zero address"; -string constant ROYALTY_FEE_INVALID = "ERC2981: royalty fee exceeds protocol limit"; -string constant NOT_COMMITTABLE = "Token not committable"; -string constant INVALID_TO_ADDRESS = "Tokens can only be pre-mined to the contract or contract owner address"; -string constant EXTERNAL_CALL_FAILED = "External call failed"; -string constant ERC721_INVALID_TOKEN_ID = "ERC721: invalid token ID"; -string constant INTERACTION_NOT_ALLOWED = "Interaction not allowed"; + +// Meta Transactions - Error +string constant FUNCTION_CALL_NOT_SUCCESSFUL = "Function call not successful"; + +// External contracts errors +string constant OWNABLE_ZERO_ADDRESS = "Ownable: new owner is the zero address"; // exception message from OpenZeppelin Ownable +string constant ERC721_INVALID_TOKEN_ID = "ERC721: invalid token ID"; // exception message from OpenZeppelin ERC721 // Meta Transactions - Structs bytes32 constant META_TRANSACTION_TYPEHASH = keccak256( @@ -257,16 +91,3 @@ string constant RETRACT_DISPUTE = "retractDispute(uint256)"; string constant RAISE_DISPUTE = "raiseDispute(uint256)"; string constant ESCALATE_DISPUTE = "escalateDispute(uint256)"; string constant RESOLVE_DISPUTE = "resolveDispute(uint256,uint256,bytes32,bytes32,uint8)"; - -// Price discovery related -string constant PRICE_TOO_HIGH = "Price discovery returned a price that is too high"; -string constant PRICE_TOO_LOW = "Price discovery returned a price that is too low"; -string constant TOKEN_ID_MANDATORY = "Token id is mandatory for bid orders"; -string constant TOKEN_ID_MISMATCH = "Token id mismatch"; -string constant INVALID_PRICE_TYPE = "Invalid price type"; -string constant INVALID_PRICE_DISCOVERY = "Invalid price discovery argument"; -string constant INCOMING_VOUCHER_ALREADY_SET = "Incoming voucher already set"; -string constant NEW_OWNER_AND_BUYER_MUST_MATCH = "New owner and buyer must match"; -string constant PRICE_DISCOVERY_CONTRACTS_NOT_SET = "PriceDiscoveryContract and Conduit must be set"; -string constant TOKEN_ID_NOT_SET = "Token id not set"; -string constant VOUCHER_TRANSFER_NOT_ALLOWED = "Voucher transfer not allowed"; diff --git a/contracts/domain/BosonErrors.sol b/contracts/domain/BosonErrors.sol new file mode 100644 index 000000000..8a920af02 --- /dev/null +++ b/contracts/domain/BosonErrors.sol @@ -0,0 +1,347 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity 0.8.21; + +interface BosonErrors { + // Pause related + // Trying to unpause a protocol when it's not paused + error NotPaused(); + // Whenever a region is paused, and a method from that region is called + error RegionPaused(); //ToDo consider adding the region to the error message + + // General + // Input parameter of type address is zero address + error InvalidAddress(); + // Exchange or dispute is in different state than expected when certain action is called + error InvalidState(); + // Two or more array parameters with different lengths + error ArrayLengthMismatch(); + + // Reentrancy guard + // Reentrancy guard is active and second call to protocol is made + error ReentrancyGuard(); + + // Protocol initialization related + // Trying to initialize the facet when it's already initialized + error AlreadyInitialized(); // ToDo consider adding the facet to the error message + // Initialization of some facet failed + error ProtocolInitializationFailed(); // ToDo consider adding the facet to the error message + // Trying to initialize the protocol with empty version + error VersionMustBeSet(); + // Length of _addresses and _calldata arrays do not match + error AddressesAndCalldataLengthMismatch(); // ToDo consider reusing ArrayLengthMismatch + // The new protocol version is not subsequent to the current one + error WrongCurrentVersion(); + // Initialization can be done only through proxy + error DirectInitializationNotAllowed(); + // Initialization of v2.3.0 can be done only if not twin exists + error TwinsAlreadyExist(); + + // Access related + // ToDo consider having a single error, with a parameter for the role + // Caller is not authorized to call the method + error AccessDenied(); + // Caller is not entitiy's assistant + error NotAssistant(); + // Caller is not entitiy's admin + error NotAdmin(); + // Caller is not entitiy's admin and assistant + error NotAdminAndAssistant(); + // Caller is neither the buyer or the seller involved in the exchange + error NotBuyerOrSeller(); + // Caller is not the owner of the voucher + error NotVoucherHolder(); + // Caller is not the buyer + error NotBuyerWallet(); + // Caller is not the agent + error NotAgentWallet(); + // Caller is not dispute resolver assistant + error NotDisputeResolverAssistant(); + // Supplied clerk is not zero address + error ClerkDeprecated(); + + // Account-related + // Entity must be active + error MustBeActive(); + // Seller's address cannot be already used in another seller + error SellerAddressMustBeUnique(); + // Buyer's address cannot be already used in another buyer + error BuyerAddressMustBeUnique(); + // DR's address cannot be already used in another DR + error DisputeResolverAddressMustBeUnique(); + // Agent's address cannot be already used in another agent + error AgentAddressMustBeUnique(); + // Seller does not exist + error NoSuchSeller(); + // Buyer does not exist + error NoSuchBuyer(); + // Dispute resolver does not exist + error NoSuchDisputeResolver(); + // Agent does not exist + error NoSuchAgent(); + // Buyer is involved in an non-finalized exchange + error WalletOwnsVouchers(); + // Escalation period is not greater than zero or is more than the max allowed + error InvalidEscalationPeriod(); + // Action would remove the last supported fee from the DR (must always have at least one) + error InexistentDisputeResolverFees(); + // Trying to add a fee that already exists + error DuplicateDisputeResolverFees(); + // Trying to add a fee with non-zero amount + error FeeAmountNotYetSupported(); + // Trying to remove a fee that does not exist + error DisputeResolverFeeNotFound(); + // Trying to approve a seller that is already approved (list of sellers that DR will handle disputes for) + error SellerAlreadyApproved(); + // Trying to assing a DR that had not approved the seller + error SellerNotApproved(); + // Trying to add or removed 0 sellers + error InexistentAllowedSellersList(); + // Custom auth token is not yet supported + error InvalidAuthTokenType(); + // Seller must use either and address or auth token for authentication, but not both + error AdminOrAuthToken(); + // A single auth token can only be used by one seller + error AuthTokenMustBeUnique(); + // Sum of protocol and agent fee exceed the max allowed fee + error InvalidAgentFeePercentage(); + // Trying to finalize the update, while it's not even started + error NoPendingUpdateForAccount(); + // Only the account itself can finalize the update + error UnauthorizedCallerUpdate(); + // Trying to update the account with the same values + error NoUpdateApplied(); + // Creating a seller's collection failed + error CloneCreationFailed(); + // Seller's salt is already used by another seller + error SellerSaltNotUnique(); + + // Offer related + // Offer does not exist + error NoSuchOffer(); + // Offer finishes in the past or it starts after it finishes + error InvalidOfferPeriod(); + // Buyer cancelation penalty is higher than the item price + error InvalidOfferPenalty(); + // New offer must be actiove + error OfferMustBeActive(); + // Offer can be added to same group only once + error OfferMustBeUnique(); + // Offer has been voided + error OfferHasBeenVoided(); + // Current timestamp is higher than offer's expiry timestamp + error OfferHasExpired(); + // Current timestamp is lower than offer's start timestamp + error OfferNotAvailable(); + // Offer's quantity available is zero + error OfferSoldOut(); + // Buyer is not allowed to commit to the offer (does not meet the token gating requirements) + error CannotCommit(); + // Bundle cannot be created since exchganes for offer exist already + error ExchangeForOfferExists(); + // Voucher must have either a fixed expiry or a fixed redeemable period, not both + error AmbiguousVoucherExpiry(); + // Redemption period starts after it ends or it ends before offer itself expires + error InvalidRedemptionPeriod(); + // Dispute period is less than minimal dispute period allowed + error InvalidDisputePeriod(); + // Resolution period is not within the allowed range or it's being misconfigured (minimal > maximal) + error InvalidResolutionPeriod(); + // Dispute resolver does not exist or is not active + error InvalidDisputeResolver(); + // Quantity available is zero + error InvalidQuantityAvailable(); + // Chose DR does not support the fees in the chosen exchange token + error DRUnsupportedFee(); + // Sum of protocol and agent fee exceed the max allowed fee + error AgentFeeAmountTooHigh(); + // Collection does not exist + error NoSuchCollection(); + + // Group related + // Group does not exist + error NoSuchGroup(); + // Offer is not in a group + error OfferNotInGroup(); + // Group remains the same + error NothingUpdated(); + // There is a logical error in the group's condition parameters or it's not supported yet + error InvalidConditionParameters(); + // Group does not have a condition + error GroupHasNoCondition(); + // Group has a condition + error GroupHasCondition(); + // User exhaused the number of commits allowed for the group + error MaxCommitsReached(); + // The supplied token id is outside the condition's range + error TokenIdNotInConditionRange(); + // ERC20 and ERC721 require zero token id + error InvalidTokenId(); + + // Exchange related + // Exchange does not exist + error NoSuchExchange(); + // Exchange cannot be completed yet + error DisputePeriodNotElapsed(); + // Current timestamp is outside the voucher's redeemable period + error VoucherNotRedeemable(); + // New expiration date is earlier than existing expiration date + error VoucherExtensionNotValid(); + // Voucher cannot be expired yet + error VoucherStillValid(); + // Voucher has expired and cannot be transferred anymore + error VoucherHasExpired(); + // Exchange has not been finalized yet + error ExchangeIsNotInAFinalState(); + // Exchange with the same id already exists + error ExchangeAlreadyExists(); + // Range length is 0, is more than quantity available or it would cause an overflow + error InvalidRangeLength(); + + // Twin related + // Twin does not exist + error NoSuchTwin(); + // Seller did not approve the twin transfer + error NoTransferApproved(); + // Twin transfer failed + error TwinTransferUnsuccessful(); + // Token address is 0 or it does not implement the required interface + error UnsupportedToken(); + // Twin cannot be removed if it's in a bundle + error BundleForTwinExists(); + // Supply available is zero + error InvalidSupplyAvailable(); + // Twin is Fungible or Multitoken and amount was set + error InvalidAmount(); + // Twin is NonFungible and amount was not set + error InvalidTwinProperty(); // ToDo consider replacing with InvalidAmount + // Token range overlap with another, starting token id is too high or end of range would overflow + error InvalidTwinTokenRange(); + // Token does not support IERC721 interface + error InvalidTokenAddress(); + + // Bundle related + // Bundle does not exist + error NoSuchBundle(); + // Twin is not in a bundle + error TwinNotInBundle(); + // Offer is not in a bundle + error OfferNotInBundle(); + // Offer can appear in a bundle only once + error BundleOfferMustBeUnique(); + // Twin can appear in a bundle only once + error BundleTwinMustBeUnique(); + // Twin supply does not covver all offers in the bundle + error InsufficientTwinSupplyToCoverBundleOffers(); + // Bundle cannot be created without an offer or a twin + error BundleRequiresAtLeastOneTwinAndOneOffer(); + + // Funds related + // Native token must be represented with zero address + error NativeWrongAddress(); + // Amount sent along (msg.value) does not match the expected amount + error NativeWrongAmount(); + // Token list lenght does not match the amount list length + error TokenAmountMismatch(); // ToDo consider replacing with ArrayLengthMismatch + // Token list is empty + error NothingToWithdraw(); + // Call is not allowed to transfer the funds + error NotAuthorized(); + // Token transfer failed + error TokenTransferFailed(); + // Received amount does not match the expected amount + error InsufficientValueReceived(); + // Seller's pool does not have enough funds to encumber + error InsufficientAvailableFunds(); + // Native token was sent when ERC20 was expected + error NativeNotAllowed(); + // Trying to deposit zero amount + error ZeroDepositNotAllowed(); + + // Meta-Transactions related + // Meta-transaction nonce is invalid + error NonceUsedAlready(); + // Signature does not match the signer + error SignerAndSignatureDoNotMatch(); + // Function signature does not match it's name + error InvalidFunctionName(); + // Signature has invalid parameters + error InvalidSignature(); + // Function is not allowed to be executed as a meta-transaction + error FunctionNotAllowlisted(); + + // Dispute related + // Dispute cannot be raised since the period to do it has elapsed + error DisputePeriodHasElapsed(); + // Dispute cannot be resolved anymore and must be finalized with expireDispute + error DisputeHasExpired(); + // Buyer gets more than 100% of the total pot + error InvalidBuyerPercent(); + // Dispute is still valid and cannot be expired yet + error DisputeStillValid(); + // New dispute timeout is earlier than existing dispute timeout + error InvalidDisputeTimeout(); + // Absolute zero offers cannot be escalated + error EscalationNotAllowed(); + + // Config related + // Percentage exceeds 100% + error InvalidFeePercentage(); + // Zero config value is not allowed + error ValueZeroNotAllowed(); + + // BosonVoucher + // Trying to issue an voucher that is in a reseverd range + error ExchangeIdInReservedRange(); + // Trying to premint vouchers for an offer that does not have a reserved range + error NoReservedRangeForOffer(); + // Trying to reserve a range that is already reserved + error OfferRangeAlreadyReserved(); + // Range start at 0 is not allowed + error InvalidRangeStart(); + // Amount to premint exceeds the range length + error InvalidAmountToMint(); + // Trying to silent mint vouchers not belonging to the range owner + error NoSilentMintAllowed(); + // Trying to premint the voucher of already expired offer + error OfferExpiredOrVoided(); + // Trying to burn preminted vouchers of still valid offer + error OfferStillValid(); + // Trying to burn more vouchers than available + error AmountExceedsRangeOrNothingToBurn(); + // Royalty fee exceeds the max allowed + error InvalidRoyaltyFee(); + // Trying to assign the premined vouchers to the address that is neither the contract owner nor the contract itself + error InvalidToAddress(); + // Call to an external contract was not successful + error ExternalCallFailed(); + // Trying to interact with external contract in a way that could result in transferring assets from the contract + error InteractionNotAllowed(); + + // Price discovery related + // Price discovery returned a price that is too low + error PriceTooLow(); + // Token id is mandatory for bid orders and wrappers + error TokenIdMandatory(); + // Incoming token id does not match the expected one + error TokenIdMismatch(); + // Using price discovery for non-price discovery offer or using ordinary commit for price discovery offer + error InvalidPriceType(); + // Missing price discovery contract address or data + error InvalidPriceDiscovery(); + // Trying to set incoming voucher when it's already set, indicating reentrancy + error IncomingVoucherAlreadySet(); + // Conduit address must be zero () + error InvalidConduitAddress(); + // Protocol does not know what token id to use + error TokenIdNotSet(); + // Transferring a preminted voucher to wrong recipient + error VoucherTransferNotAllowed(); + // Price discovery contract returned a negative price + error NegativePriceNotAllowed(); + // Price discovery did not send the voucher to the protocol + error VoucherNotReceived(); + // Either token with wrong id received or wrong voucher contract made the transfer + error UnexpectedERC721Received(); + // Royalty fee exceeds the price + error FeeAmountTooHigh(); +} diff --git a/contracts/interfaces/handlers/IBosonAccountHandler.sol b/contracts/interfaces/handlers/IBosonAccountHandler.sol index 59c390261..a0ad9260e 100644 --- a/contracts/interfaces/handlers/IBosonAccountHandler.sol +++ b/contracts/interfaces/handlers/IBosonAccountHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonAccountEvents } from "../events/IBosonAccountEvents.sol"; /** @@ -11,7 +12,7 @@ import { IBosonAccountEvents } from "../events/IBosonAccountEvents.sol"; * * The ERC-165 identifier for this interface is: 0xbc1d7461 */ -interface IBosonAccountHandler is IBosonAccountEvents { +interface IBosonAccountHandler is IBosonAccountEvents, BosonErrors { /** * @notice Creates a seller. * diff --git a/contracts/interfaces/handlers/IBosonBundleHandler.sol b/contracts/interfaces/handlers/IBosonBundleHandler.sol index 466109993..a3063e984 100644 --- a/contracts/interfaces/handlers/IBosonBundleHandler.sol +++ b/contracts/interfaces/handlers/IBosonBundleHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonBundleEvents } from "../events/IBosonBundleEvents.sol"; /** @@ -11,7 +12,7 @@ import { IBosonBundleEvents } from "../events/IBosonBundleEvents.sol"; * * The ERC-165 identifier for this interface is: 0x7b53dece */ -interface IBosonBundleHandler is IBosonBundleEvents { +interface IBosonBundleHandler is BosonErrors, IBosonBundleEvents { /** * @notice Creates a Bundle. * diff --git a/contracts/interfaces/handlers/IBosonConfigHandler.sol b/contracts/interfaces/handlers/IBosonConfigHandler.sol index bea11374a..0b870d591 100644 --- a/contracts/interfaces/handlers/IBosonConfigHandler.sol +++ b/contracts/interfaces/handlers/IBosonConfigHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonConfigEvents } from "../events/IBosonConfigEvents.sol"; /** @@ -11,7 +12,7 @@ import { IBosonConfigEvents } from "../events/IBosonConfigEvents.sol"; * * The ERC-165 identifier for this interface is: 0xbc28d3e6 */ -interface IBosonConfigHandler is IBosonConfigEvents { +interface IBosonConfigHandler is IBosonConfigEvents, BosonErrors { /** * @notice Sets the Boson Token (ERC-20 contract) address. * diff --git a/contracts/interfaces/handlers/IBosonDisputeHandler.sol b/contracts/interfaces/handlers/IBosonDisputeHandler.sol index 1febe3c34..87aa4394e 100644 --- a/contracts/interfaces/handlers/IBosonDisputeHandler.sol +++ b/contracts/interfaces/handlers/IBosonDisputeHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonDisputeEvents } from "../events/IBosonDisputeEvents.sol"; import { IBosonFundsLibEvents } from "../events/IBosonFundsEvents.sol"; @@ -12,7 +13,7 @@ import { IBosonFundsLibEvents } from "../events/IBosonFundsEvents.sol"; * * The ERC-165 identifier for this interface is: 0xd9ea8317 */ -interface IBosonDisputeHandler is IBosonDisputeEvents, IBosonFundsLibEvents { +interface IBosonDisputeHandler is BosonErrors, IBosonDisputeEvents, IBosonFundsLibEvents { /** * @notice Raises a dispute. * diff --git a/contracts/interfaces/handlers/IBosonExchangeHandler.sol b/contracts/interfaces/handlers/IBosonExchangeHandler.sol index d5fbbb83e..ff52b67e5 100644 --- a/contracts/interfaces/handlers/IBosonExchangeHandler.sol +++ b/contracts/interfaces/handlers/IBosonExchangeHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonExchangeEvents } from "../events/IBosonExchangeEvents.sol"; import { IBosonTwinEvents } from "../events/IBosonTwinEvents.sol"; import { IBosonFundsLibEvents } from "../events/IBosonFundsEvents.sol"; @@ -13,7 +14,7 @@ import { IBosonFundsLibEvents } from "../events/IBosonFundsEvents.sol"; * * The ERC-165 identifier for this interface is: 0x0e1fefcb */ -interface IBosonExchangeHandler is IBosonExchangeEvents, IBosonFundsLibEvents, IBosonTwinEvents { +interface IBosonExchangeHandler is BosonErrors, IBosonExchangeEvents, IBosonFundsLibEvents, IBosonTwinEvents { /** * @notice Commits to a static offer (first step of an exchange). * diff --git a/contracts/interfaces/handlers/IBosonFundsHandler.sol b/contracts/interfaces/handlers/IBosonFundsHandler.sol index f2ddde462..fb0d0d613 100644 --- a/contracts/interfaces/handlers/IBosonFundsHandler.sol +++ b/contracts/interfaces/handlers/IBosonFundsHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonFundsEvents } from "../events/IBosonFundsEvents.sol"; import { IBosonFundsLibEvents } from "../events/IBosonFundsEvents.sol"; @@ -12,7 +13,7 @@ import { IBosonFundsLibEvents } from "../events/IBosonFundsEvents.sol"; * * The ERC-165 identifier for this interface is: 0x2f4a64d7 */ -interface IBosonFundsHandler is IBosonFundsEvents, IBosonFundsLibEvents { +interface IBosonFundsHandler is IBosonFundsEvents, IBosonFundsLibEvents, BosonErrors { /** * @notice Receives funds from the caller, maps funds to the seller id and stores them so they can be used during the commitToOffer. * diff --git a/contracts/interfaces/handlers/IBosonGroupHandler.sol b/contracts/interfaces/handlers/IBosonGroupHandler.sol index c2ad15fda..59408f1b3 100644 --- a/contracts/interfaces/handlers/IBosonGroupHandler.sol +++ b/contracts/interfaces/handlers/IBosonGroupHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonGroupEvents } from "../events/IBosonGroupEvents.sol"; /** @@ -11,7 +12,7 @@ import { IBosonGroupEvents } from "../events/IBosonGroupEvents.sol"; * * The ERC-165 identifier for this interface is: 0x08ccdf47 */ -interface IBosonGroupHandler is IBosonGroupEvents { +interface IBosonGroupHandler is BosonErrors, IBosonGroupEvents { /** * @notice Creates a group. * diff --git a/contracts/interfaces/handlers/IBosonMetaTransactionsHandler.sol b/contracts/interfaces/handlers/IBosonMetaTransactionsHandler.sol index fb233de45..814b386fc 100644 --- a/contracts/interfaces/handlers/IBosonMetaTransactionsHandler.sol +++ b/contracts/interfaces/handlers/IBosonMetaTransactionsHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonMetaTransactionsEvents } from "../events/IBosonMetaTransactionsEvents.sol"; /** @@ -11,7 +12,7 @@ import { IBosonMetaTransactionsEvents } from "../events/IBosonMetaTransactionsEv * * The ERC-165 identifier for this interface is: 0xb3e4e803 */ -interface IBosonMetaTransactionsHandler is IBosonMetaTransactionsEvents { +interface IBosonMetaTransactionsHandler is IBosonMetaTransactionsEvents, BosonErrors { /** * @notice Checks nonce and returns true if used already for a specific address. * diff --git a/contracts/interfaces/handlers/IBosonOfferHandler.sol b/contracts/interfaces/handlers/IBosonOfferHandler.sol index 9eefbaa3c..5c6a9b899 100644 --- a/contracts/interfaces/handlers/IBosonOfferHandler.sol +++ b/contracts/interfaces/handlers/IBosonOfferHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonOfferEvents } from "../events/IBosonOfferEvents.sol"; /** @@ -11,7 +12,7 @@ import { IBosonOfferEvents } from "../events/IBosonOfferEvents.sol"; * * The ERC-165 identifier for this interface is: 0x67991d09 */ -interface IBosonOfferHandler is IBosonOfferEvents { +interface IBosonOfferHandler is BosonErrors, IBosonOfferEvents { /** * @notice Creates an offer. * diff --git a/contracts/interfaces/handlers/IBosonOrchestrationHandler.sol b/contracts/interfaces/handlers/IBosonOrchestrationHandler.sol index b2de2bb5d..44b438f32 100644 --- a/contracts/interfaces/handlers/IBosonOrchestrationHandler.sol +++ b/contracts/interfaces/handlers/IBosonOrchestrationHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonAccountEvents } from "../events/IBosonAccountEvents.sol"; import { IBosonGroupEvents } from "../events/IBosonGroupEvents.sol"; import { IBosonOfferEvents } from "../events/IBosonOfferEvents.sol"; @@ -20,7 +21,8 @@ interface IBosonOrchestrationHandler is IBosonGroupEvents, IBosonOfferEvents, IBosonTwinEvents, - IBosonBundleEvents + IBosonBundleEvents, + BosonErrors { /** * @notice Raises a dispute and immediately escalates it. diff --git a/contracts/interfaces/handlers/IBosonPauseHandler.sol b/contracts/interfaces/handlers/IBosonPauseHandler.sol index 873400a46..985a6261f 100644 --- a/contracts/interfaces/handlers/IBosonPauseHandler.sol +++ b/contracts/interfaces/handlers/IBosonPauseHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonPauseEvents } from "../events/IBosonPauseEvents.sol"; /** @@ -11,7 +12,7 @@ import { IBosonPauseEvents } from "../events/IBosonPauseEvents.sol"; * * The ERC-165 identifier for this interface is: 0x770b96d0 */ -interface IBosonPauseHandler is IBosonPauseEvents { +interface IBosonPauseHandler is IBosonPauseEvents, BosonErrors { /** * @notice Pauses some or all of the protocol. * diff --git a/contracts/interfaces/handlers/IBosonPriceDiscoveryHandler.sol b/contracts/interfaces/handlers/IBosonPriceDiscoveryHandler.sol index b93a7daf3..a7504e9b9 100644 --- a/contracts/interfaces/handlers/IBosonPriceDiscoveryHandler.sol +++ b/contracts/interfaces/handlers/IBosonPriceDiscoveryHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonExchangeEvents } from "../events/IBosonExchangeEvents.sol"; import { IBosonTwinEvents } from "../events/IBosonTwinEvents.sol"; import { IBosonFundsLibEvents } from "../events/IBosonFundsEvents.sol"; @@ -13,7 +14,7 @@ import { IBosonFundsLibEvents } from "../events/IBosonFundsEvents.sol"; * * The ERC-165 identifier for this interface is: 0xdec319c9 */ -interface IBosonPriceDiscoveryHandler is IBosonExchangeEvents, IBosonFundsLibEvents, IBosonTwinEvents { +interface IBosonPriceDiscoveryHandler is BosonErrors, IBosonExchangeEvents, IBosonFundsLibEvents, IBosonTwinEvents { /** * @notice Commits to a price discovery offer (first step of an exchange). * diff --git a/contracts/interfaces/handlers/IBosonProtocolInitializationHandler.sol b/contracts/interfaces/handlers/IBosonProtocolInitializationHandler.sol index 0ae37afb8..93da4d02f 100644 --- a/contracts/interfaces/handlers/IBosonProtocolInitializationHandler.sol +++ b/contracts/interfaces/handlers/IBosonProtocolInitializationHandler.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.21; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import "../events/IBosonProtocolInitializationEvents.sol"; import "../events/IBosonConfigEvents.sol"; @@ -11,7 +12,7 @@ import "../events/IBosonConfigEvents.sol"; * * The ERC-165 identifier for this interface is: 0x0d8e6e2c */ -interface IBosonProtocolInitializationHandler is IBosonProtocolInitializationEvents, IBosonConfigEvents { +interface IBosonProtocolInitializationHandler is IBosonProtocolInitializationEvents, IBosonConfigEvents, BosonErrors { /** * @notice Gets the current protocol version. * diff --git a/contracts/interfaces/handlers/IBosonSequentialCommitHandler.sol b/contracts/interfaces/handlers/IBosonSequentialCommitHandler.sol index 461b58597..378e2c1aa 100644 --- a/contracts/interfaces/handlers/IBosonSequentialCommitHandler.sol +++ b/contracts/interfaces/handlers/IBosonSequentialCommitHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonExchangeEvents } from "../events/IBosonExchangeEvents.sol"; import { IBosonFundsLibEvents } from "../events/IBosonFundsEvents.sol"; @@ -12,7 +13,7 @@ import { IBosonFundsLibEvents } from "../events/IBosonFundsEvents.sol"; * * The ERC-165 identifier for this interface is: 0x34780cc6 */ -interface IBosonSequentialCommitHandler is IBosonExchangeEvents, IBosonFundsLibEvents { +interface IBosonSequentialCommitHandler is BosonErrors, IBosonExchangeEvents, IBosonFundsLibEvents { /** * @notice Commits to an existing exchange. Price discovery is offloaded to external contract. * diff --git a/contracts/interfaces/handlers/IBosonTwinHandler.sol b/contracts/interfaces/handlers/IBosonTwinHandler.sol index 352444ce1..2e7b2b790 100644 --- a/contracts/interfaces/handlers/IBosonTwinHandler.sol +++ b/contracts/interfaces/handlers/IBosonTwinHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import { BosonTypes } from "../../domain/BosonTypes.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonTwinEvents } from "../events/IBosonTwinEvents.sol"; /** @@ -11,7 +12,7 @@ import { IBosonTwinEvents } from "../events/IBosonTwinEvents.sol"; * * The ERC-165 identifier for this interface is: 0x60b30e70 */ -interface IBosonTwinHandler is IBosonTwinEvents { +interface IBosonTwinHandler is BosonErrors, IBosonTwinEvents { /** * @notice Creates a Twin. * diff --git a/contracts/mock/MockExchangeHandlerFacet.sol b/contracts/mock/MockExchangeHandlerFacet.sol index 9ecf1fa6c..e15e5f41a 100644 --- a/contracts/mock/MockExchangeHandlerFacet.sol +++ b/contracts/mock/MockExchangeHandlerFacet.sol @@ -83,7 +83,9 @@ contract MockExchangeHandlerFacet is BuyerBase, DisputeBase { // N.B. An existing buyer or seller may be the "anyone else" on an exchange they are not a part of if (!buyerExists || buyerId != exchange.buyerId) { uint256 elapsed = block.timestamp - voucher.redeemedDate; - require(elapsed >= fetchOfferDurations(offerId).disputePeriod, DISPUTE_PERIOD_NOT_ELAPSED); + if (elapsed < fetchOfferDurations(offerId).disputePeriod) { + revert DisputePeriodNotElapsed(); + } } // Finalize the exchange @@ -145,7 +147,9 @@ contract MockExchangeHandlerFacet is BuyerBase, DisputeBase { (, offer) = fetchOffer(exchange.offerId); // Only seller's assistant may call - require(sellerExists && offer.sellerId == sellerId, NOT_ASSISTANT); + if (!sellerExists || offer.sellerId != sellerId) { + revert NotAssistant(); + } // Revoke the voucher revokeVoucherInternal(exchange); @@ -196,7 +200,9 @@ contract MockExchangeHandlerFacet is BuyerBase, DisputeBase { (Exchange storage exchange, Voucher storage voucher) = getValidExchange(_exchangeId, ExchangeState.Committed); // Make sure that the voucher has expired - require(block.timestamp >= voucher.validUntilDate, VOUCHER_STILL_VALID); + if (block.timestamp < voucher.validUntilDate) { + revert VoucherStillValid(); + } // Finalize the exchange, burning the voucher finalizeExchange(exchange, ExchangeState.Canceled); @@ -241,10 +247,14 @@ contract MockExchangeHandlerFacet is BuyerBase, DisputeBase { (sellerExists, sellerId) = getSellerIdByAssistant(sender); // Only seller's assistant may call - require(sellerExists && offer.sellerId == sellerId, NOT_ASSISTANT); + if (!sellerExists || offer.sellerId != sellerId) { + revert NotAssistant(); + } // Make sure the proposed date is later than the current one - require(_validUntilDate > voucher.validUntilDate, VOUCHER_EXTENSION_NOT_VALID); + if (_validUntilDate <= voucher.validUntilDate) { + revert VoucherExtensionNotValid(); + } // Extend voucher voucher.validUntilDate = _validUntilDate; @@ -277,11 +287,11 @@ contract MockExchangeHandlerFacet is BuyerBase, DisputeBase { checkBuyer(exchange.buyerId); // Make sure the voucher is redeemable - require( - block.timestamp >= fetchOfferDates(offerId).voucherRedeemableFrom && - block.timestamp <= voucher.validUntilDate, - VOUCHER_NOT_REDEEMABLE - ); + if ( + block.timestamp < fetchOfferDates(offerId).voucherRedeemableFrom || block.timestamp > voucher.validUntilDate + ) { + revert VoucherNotRedeemable(); + } // Store the time the exchange was redeemed voucher.redeemedDate = block.timestamp; diff --git a/contracts/mock/Test3Facet.sol b/contracts/mock/Test3Facet.sol index 2d4f3a791..03fbaf683 100644 --- a/contracts/mock/Test3Facet.sol +++ b/contracts/mock/Test3Facet.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import "../domain/BosonConstants.sol"; +import { BosonErrors } from "../domain/BosonErrors.sol"; import { AddressUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import { TestFacetLib } from "./TestFacetLib.sol"; @@ -13,10 +14,10 @@ import { TestFacetLib } from "./TestFacetLib.sol"; * @author Nick Mudge (https://twitter.com/mudgen) * @author Cliff Hall (https://twitter.com/seaofarrows) */ -contract Test3Facet { +contract Test3Facet is BosonErrors { modifier onlyUninitialized() { TestFacetLib.TestFacetStorage storage tfs = TestFacetLib.testFacetStorage(); - require(!tfs.initialized, ALREADY_INITIALIZED); + if (tfs.initialized) revert AlreadyInitialized(); tfs.initialized = true; _; } diff --git a/contracts/mock/TestInitializableDiamond.sol b/contracts/mock/TestInitializableDiamond.sol index 6f9a93bfd..b9a27db5f 100644 --- a/contracts/mock/TestInitializableDiamond.sol +++ b/contracts/mock/TestInitializableDiamond.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import "../domain/BosonConstants.sol"; +import "../domain/BosonErrors.sol"; import { TestFacetLib } from "./TestFacetLib.sol"; import "../diamond/ProtocolDiamond.sol"; @@ -11,7 +12,7 @@ import "../diamond/ProtocolDiamond.sol"; * @notice Contract for testing initializeable diamond contract * */ -contract TestInitializableDiamond is ProtocolDiamond { +contract TestInitializableDiamond is ProtocolDiamond, BosonErrors { /** * @notice Constructor * @@ -31,7 +32,7 @@ contract TestInitializableDiamond is ProtocolDiamond { modifier onlyUninitialized() { TestFacetLib.TestFacetStorage storage tfs = TestFacetLib.testFacetStorage(); - require(!tfs.initialized, ALREADY_INITIALIZED); + if (tfs.initialized) revert AlreadyInitialized(); tfs.initialized = true; _; } diff --git a/contracts/protocol/bases/BeaconClientBase.sol b/contracts/protocol/bases/BeaconClientBase.sol index c80d2b9fb..20bdfec26 100644 --- a/contracts/protocol/bases/BeaconClientBase.sol +++ b/contracts/protocol/bases/BeaconClientBase.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import "../../domain/BosonConstants.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonOfferHandler } from "../../interfaces/handlers/IBosonOfferHandler.sol"; import { IBosonExchangeHandler } from "../../interfaces/handlers/IBosonExchangeHandler.sol"; import { IBosonAccountHandler } from "../../interfaces/handlers/IBosonAccountHandler.sol"; @@ -18,7 +19,7 @@ import { IClientExternalAddresses } from "../../interfaces/clients/IClientExtern * * Boson client contracts include BosonVoucher */ -abstract contract BeaconClientBase is BosonTypes { +abstract contract BeaconClientBase is BosonTypes, BosonErrors { /** * @dev Modifier that checks that the caller has a specific role. * @@ -30,7 +31,7 @@ abstract contract BeaconClientBase is BosonTypes { * @param _role - the role to check */ modifier onlyRole(bytes32 _role) { - require(BeaconClientLib.hasRole(_role), ACCESS_DENIED); + if (!BeaconClientLib.hasRole(_role)) revert AccessDenied(); _; } diff --git a/contracts/protocol/bases/BundleBase.sol b/contracts/protocol/bases/BundleBase.sol index afacfc875..9549c5d45 100644 --- a/contracts/protocol/bases/BundleBase.sol +++ b/contracts/protocol/bases/BundleBase.sol @@ -42,13 +42,11 @@ contract BundleBase is ProtocolBase, IBosonBundleEvents { // get seller id, make sure it exists and store it to incoming struct (bool exists, uint256 sellerId) = getSellerIdByAssistant(sender); - require(exists, NOT_ASSISTANT); + if (!exists) revert NotAssistant(); // validate that offer ids and twin ids are not empty - require( - _bundle.offerIds.length > 0 && _bundle.twinIds.length > 0, - BUNDLE_REQUIRES_AT_LEAST_ONE_TWIN_AND_ONE_OFFER - ); + if (_bundle.offerIds.length == 0 || _bundle.twinIds.length == 0) + revert BundleRequiresAtLeastOneTwinAndOneOffer(); // Get the next bundle and increment the counter uint256 bundleId = protocolCounters().nextBundleId++; @@ -62,11 +60,11 @@ contract BundleBase is ProtocolBase, IBosonBundleEvents { offersTotalQuantityAvailable = calculateOffersTotalQuantity(offersTotalQuantityAvailable, offerId); (bool bundleByOfferExists, ) = fetchBundleIdByOffer(offerId); - require(!bundleByOfferExists, BUNDLE_OFFER_MUST_BE_UNIQUE); + if (bundleByOfferExists) revert BundleOfferMustBeUnique(); (bool exchangeIdsForOfferExists, ) = getExchangeIdsByOffer(offerId); // make sure exchange does not already exist for this offer id. - require(!exchangeIdsForOfferExists, EXCHANGE_FOR_OFFER_EXISTS); + if (exchangeIdsForOfferExists) revert ExchangeForOfferExists(); // Add to bundleIdByOffer mapping lookups.bundleIdByOffer[offerId] = bundleId; @@ -81,7 +79,7 @@ contract BundleBase is ProtocolBase, IBosonBundleEvents { // A twin can't belong to multiple bundles (bool bundleForTwinExist, ) = fetchBundleIdByTwin(twinId); - require(!bundleForTwinExist, BUNDLE_TWIN_MUST_BE_UNIQUE); + if (bundleForTwinExist) revert BundleTwinMustBeUnique(); bundleSupplyChecks(offersTotalQuantityAvailable, twinId); @@ -121,13 +119,13 @@ contract BundleBase is ProtocolBase, IBosonBundleEvents { (exists, twin) = fetchTwin(_twinId); // Twin must already exist - require(exists, NO_SUCH_TWIN); + if (!exists) revert NoSuchTwin(); // Get seller id, we assume seller id exists if twin exists (, uint256 sellerId) = getSellerIdByAssistant(msgSender()); // Caller's seller id must match twin seller id - require(sellerId == twin.sellerId, NOT_ASSISTANT); + if (sellerId != twin.sellerId) revert NotAssistant(); } /** @@ -147,14 +145,13 @@ contract BundleBase is ProtocolBase, IBosonBundleEvents { // twin is NonFungibleToken or bundle has an unlimited offer if (twin.tokenType == TokenType.NonFungibleToken || _offersTotalQuantity == type(uint256).max) { // the sum of all offers quantity should be less or equal twin supply - require(_offersTotalQuantity <= twin.supplyAvailable, INSUFFICIENT_TWIN_SUPPLY_TO_COVER_BUNDLE_OFFERS); + if (_offersTotalQuantity > twin.supplyAvailable) revert InsufficientTwinSupplyToCoverBundleOffers(); } else { // twin is FungibleToken or MultiToken // the sum of all offers quantity multiplied by twin amount should be less or equal twin supply - require( - _offersTotalQuantity * twin.amount <= twin.supplyAvailable, - INSUFFICIENT_TWIN_SUPPLY_TO_COVER_BUNDLE_OFFERS - ); + if (_offersTotalQuantity * twin.amount > twin.supplyAvailable) { + revert InsufficientTwinSupplyToCoverBundleOffers(); + } } } diff --git a/contracts/protocol/bases/BuyerBase.sol b/contracts/protocol/bases/BuyerBase.sol index 6aa7e89e0..b783042f8 100644 --- a/contracts/protocol/bases/BuyerBase.sol +++ b/contracts/protocol/bases/BuyerBase.sol @@ -26,16 +26,16 @@ contract BuyerBase is ProtocolBase, IBosonAccountEvents { */ function createBuyerInternal(Buyer memory _buyer) internal { //Check for zero address - require(_buyer.wallet != address(0), INVALID_ADDRESS); + if (_buyer.wallet == address(0)) revert InvalidAddress(); //Check active is not set to false - require(_buyer.active, MUST_BE_ACTIVE); + if (!_buyer.active) revert MustBeActive(); // Get the next account id and increment the counter uint256 buyerId = protocolCounters().nextAccountId++; //check that the wallet address is unique to one buyer id - require(protocolLookups().buyerIdByWallet[_buyer.wallet] == 0, BUYER_ADDRESS_MUST_BE_UNIQUE); + if (protocolLookups().buyerIdByWallet[_buyer.wallet] != 0) revert BuyerAddressMustBeUnique(); _buyer.id = buyerId; storeBuyer(_buyer); @@ -80,7 +80,7 @@ contract BuyerBase is ProtocolBase, IBosonAccountEvents { (, Buyer storage buyer) = fetchBuyer(buyerId); // Make sure buyer account is active - require(buyer.active, MUST_BE_ACTIVE); + if (!buyer.active) revert MustBeActive(); } else { // Create the buyer account Buyer memory newBuyer; diff --git a/contracts/protocol/bases/ClientBase.sol b/contracts/protocol/bases/ClientBase.sol index 26c373fad..20cc5f928 100644 --- a/contracts/protocol/bases/ClientBase.sol +++ b/contracts/protocol/bases/ClientBase.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import "../../domain/BosonConstants.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IBosonOfferHandler } from "../../interfaces/handlers/IBosonOfferHandler.sol"; import { IBosonExchangeHandler } from "../../interfaces/handlers/IBosonExchangeHandler.sol"; import { BosonTypes } from "../../domain/BosonTypes.sol"; @@ -16,7 +17,7 @@ import { ClientLib } from "../libs/ClientLib.sol"; * to use `BeaconClientBase` instead * */ -abstract contract ClientBase is BosonTypes { +abstract contract ClientBase is BosonTypes, BosonErrors { /** * @dev Modifier that checks that the caller has a specific role. * @@ -28,7 +29,7 @@ abstract contract ClientBase is BosonTypes { * @param _role - the role to check */ modifier onlyRole(bytes32 _role) { - require(ClientLib.hasRole(_role), ACCESS_DENIED); + if (!ClientLib.hasRole(_role)) revert AccessDenied(); _; } diff --git a/contracts/protocol/bases/ClientExternalAddressesBase.sol b/contracts/protocol/bases/ClientExternalAddressesBase.sol index d4966f2f7..1ceef44ba 100644 --- a/contracts/protocol/bases/ClientExternalAddressesBase.sol +++ b/contracts/protocol/bases/ClientExternalAddressesBase.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import "../../domain/BosonConstants.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { IAccessControl } from "../../interfaces/IAccessControl.sol"; import { IClientExternalAddresses } from "../../interfaces/clients/IClientExternalAddresses.sol"; import { IBosonConfigHandler } from "../../interfaces/handlers/IBosonConfigHandler.sol"; @@ -12,7 +13,7 @@ import { ClientLib } from "../libs/ClientLib.sol"; * * @notice Helps minimal proxies. */ -contract ClientExternalAddressesBase is IClientExternalAddresses { +contract ClientExternalAddressesBase is IClientExternalAddresses, BosonErrors { /** * @dev Modifier that checks that the caller has a specific role. * @@ -23,7 +24,7 @@ contract ClientExternalAddressesBase is IClientExternalAddresses { * @param _role - the role to check */ modifier onlyRole(bytes32 _role) { - require(ClientLib.hasRole(_role), "Access denied, caller doesn't have role"); + if (!ClientLib.hasRole(_role)) revert AccessDenied(); _; } @@ -34,7 +35,7 @@ contract ClientExternalAddressesBase is IClientExternalAddresses { * @param _impl - the implementation address */ constructor(address _protocolAddress, address _impl) { - require(_protocolAddress != address(0) && _impl != address(0), INVALID_ADDRESS); + if (_protocolAddress == address(0) || _impl == address(0)) revert InvalidAddress(); // Get the ProxyStorage struct ClientLib.ProxyStorage storage ps = ClientLib.proxyStorage(); @@ -70,7 +71,7 @@ contract ClientExternalAddressesBase is IClientExternalAddresses { * @param _impl - the implementation address */ function setImplementation(address _impl) external override onlyRole(UPGRADER) { - require(_impl != address(0), INVALID_ADDRESS); + if (_impl == address(0)) revert InvalidAddress(); // Get the ProxyStorage struct ClientLib.ProxyStorage storage ps = ClientLib.proxyStorage(); @@ -114,7 +115,7 @@ contract ClientExternalAddressesBase is IClientExternalAddresses { * @param _protocolAddress - the ProtocolDiamond address */ function setProtocolAddress(address _protocolAddress) external override onlyRole(UPGRADER) { - require(_protocolAddress != address(0), INVALID_ADDRESS); + if (_protocolAddress == address(0)) revert InvalidAddress(); // Get the ProxyStorage struct ClientLib.ProxyStorage storage ps = ClientLib.proxyStorage(); diff --git a/contracts/protocol/bases/DisputeBase.sol b/contracts/protocol/bases/DisputeBase.sol index 5f24cd83f..9c186b64e 100644 --- a/contracts/protocol/bases/DisputeBase.sol +++ b/contracts/protocol/bases/DisputeBase.sol @@ -32,7 +32,7 @@ contract DisputeBase is ProtocolBase, IBosonDisputeEvents, IBosonFundsLibEvents // Make sure the dispute period has not elapsed uint256 elapsed = block.timestamp - _voucher.redeemedDate; - require(elapsed < offerDurations.disputePeriod, DISPUTE_PERIOD_HAS_ELAPSED); + if (elapsed >= offerDurations.disputePeriod) revert DisputePeriodHasElapsed(); // Make sure the caller is buyer associated with the exchange checkBuyer(_exchange.buyerId); @@ -92,16 +92,16 @@ contract DisputeBase is ProtocolBase, IBosonDisputeEvents, IBosonFundsLibEvents (, Dispute storage dispute, DisputeDates storage disputeDates) = fetchDispute(_exchangeId); // make sure the dispute not expired already - require(block.timestamp <= disputeDates.timeout, DISPUTE_HAS_EXPIRED); + if (block.timestamp > disputeDates.timeout) revert DisputeHasExpired(); // Make sure the dispute is in the resolving state - require(dispute.state == DisputeState.Resolving, INVALID_STATE); + if (dispute.state != DisputeState.Resolving) revert InvalidState(); // Fetch the dispute resolution terms from the storage DisputeResolutionTerms storage disputeResolutionTerms = fetchDisputeResolutionTerms(exchange.offerId); // absolute zero offers can be without DR. In that case we prevent escalation - require(disputeResolutionTerms.disputeResolverId > 0, ESCALATION_NOT_ALLOWED); + if (disputeResolutionTerms.disputeResolverId == 0) revert EscalationNotAllowed(); // fetch offer to get info about dispute resolver id (, Offer storage offer) = fetchOffer(exchange.offerId); diff --git a/contracts/protocol/bases/GroupBase.sol b/contracts/protocol/bases/GroupBase.sol index 1ddffd518..ffecf3f8f 100644 --- a/contracts/protocol/bases/GroupBase.sol +++ b/contracts/protocol/bases/GroupBase.sol @@ -36,10 +36,10 @@ contract GroupBase is ProtocolBase, IBosonGroupEvents { // get seller id, make sure it exists and store it to incoming struct (bool exists, uint256 sellerId) = getSellerIdByAssistant(sender); - require(exists, NOT_ASSISTANT); + if (!exists) revert NotAssistant(); // condition must be valid - require(validateCondition(_condition), INVALID_CONDITION_PARAMETERS); + if (!validateCondition(_condition)) revert InvalidConditionParameters(); // Get the next group and increment the counter uint256 groupId = protocolCounters().nextGroupId++; @@ -50,7 +50,7 @@ contract GroupBase is ProtocolBase, IBosonGroupEvents { // Offer should not belong to another group already (bool exist, ) = getGroupIdByOffer(_group.offerIds[i]); - require(!exist, OFFER_MUST_BE_UNIQUE); + if (exist) revert OfferMustBeUnique(); // add to groupIdByOffer mapping lookups.groupIdByOffer[_group.offerIds[i]] = groupId; @@ -188,7 +188,7 @@ contract GroupBase is ProtocolBase, IBosonGroupEvents { // Offer should not belong to another group already (bool exist, ) = getGroupIdByOffer(offerId); - require(!exist, OFFER_MUST_BE_UNIQUE); + if (exist) revert OfferMustBeUnique(); // add to groupIdByOffer mapping lookups.groupIdByOffer[offerId] = _groupId; @@ -230,18 +230,18 @@ contract GroupBase is ProtocolBase, IBosonGroupEvents { uint256[] memory _offerIds ) internal view returns (uint256 sellerId, Group storage group) { // make sure that at least something will be updated - require(_offerIds.length != 0, NOTHING_UPDATED); + if (_offerIds.length == 0) revert NothingUpdated(); // Get storage location for group bool exists; (exists, group) = fetchGroup(_groupId); - require(exists, NO_SUCH_GROUP); + if (!exists) revert NoSuchGroup(); // Get seller id, we assume seller id exists if group exists (, sellerId) = getSellerIdByAssistant(msgSender()); // Caller's seller id must match group seller id - require(sellerId == group.sellerId, NOT_ASSISTANT); + if (sellerId != group.sellerId) revert NotAssistant(); } } diff --git a/contracts/protocol/bases/OfferBase.sol b/contracts/protocol/bases/OfferBase.sol index a7a7f05d4..e9ca89895 100644 --- a/contracts/protocol/bases/OfferBase.sol +++ b/contracts/protocol/bases/OfferBase.sol @@ -54,7 +54,7 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { ) internal { // get seller id, make sure it exists and store it to incoming struct (bool exists, uint256 sellerId) = getSellerIdByAssistant(msgSender()); - require(exists, NOT_ASSISTANT); + if (!exists) revert NotAssistant(); _offer.sellerId = sellerId; // Get the next offerId and increment the counter uint256 offerId = protocolCounters().nextOfferId++; @@ -113,19 +113,20 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { uint256 _agentId ) internal { // validFrom date must be less than validUntil date - require(_offerDates.validFrom < _offerDates.validUntil, OFFER_PERIOD_INVALID); + if (_offerDates.validFrom >= _offerDates.validUntil) revert InvalidOfferPeriod(); // validUntil date must be in the future - require(_offerDates.validUntil > block.timestamp, OFFER_PERIOD_INVALID); + if (_offerDates.validUntil <= block.timestamp) revert InvalidOfferPeriod(); // exactly one of voucherRedeemableUntil and voucherValid must be zero // if voucherRedeemableUntil exist, it must be greater than validUntil if (_offerDates.voucherRedeemableUntil > 0) { - require(_offerDurations.voucherValid == 0, AMBIGUOUS_VOUCHER_EXPIRY); - require(_offerDates.voucherRedeemableFrom < _offerDates.voucherRedeemableUntil, REDEMPTION_PERIOD_INVALID); - require(_offerDates.voucherRedeemableUntil >= _offerDates.validUntil, REDEMPTION_PERIOD_INVALID); + if (_offerDurations.voucherValid != 0) revert AmbiguousVoucherExpiry(); + if (_offerDates.voucherRedeemableFrom >= _offerDates.voucherRedeemableUntil) + revert InvalidRedemptionPeriod(); + if (_offerDates.voucherRedeemableUntil < _offerDates.validUntil) revert InvalidRedemptionPeriod(); } else { - require(_offerDurations.voucherValid > 0, AMBIGUOUS_VOUCHER_EXPIRY); + if (_offerDurations.voucherValid == 0) revert AmbiguousVoucherExpiry(); } // Operate in a block to avoid "stack too deep" error @@ -134,21 +135,22 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { ProtocolLib.ProtocolLimits storage limits = protocolLimits(); // dispute period must be greater than or equal to the minimum dispute period - require(_offerDurations.disputePeriod >= limits.minDisputePeriod, INVALID_DISPUTE_PERIOD); + if (_offerDurations.disputePeriod < limits.minDisputePeriod) revert InvalidDisputePeriod(); // resolution period must be between the minimum and maximum resolution periods - require( - _offerDurations.resolutionPeriod >= limits.minResolutionPeriod && - _offerDurations.resolutionPeriod <= limits.maxResolutionPeriod, - INVALID_RESOLUTION_PERIOD - ); + if ( + _offerDurations.resolutionPeriod < limits.minResolutionPeriod || + _offerDurations.resolutionPeriod > limits.maxResolutionPeriod + ) { + revert InvalidResolutionPeriod(); + } } // when creating offer, it cannot be set to voided - require(!_offer.voided, OFFER_MUST_BE_ACTIVE); + if (_offer.voided) revert OfferMustBeActive(); // quantity must be greater than zero - require(_offer.quantityAvailable > 0, INVALID_QUANTITY_AVAILABLE); + if (_offer.quantityAvailable == 0) revert InvalidQuantityAvailable(); DisputeResolutionTerms memory disputeResolutionTerms; { @@ -165,7 +167,7 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { DisputeResolver storage disputeResolver, DisputeResolverFee[] storage disputeResolverFees ) = fetchDisputeResolver(_disputeResolverId); - require(exists && disputeResolver.active, INVALID_DISPUTE_RESOLVER); + if (!exists || !disputeResolver.active) revert InvalidDisputeResolver(); // Operate in a block to avoid "stack too deep" error { @@ -173,15 +175,13 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { if (lookups.allowedSellers[_disputeResolverId].length > 0) { // if length == 0, dispute resolver allows any seller // if length > 0, we check that it is on allow list - require( - lookups.allowedSellerIndex[_disputeResolverId][_offer.sellerId] > 0, - SELLER_NOT_APPROVED - ); + if (lookups.allowedSellerIndex[_disputeResolverId][_offer.sellerId] == 0) + revert SellerNotApproved(); } // get the index of DisputeResolverFee and make sure DR supports the exchangeToken uint256 feeIndex = lookups.disputeResolverFeeTokenIndex[_disputeResolverId][_offer.exchangeToken]; - require(feeIndex > 0, DR_UNSUPPORTED_FEE); + if (feeIndex == 0) revert DRUnsupportedFee(); uint256 feeAmount = disputeResolverFees[feeIndex - 1].feeAmount; @@ -199,10 +199,8 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { // Collection must exist. Collections with index 0 exist by default. if (_offer.collectionIndex > 0) { - require( - lookups.additionalCollections[_offer.sellerId].length >= _offer.collectionIndex, - NO_SUCH_COLLECTION - ); + if (lookups.additionalCollections[_offer.sellerId].length < _offer.collectionIndex) + revert NoSuchCollection(); } } @@ -213,7 +211,7 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { (bool agentExists, Agent storage agent) = fetchAgent(_agentId); // Make sure agent exists if _agentId is not zero. - require(_agentId == 0 || agentExists, NO_SUCH_AGENT); + if (_agentId != 0 && !agentExists) revert NoSuchAgent(); // Operate in a block to avoid "stack too deep" error { @@ -221,7 +219,7 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { uint256 offerPrice = _offer.price; // condition for successful payout when exchange final state is canceled - require(_offer.buyerCancelPenalty <= offerPrice, OFFER_PENALTY_INVALID); + if (_offer.buyerCancelPenalty > offerPrice) revert InvalidOfferPenalty(); // Calculate and set the protocol fee uint256 protocolFee = getProtocolFee(_offer.exchangeToken, offerPrice); @@ -232,7 +230,7 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { uint256 totalOfferFeeLimit = (protocolLimits().maxTotalOfferFeePercentage * offerPrice) / 10000; // Sum of agent fee amount and protocol fee amount should be <= offer fee limit - require((agentFeeAmount + protocolFee) <= totalOfferFeeLimit, AGENT_FEE_AMOUNT_TOO_HIGH); + if ((agentFeeAmount + protocolFee) > totalOfferFeeLimit) revert AgentFeeAmountTooHigh(); //Set offer fees props individually since calldata structs can't be copied to storage offerFees.protocolFee = protocolFee; @@ -316,14 +314,12 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { // Get offer, make sure the caller is the assistant Offer storage offer = getValidOfferWithSellerCheck(_offerId); - // Prevent reservation of an empty range - require(_length > 0, INVALID_RANGE_LENGTH); - - // Cannot reserve more than it's available - require(offer.quantityAvailable >= _length, INVALID_RANGE_LENGTH); - - // Prevent reservation of too large range, since it affects exchangeId - require(_length <= type(uint64).max, INVALID_RANGE_LENGTH); + // Invalid ranges: + // - Empty range + // - Too large range, since it affects exchangeId + // - More than quantity available + if (_length == 0 || _length > type(uint64).max || offer.quantityAvailable < _length) + revert InvalidRangeLength(); // Get starting token id ProtocolLib.ProtocolCounters storage pc = protocolCounters(); @@ -336,7 +332,7 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { address sender = msgSender(); // _to must be the contract address or the contract owner - require(_to == address(bosonVoucher) || _to == sender, INVALID_TO_ADDRESS); + if (_to != address(bosonVoucher) && _to != sender) revert InvalidToAddress(); // increase exchangeIds pc.nextExchangeId = _startId + _length; diff --git a/contracts/protocol/bases/PausableBase.sol b/contracts/protocol/bases/PausableBase.sol index 3025f3484..ace5ed59a 100644 --- a/contracts/protocol/bases/PausableBase.sol +++ b/contracts/protocol/bases/PausableBase.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import "./../../domain/BosonConstants.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { ProtocolLib } from "../libs/ProtocolLib.sol"; import { BosonTypes } from "../../domain/BosonTypes.sol"; @@ -177,6 +178,6 @@ contract PausableBase is BosonTypes { function revertIfPaused(PausableRegion _region) internal view { // Region enum value must be used as the exponent in a power of 2 uint256 powerOfTwo = 1 << uint256(_region); - require((ProtocolLib.protocolStatus().pauseScenario & powerOfTwo) != powerOfTwo, REGION_PAUSED); + if ((ProtocolLib.protocolStatus().pauseScenario & powerOfTwo) == powerOfTwo) revert BosonErrors.RegionPaused(); } } diff --git a/contracts/protocol/bases/PriceDiscoveryBase.sol b/contracts/protocol/bases/PriceDiscoveryBase.sol index 10dc1049b..18b31df13 100644 --- a/contracts/protocol/bases/PriceDiscoveryBase.sol +++ b/contracts/protocol/bases/PriceDiscoveryBase.sol @@ -63,10 +63,14 @@ contract PriceDiscoveryBase is ProtocolBase { address _seller, address _buyer ) internal returns (uint256 actualPrice) { - require( - _priceDiscovery.priceDiscoveryContract != address(0) && _priceDiscovery.conduit != address(0), - PRICE_DISCOVERY_CONTRACTS_NOT_SET - ); + // Make sure caller provided price discovery data + if (_priceDiscovery.priceDiscoveryContract == address(0) || _priceDiscovery.priceDiscoveryData.length == 0) { + revert InvalidPriceDiscovery(); + } + + // If not dealing with wrapper, voucher is transferred using the conduit which must not be zero address + if (_priceDiscovery.side != Side.Wrapper && _priceDiscovery.conduit == address(0)) + revert InvalidConduitAddress(); IBosonVoucher bosonVoucher = IBosonVoucher( getCloneAddress(protocolLookups(), _offer.sellerId, _offer.collectionIndex) @@ -128,7 +132,7 @@ contract PriceDiscoveryBase is ProtocolBase { _priceDiscovery.priceDiscoveryContract.functionCallWithValue(_priceDiscovery.priceDiscoveryData, msg.value); uint256 protocolBalanceAfter = getBalance(_exchangeToken, address(this)); - require(protocolBalanceBefore >= protocolBalanceAfter, NEGATIVE_PRICE_NOT_ALLOWED); + if (protocolBalanceBefore < protocolBalanceAfter) revert NegativePriceNotAllowed(); actualPrice = protocolBalanceBefore - protocolBalanceAfter; // If token is ERC20, reset approval @@ -140,7 +144,7 @@ contract PriceDiscoveryBase is ProtocolBase { { // Make sure that the price discovery contract has transferred the voucher to the protocol - require(_bosonVoucher.ownerOf(_tokenId) == address(this), VOUCHER_NOT_RECEIVED); + if (_bosonVoucher.ownerOf(_tokenId) != address(this)) revert VoucherNotReceived(); // Transfer voucher to buyer _bosonVoucher.transferFrom(address(this), _buyer, _tokenId); @@ -182,10 +186,10 @@ contract PriceDiscoveryBase is ProtocolBase { address _seller, IBosonVoucher _bosonVoucher ) internal returns (uint256 actualPrice) { - require(_tokenId != 0, TOKEN_ID_MANDATORY); + if (_tokenId == 0) revert TokenIdMandatory(); address sender = msgSender(); - require(_seller == sender, NOT_VOUCHER_HOLDER); + if (_seller != sender) revert NotVoucherHolder(); // Transfer seller's voucher to protocol // Don't need to use safe transfer from, since that protocol can handle the voucher @@ -220,11 +224,11 @@ contract PriceDiscoveryBase is ProtocolBase { } // Calculate actual price - require(protocolBalanceAfter >= protocolBalanceBefore, NEGATIVE_PRICE_NOT_ALLOWED); + if (protocolBalanceAfter < protocolBalanceBefore) revert NegativePriceNotAllowed(); actualPrice = protocolBalanceAfter - protocolBalanceBefore; // Make sure that balance change is at least the expected price - require(actualPrice >= _priceDiscovery.price, INSUFFICIENT_VALUE_RECEIVED); + if (actualPrice < _priceDiscovery.price) revert InsufficientValueReceived(); // Verify that token id provided by caller matches the token id that the price discovery contract has sent to buyer getAndVerifyTokenId(_tokenId); @@ -251,11 +255,11 @@ contract PriceDiscoveryBase is ProtocolBase { PriceDiscovery calldata _priceDiscovery, IBosonVoucher _bosonVoucher ) internal returns (uint256 actualPrice) { - require(_tokenId != 0, TOKEN_ID_MANDATORY); + if (_tokenId == 0) revert TokenIdMandatory(); // If price discovery contract does not own the voucher, it cannot be classified as a wrapper address owner = _bosonVoucher.ownerOf(_tokenId); - require(owner == _priceDiscovery.priceDiscoveryContract, NOT_VOUCHER_HOLDER); + if (owner != _priceDiscovery.priceDiscoveryContract) revert NotVoucherHolder(); // Check balance before calling wrapper bool isNative = _exchangeToken == address(0); @@ -278,12 +282,12 @@ contract PriceDiscoveryBase is ProtocolBase { uint256 protocolBalanceAfter = getBalance(_exchangeToken, address(this)); // Verify that actual price is within the expected range - require(protocolBalanceAfter >= protocolBalanceBefore, NEGATIVE_PRICE_NOT_ALLOWED); + if (protocolBalanceAfter < protocolBalanceBefore) revert NegativePriceNotAllowed(); actualPrice = protocolBalanceAfter - protocolBalanceBefore; // when working with wrappers, price is already known, so the caller should set it exactly // If protocol receive more than expected, it does not return the surplus to the caller - require(actualPrice == _priceDiscovery.price, PRICE_TOO_LOW); + if (actualPrice != _priceDiscovery.price) revert PriceTooLow(); // Verify that token id provided by caller matches the token id that the price discovery contract has sent to buyer getAndVerifyTokenId(_tokenId); @@ -314,14 +318,14 @@ contract PriceDiscoveryBase is ProtocolBase { // If caller has provided token id, it must match the token id that the price discovery send to the protocol if (_tokenId != 0) { - require(_tokenId == ps.incomingVoucherId, TOKEN_ID_MISMATCH); + if (_tokenId != ps.incomingVoucherId) revert TokenIdMismatch(); } else { // If caller has not provided token id, use the one stored in onPremintedVoucherTransfer function _tokenId = ps.incomingVoucherId; } // Token id cannot be zero at this point - require(_tokenId != 0, TOKEN_ID_NOT_SET); + if (_tokenId == 0) revert TokenIdNotSet(); return _tokenId; } diff --git a/contracts/protocol/bases/ProtocolBase.sol b/contracts/protocol/bases/ProtocolBase.sol index c8094f393..1f026226e 100644 --- a/contracts/protocol/bases/ProtocolBase.sol +++ b/contracts/protocol/bases/ProtocolBase.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import "../../domain/BosonConstants.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { ProtocolLib } from "../libs/ProtocolLib.sol"; import { DiamondLib } from "../../diamond/DiamondLib.sol"; import { EIP712Lib } from "../libs/EIP712Lib.sol"; @@ -14,13 +15,13 @@ import { ReentrancyGuardBase } from "./ReentrancyGuardBase.sol"; * * @notice Provides domain and common modifiers to Protocol facets */ -abstract contract ProtocolBase is PausableBase, ReentrancyGuardBase { +abstract contract ProtocolBase is PausableBase, ReentrancyGuardBase, BosonErrors { /** * @notice Modifier to protect initializer function from being invoked twice. */ modifier onlyUninitialized(bytes4 interfaceId) { ProtocolLib.ProtocolStatus storage ps = protocolStatus(); - require(!ps.initializedInterfaces[interfaceId], ALREADY_INITIALIZED); + if (ps.initializedInterfaces[interfaceId]) revert AlreadyInitialized(); ps.initializedInterfaces[interfaceId] = true; _; } @@ -36,7 +37,7 @@ abstract contract ProtocolBase is PausableBase, ReentrancyGuardBase { */ modifier onlyRole(bytes32 _role) { DiamondLib.DiamondStorage storage ds = DiamondLib.diamondStorage(); - require(ds.accessController.hasRole(_role, msgSender()), ACCESS_DENIED); + if (!ds.accessController.hasRole(_role, msgSender())) revert AccessDenied(); _; } @@ -497,10 +498,10 @@ abstract contract ProtocolBase is PausableBase, ReentrancyGuardBase { (exists, offer) = fetchOffer(_offerId); // Offer must already exist - require(exists, NO_SUCH_OFFER); + if (!exists) revert NoSuchOffer(); // Offer must not already be voided - require(!offer.voided, OFFER_HAS_BEEN_VOIDED); + if (offer.voided) revert OfferHasBeenVoided(); } /** @@ -522,7 +523,7 @@ abstract contract ProtocolBase is PausableBase, ReentrancyGuardBase { (, Seller storage seller, ) = fetchSeller(offer.sellerId); // Caller must be seller's assistant address - require(seller.assistant == msgSender(), NOT_ASSISTANT); + if (seller.assistant != msgSender()) revert NotAssistant(); } /** @@ -585,7 +586,7 @@ abstract contract ProtocolBase is PausableBase, ReentrancyGuardBase { (, uint256 buyerId) = getBuyerIdByWallet(msgSender()); // Must be the buyer associated with the exchange (which is always voucher holder) - require(buyerId == _currentBuyer, NOT_VOUCHER_HOLDER); + if (buyerId != _currentBuyer) revert NotVoucherHolder(); } /** @@ -609,9 +610,10 @@ abstract contract ProtocolBase is PausableBase, ReentrancyGuardBase { (exchangeExists, exchange) = fetchExchange(_exchangeId); // Make sure the exchange exists - require(exchangeExists, NO_SUCH_EXCHANGE); + if (!exchangeExists) revert NoSuchExchange(); + // Make sure the exchange is in expected state - require(exchange.state == _expectedState, INVALID_STATE); + if (exchange.state != _expectedState) revert InvalidState(); // Get the voucher voucher = fetchVoucher(_exchangeId); diff --git a/contracts/protocol/bases/ReentrancyGuardBase.sol b/contracts/protocol/bases/ReentrancyGuardBase.sol index 64fb4ae6b..17fdfe957 100644 --- a/contracts/protocol/bases/ReentrancyGuardBase.sol +++ b/contracts/protocol/bases/ReentrancyGuardBase.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - import "../../domain/BosonConstants.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { ProtocolLib } from "../libs/ProtocolLib.sol"; pragma solidity 0.8.21; @@ -36,7 +36,7 @@ abstract contract ReentrancyGuardBase { modifier nonReentrant() { ProtocolLib.ProtocolStatus storage ps = ProtocolLib.protocolStatus(); // On the first call to nonReentrant, ps.reentrancyStatus will be NOT_ENTERED - require(ps.reentrancyStatus != ENTERED, REENTRANCY_GUARD); + if (ps.reentrancyStatus == ENTERED) revert BosonErrors.ReentrancyGuard(); // Any calls to nonReentrant after this point will fail ps.reentrancyStatus = ENTERED; diff --git a/contracts/protocol/bases/SellerBase.sol b/contracts/protocol/bases/SellerBase.sol index 5243d8b1a..2369d0937 100644 --- a/contracts/protocol/bases/SellerBase.sol +++ b/contracts/protocol/bases/SellerBase.sol @@ -45,17 +45,16 @@ contract SellerBase is ProtocolBase, IBosonAccountEvents { VoucherInitValues calldata _voucherInitValues ) internal { // Check active is not set to false - require(_seller.active, MUST_BE_ACTIVE); + if (!_seller.active) revert MustBeActive(); // Check for zero address - require(_seller.assistant != address(0) && _seller.treasury != address(0), INVALID_ADDRESS); + if (_seller.assistant == address(0) || _seller.treasury == address(0)) revert InvalidAddress(); // Admin address or AuthToken data must be present. A seller can have one or the other - require( - (_seller.admin == address(0) && _authToken.tokenType != AuthTokenType.None) || - (_seller.admin != address(0) && _authToken.tokenType == AuthTokenType.None), - ADMIN_OR_AUTH_TOKEN - ); + if ( + (_seller.admin == address(0) && _authToken.tokenType == AuthTokenType.None) || + (_seller.admin != address(0) && _authToken.tokenType != AuthTokenType.None) + ) revert AdminOrAuthToken(); // Cache protocol lookups for reference ProtocolLib.ProtocolLookups storage lookups = protocolLookups(); @@ -64,33 +63,29 @@ contract SellerBase is ProtocolBase, IBosonAccountEvents { address sender = msgSender(); // Check that caller is the supplied assistant - require(_seller.assistant == sender, NOT_ASSISTANT); - require(_seller.clerk == address(0), CLERK_DEPRECATED); + if (_seller.assistant != sender) revert NotAssistant(); + if (_seller.clerk != address(0)) revert ClerkDeprecated(); // Do caller and uniqueness checks based on auth type if (_authToken.tokenType != AuthTokenType.None) { - require(_authToken.tokenType != AuthTokenType.Custom, INVALID_AUTH_TOKEN_TYPE); + if (_authToken.tokenType == AuthTokenType.Custom) revert InvalidAuthTokenType(); // Check that caller owns the auth token address authTokenContract = lookups.authTokenContracts[_authToken.tokenType]; address tokenIdOwner = IERC721(authTokenContract).ownerOf(_authToken.tokenId); - require(tokenIdOwner == sender, NOT_ADMIN); + if (tokenIdOwner != sender) revert NotAdmin(); // Check that auth token is unique to this seller - require( - lookups.sellerIdByAuthToken[_authToken.tokenType][_authToken.tokenId] == 0, - AUTH_TOKEN_MUST_BE_UNIQUE - ); + if (lookups.sellerIdByAuthToken[_authToken.tokenType][_authToken.tokenId] != 0) + revert AuthTokenMustBeUnique(); } else { // Check that caller is supplied admin - require(_seller.admin == sender, NOT_ADMIN); + if (_seller.admin != sender) revert NotAdmin(); } // Check that the sender address is unique to one seller id, across all roles - require( - lookups.sellerIdByAdmin[sender] == 0 && lookups.sellerIdByAssistant[sender] == 0, - SELLER_ADDRESS_MUST_BE_UNIQUE - ); + if (lookups.sellerIdByAdmin[sender] != 0 || lookups.sellerIdByAssistant[sender] != 0) + revert SellerAddressMustBeUnique(); // Get the next account id and increment the counter uint256 sellerId = protocolCounters().nextAccountId++; @@ -99,7 +94,7 @@ contract SellerBase is ProtocolBase, IBosonAccountEvents { // Calculate seller salt and check that it is unique bytes32 sellerSalt = keccak256(abi.encodePacked(sender, _voucherInitValues.collectionSalt)); - require(!lookups.isUsedSellerSalt[sellerSalt], SELLER_SALT_NOT_UNIQUE); + if (lookups.isUsedSellerSalt[sellerSalt]) revert SellerSaltNotUnique(); lookups.sellerSalt[sellerId] = sellerSalt; lookups.isUsedSellerSalt[sellerSalt] = true; @@ -187,7 +182,7 @@ contract SellerBase is ProtocolBase, IBosonAccountEvents { cloneAddress := create2(0, clone, 0x37, collectionSalt) } - require(cloneAddress != address(0), CLONE_CREATION_FAILED); + if (cloneAddress == address(0)) revert CloneCreationFailed(); // Initialize the clone IInitializableVoucherClone(cloneAddress).initialize(pa.voucherBeacon); diff --git a/contracts/protocol/bases/TwinBase.sol b/contracts/protocol/bases/TwinBase.sol index 3f803ef06..f2a6851e2 100644 --- a/contracts/protocol/bases/TwinBase.sol +++ b/contracts/protocol/bases/TwinBase.sol @@ -42,13 +42,13 @@ contract TwinBase is ProtocolBase, IBosonTwinEvents { // get seller id, make sure it exists and store it to incoming struct (bool exists, uint256 sellerId) = getSellerIdByAssistant(sender); - require(exists, NOT_ASSISTANT); + if (!exists) revert NotAssistant(); // Protocol must be approved to transfer seller’s tokens - require(isProtocolApproved(_twin.tokenAddress, sender, address(this)), NO_TRANSFER_APPROVED); + if (!isProtocolApproved(_twin.tokenAddress, sender, address(this))) revert NoTransferApproved(); // Twin supply must exist and can't be zero - require(_twin.supplyAvailable > 0, INVALID_SUPPLY_AVAILABLE); + if (_twin.supplyAvailable == 0) revert InvalidSupplyAvailable(); // Get the next twinId and increment the counter uint256 twinId = protocolCounters().nextTwinId++; @@ -56,19 +56,19 @@ contract TwinBase is ProtocolBase, IBosonTwinEvents { if (_twin.tokenType == TokenType.NonFungibleToken) { // Check if the token supports IERC721 interface - require(contractSupportsInterface(_twin.tokenAddress, type(IERC721).interfaceId), INVALID_TOKEN_ADDRESS); + if (!contractSupportsInterface(_twin.tokenAddress, type(IERC721).interfaceId)) revert InvalidTokenAddress(); // If token is NonFungible amount should be zero - require(_twin.amount == 0, INVALID_TWIN_PROPERTY); + if (_twin.amount != 0) revert InvalidTwinProperty(); // Calculate new twin range [tokenId...lastTokenId] uint256 lastTokenId; uint256 tokenId = _twin.tokenId; if (_twin.supplyAvailable == type(uint256).max) { - require(tokenId <= (1 << 255), INVALID_TWIN_TOKEN_RANGE); // if supply is "unlimited", starting index can be at most 2*255 + if (tokenId > (1 << 255)) revert InvalidTwinTokenRange(); // if supply is "unlimited", starting index can be at most 2*255 lastTokenId = type(uint256).max; } else { - require(type(uint256).max - _twin.supplyAvailable >= tokenId, INVALID_TWIN_TOKEN_RANGE); + if (type(uint256).max - _twin.supplyAvailable < tokenId) revert InvalidTwinTokenRange(); lastTokenId = tokenId + _twin.supplyAvailable - 1; } @@ -81,7 +81,7 @@ contract TwinBase is ProtocolBase, IBosonTwinEvents { // A valid range has: // - the first id of range greater than the last token id (tokenId + initialSupply - 1) of the looped twin or // - the last id of range lower than the looped twin tokenId (beginning of range) - require(tokenId > twinRanges[i].end || lastTokenId < twinRanges[i].start, INVALID_TWIN_TOKEN_RANGE); + if (lastTokenId >= twinRanges[i].start && tokenId <= twinRanges[i].end) revert InvalidTwinTokenRange(); unchecked { i++; @@ -98,15 +98,16 @@ contract TwinBase is ProtocolBase, IBosonTwinEvents { } else if (_twin.tokenType == TokenType.MultiToken) { // If token is Fungible or MultiToken amount should not be zero // Also, the amount of tokens should not be more than the available token supply. - require(_twin.amount > 0 && _twin.amount <= _twin.supplyAvailable, INVALID_AMOUNT); + if (_twin.amount == 0 || _twin.amount > _twin.supplyAvailable) revert InvalidAmount(); // Not every ERC20 has supportsInterface method so we can't check interface support if token type is NonFungible // Check if the token supports IERC1155 interface - require(contractSupportsInterface(_twin.tokenAddress, type(IERC1155).interfaceId), INVALID_TOKEN_ADDRESS); + if (!contractSupportsInterface(_twin.tokenAddress, type(IERC1155).interfaceId)) + revert InvalidTokenAddress(); } else { // If token is Fungible or MultiToken amount should not be zero // Also, the amount of tokens should not be more than the available token supply. - require(_twin.amount > 0 && _twin.amount <= _twin.supplyAvailable, INVALID_AMOUNT); + if (_twin.amount == 0 || _twin.amount > _twin.supplyAvailable) revert InvalidAmount(); } // Get storage location for twin @@ -153,7 +154,7 @@ contract TwinBase is ProtocolBase, IBosonTwinEvents { address _assistant, address _protocol ) internal view returns (bool _approved) { - require(_tokenAddress != address(0), UNSUPPORTED_TOKEN); + if (_tokenAddress == address(0)) revert UnsupportedToken(); try ITwinToken(_tokenAddress).allowance(_assistant, _protocol) returns (uint256 _allowance) { if (_allowance > 0) { @@ -163,7 +164,7 @@ contract TwinBase is ProtocolBase, IBosonTwinEvents { try ITwinToken(_tokenAddress).isApprovedForAll(_assistant, _protocol) returns (bool _isApproved) { _approved = _isApproved; } catch { - revert(UNSUPPORTED_TOKEN); + revert UnsupportedToken(); } } } diff --git a/contracts/protocol/clients/voucher/BosonVoucher.sol b/contracts/protocol/clients/voucher/BosonVoucher.sol index a4ff269ef..0f8feb880 100644 --- a/contracts/protocol/clients/voucher/BosonVoucher.sol +++ b/contracts/protocol/clients/voucher/BosonVoucher.sol @@ -117,7 +117,7 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable // Revert if exchange id falls within a reserved range uint256 rangeStart = range.start; - require(_tokenId < rangeStart || _tokenId >= rangeStart + range.length, EXCHANGE_ID_IN_RESERVED_RANGE); + if (_tokenId >= rangeStart && _tokenId < rangeStart + range.length) revert ExchangeIdInReservedRange(); // Issue voucher is called only during commitToOffer (in protocol), so token can be set as committed _committed[_tokenId] = true; @@ -158,23 +158,23 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable */ function reserveRange(uint256 _offerId, uint256 _start, uint256 _length, address _to) external onlyRole(PROTOCOL) { // _to must be the contract address or the contract owner (operator) - require(_to == address(this) || _to == owner(), INVALID_TO_ADDRESS); + if (_to != address(this) && _to != owner()) revert InvalidToAddress(); // Prevent reservation of an empty range - require(_length > 0, INVALID_RANGE_LENGTH); + if (_length == 0) revert InvalidRangeLength(); // Adjust start id to include offer id - require(_start > 0, INVALID_RANGE_START); + if (_start == 0) revert InvalidRangeStart(); _start += (_offerId << 128); // Prevent overflow in issueVoucher and preMint - require(_start <= type(uint256).max - _length, INVALID_RANGE_LENGTH); + if (_start > type(uint256).max - _length) revert InvalidRangeLength(); // Get storage slot for the range Range storage range = _rangeByOfferId[_offerId]; // Revert if the offer id is already associated with a range - require(range.length == 0, OFFER_RANGE_ALREADY_RESERVED); + if (range.length != 0) revert OfferRangeAlreadyReserved(); // Store the reserved range range.start = _start; @@ -220,14 +220,14 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable Range storage range = _rangeByOfferId[_offerId]; // Revert if id not associated with a range - require(range.length != 0, NO_RESERVED_RANGE_FOR_OFFER); + if (range.length == 0) revert NoReservedRangeForOffer(); // Revert if no more to mint in range - require(range.length >= range.minted + _amount, INVALID_AMOUNT_TO_MINT); + if (range.length < range.minted + _amount) revert InvalidAmountToMint(); // Make sure that offer is not expired or voided (Offer memory offer, OfferDates memory offerDates) = getBosonOffer(_offerId); - require(!offer.voided && block.timestamp <= offerDates.validUntil, OFFER_EXPIRED_OR_VOIDED); + if (offer.voided || block.timestamp > offerDates.validUntil) revert OfferExpiredOrVoided(); // Get the first token to mint uint256 start = range.start + range.minted; @@ -283,11 +283,11 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable Range storage range = _rangeByOfferId[_offerId]; // Revert if id not associated with a range - require(range.length != 0, NO_RESERVED_RANGE_FOR_OFFER); + if (range.length == 0) revert NoReservedRangeForOffer(); // Make sure that offer is either expired or voided (Offer memory offer, OfferDates memory offerDates) = getBosonOffer(_offerId); - require(offer.voided || block.timestamp > offerDates.validUntil, OFFER_STILL_VALID); + if (!offer.voided && block.timestamp <= offerDates.validUntil) revert OfferStillValid(); // Get the first token to burn uint256 start = range.lastBurnedTokenId == 0 ? range.start : range.lastBurnedTokenId + 1; @@ -296,7 +296,7 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable uint256 end = start + _amount; // End should be greater than start - require(end > start && end <= range.start + range.minted, AMOUNT_EXCEEDS_RANGE_OR_NOTHING_TO_BURN); + if (end <= start || end > range.start + range.minted) revert AmountExceedsRangeOrNothingToBurn(); // Burn the range address rangeOwner = range.owner; @@ -517,7 +517,7 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable * N.B. In the future it might be possible to renounce ownership via seller deactivation in the protocol. */ function renounceOwnership() public pure override { - revert(ACCESS_DENIED); + revert AccessDenied(); } /** @@ -553,12 +553,12 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable * @return result - result of the call */ function callExternalContract(address _to, bytes calldata _data) external payable onlyOwner returns (bytes memory) { - require(_to != address(0), INVALID_ADDRESS); + if (_to == address(0)) revert InvalidAddress(); // Check if _to supports `balanceOf` method and revert if it does // This works with all contracts that implement this method even if they don't necessary implement ERC20 interface try IERC20(_to).balanceOf(address(this)) returns (uint256) { - revert(INTERACTION_NOT_ALLOWED); + revert InteractionNotAllowed(); } catch {} return _to.functionCallWithValue(_data, msg.value, FUNCTION_CALL_NOT_SUCCESSFUL); @@ -575,7 +575,7 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable * @param _approved - true to approve the operator in question, false to revoke approval */ function setApprovalForAllToContract(address _operator, bool _approved) external onlyOwner { - require(_operator != address(0), INVALID_ADDRESS); + if (_operator == address(0)) revert InvalidAddress(); _setApprovalForAll(address(this), _operator, _approved); } @@ -670,7 +670,7 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable uint16 maxRoyaltyPecentage = IBosonConfigHandler(protocolDiamond).getMaxRoyaltyPecentage(); // make sure that new royalty percentage does not exceed the max value set in the protocol - require(_newRoyaltyPercentage <= maxRoyaltyPecentage, ROYALTY_FEE_INVALID); + if (_newRoyaltyPercentage > maxRoyaltyPecentage) revert InvalidRoyaltyFee(); _royaltyPercentage = _newRoyaltyPercentage; @@ -819,7 +819,7 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable * Updates owners, but do not emit Transfer event. Event was already emited during pre-mint. */ function silentMint(address _from, uint256 _tokenId) internal { - require(_from == owner() || _from == address(this), NO_SILENT_MINT_ALLOWED); + if (_from != owner() && _from != address(this)) revert NoSilentMintAllowed(); // update data, so transfer will succeed getERC721UpgradeableStorage()._owners[_tokenId] = _from; diff --git a/contracts/protocol/facets/AgentHandlerFacet.sol b/contracts/protocol/facets/AgentHandlerFacet.sol index cf4372225..813db904d 100644 --- a/contracts/protocol/facets/AgentHandlerFacet.sol +++ b/contracts/protocol/facets/AgentHandlerFacet.sol @@ -37,16 +37,16 @@ contract AgentHandlerFacet is IBosonAccountEvents, ProtocolBase { */ function createAgent(Agent memory _agent) external agentsNotPaused nonReentrant { //Check for zero address - require(_agent.wallet != address(0), INVALID_ADDRESS); + if (_agent.wallet == address(0)) revert InvalidAddress(); //Check active is not set to false - require(_agent.active, MUST_BE_ACTIVE); + if (!_agent.active) revert MustBeActive(); // Get the next account id and increment the counter uint256 agentId = protocolCounters().nextAccountId++; //check that the wallet address is unique to one agent id - require(protocolLookups().agentIdByWallet[_agent.wallet] == 0, AGENT_ADDRESS_MUST_BE_UNIQUE); + if (protocolLookups().agentIdByWallet[_agent.wallet] != 0) revert AgentAddressMustBeUnique(); _agent.id = agentId; storeAgent(_agent); @@ -77,7 +77,7 @@ contract AgentHandlerFacet is IBosonAccountEvents, ProtocolBase { ProtocolLib.ProtocolLookups storage lookups = protocolLookups(); // Check for zero address - require(_agent.wallet != address(0), INVALID_ADDRESS); + if (_agent.wallet == address(0)) revert InvalidAddress(); bool exists; Agent storage agent; @@ -86,18 +86,18 @@ contract AgentHandlerFacet is IBosonAccountEvents, ProtocolBase { (exists, agent) = fetchAgent(_agent.id); // Agent must already exist - require(exists, NO_SUCH_AGENT); + if (!exists) revert NoSuchAgent(); // Get message sender address sender = msgSender(); // Check that msg.sender is the wallet address for this agent - require(agent.wallet == sender, NOT_AGENT_WALLET); + if (agent.wallet != sender) revert NotAgentWallet(); // Check that the wallet address is not associated with another agent or is already associated with the agent passed in mapping(address => uint256) storage agentIds = lookups.agentIdByWallet; - uint256 check1 = agentIds[_agent.wallet]; - require(check1 == 0 || check1 == _agent.id, AGENT_ADDRESS_MUST_BE_UNIQUE); + uint256 agentId = agentIds[_agent.wallet]; + if (agentId != 0 && agentId != _agent.id) revert AgentAddressMustBeUnique(); // Delete current mappings delete agentIds[sender]; @@ -129,10 +129,8 @@ contract AgentHandlerFacet is IBosonAccountEvents, ProtocolBase { function storeAgent(Agent memory _agent) internal { // Make sure agent fee percentage + protocol fee percentage is less than or equal the max. // This will lessen the likelihood that creation of offers using this agent will fail - require( - (_agent.feePercentage + protocolFees().percentage) <= protocolLimits().maxTotalOfferFeePercentage, - INVALID_AGENT_FEE_PERCENTAGE - ); + if ((_agent.feePercentage + protocolFees().percentage) > protocolLimits().maxTotalOfferFeePercentage) + revert InvalidAgentFeePercentage(); // Get storage location for agent (, Agent storage agent) = fetchAgent(_agent.id); diff --git a/contracts/protocol/facets/BuyerHandlerFacet.sol b/contracts/protocol/facets/BuyerHandlerFacet.sol index c6d08d68f..592c08936 100644 --- a/contracts/protocol/facets/BuyerHandlerFacet.sol +++ b/contracts/protocol/facets/BuyerHandlerFacet.sol @@ -59,7 +59,7 @@ contract BuyerHandlerFacet is BuyerBase { ProtocolLib.ProtocolLookups storage lookups = protocolLookups(); // Check for zero address - require(_buyer.wallet != address(0), INVALID_ADDRESS); + if (_buyer.wallet == address(0)) revert InvalidAddress(); bool exists; Buyer storage buyer; @@ -68,23 +68,23 @@ contract BuyerHandlerFacet is BuyerBase { (exists, buyer) = fetchBuyer(_buyer.id); // Buyer must already exist - require(exists, NO_SUCH_BUYER); + if (!exists) revert NoSuchBuyer(); // Get message sender address sender = msgSender(); // Check that msg.sender is the wallet address for this buyer - require(buyer.wallet == sender, NOT_BUYER_WALLET); + if (buyer.wallet != sender) revert NotBuyerWallet(); // Check that current wallet address does not own any vouchers, if changing wallet address if (buyer.wallet != _buyer.wallet) { - require(lookups.voucherCount[_buyer.id] == 0, WALLET_OWNS_VOUCHERS); + if (lookups.voucherCount[_buyer.id] != 0) revert WalletOwnsVouchers(); } // Check that the wallet address is unique to one buyer id if new mapping(address => uint256) storage buyerIds = lookups.buyerIdByWallet; - uint256 check1 = buyerIds[_buyer.wallet]; - require(check1 == 0 || check1 == _buyer.id, BUYER_ADDRESS_MUST_BE_UNIQUE); + uint256 buyerId = buyerIds[_buyer.wallet]; + if (buyerId != 0 && buyerId != _buyer.id) revert BuyerAddressMustBeUnique(); // Delete current mappings delete buyerIds[sender]; diff --git a/contracts/protocol/facets/ConfigHandlerFacet.sol b/contracts/protocol/facets/ConfigHandlerFacet.sol index bcafa6ebf..8b9c45f00 100644 --- a/contracts/protocol/facets/ConfigHandlerFacet.sol +++ b/contracts/protocol/facets/ConfigHandlerFacet.sol @@ -81,7 +81,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { * @param _tokenAddress - the Boson Token (ERC-20 contract) address */ function setTokenAddress(address payable _tokenAddress) public override onlyRole(ADMIN) nonReentrant { - require(_tokenAddress != address(0), INVALID_ADDRESS); + checkNonZeroAddress(_tokenAddress); protocolAddresses().token = _tokenAddress; emit TokenAddressChanged(_tokenAddress, msgSender()); } @@ -107,7 +107,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { * @param _treasuryAddress - the the multi-sig wallet address */ function setTreasuryAddress(address payable _treasuryAddress) public override onlyRole(ADMIN) nonReentrant { - require(_treasuryAddress != address(0), INVALID_ADDRESS); + checkNonZeroAddress(_treasuryAddress); protocolAddresses().treasury = _treasuryAddress; emit TreasuryAddressChanged(_treasuryAddress, msgSender()); } @@ -133,7 +133,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { * @param _voucherBeaconAddress - the Boson Voucher beacon contract address */ function setVoucherBeaconAddress(address _voucherBeaconAddress) public override onlyRole(ADMIN) nonReentrant { - require(_voucherBeaconAddress != address(0), INVALID_ADDRESS); + checkNonZeroAddress(_voucherBeaconAddress); protocolAddresses().voucherBeacon = _voucherBeaconAddress; emit VoucherBeaconAddressChanged(_voucherBeaconAddress, msgSender()); } @@ -159,7 +159,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { * @param _beaconProxyAddress - reference proxy implementation address */ function setBeaconProxyAddress(address _beaconProxyAddress) public override onlyRole(ADMIN) nonReentrant { - require(_beaconProxyAddress != address(0), INVALID_ADDRESS); + checkNonZeroAddress(_beaconProxyAddress); protocolAddresses().beaconProxy = _beaconProxyAddress; emit BeaconProxyAddressChanged(_beaconProxyAddress, msgSender()); } @@ -189,7 +189,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { */ function setProtocolFeePercentage(uint256 _protocolFeePercentage) public override onlyRole(ADMIN) nonReentrant { // Make sure percentage is less than 10000 - require(_protocolFeePercentage <= 10000, FEE_PERCENTAGE_INVALID); + checkMaxPercententage(_protocolFeePercentage); // Store fee percentage protocolFees().percentage = _protocolFeePercentage; @@ -249,7 +249,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { uint256 _maxEscalationResponsePeriod ) public override onlyRole(ADMIN) nonReentrant { // Make sure _maxEscalationResponsePeriod is greater than 0 - checkNonZero(_maxEscalationResponsePeriod); + checkNonZeroValue(_maxEscalationResponsePeriod); protocolLimits().maxEscalationResponsePeriod = _maxEscalationResponsePeriod; emit MaxEscalationResponsePeriodChanged(_maxEscalationResponsePeriod, msgSender()); @@ -282,7 +282,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { uint16 _maxTotalOfferFeePercentage ) public override onlyRole(ADMIN) nonReentrant { // Make sure percentage is less than 10000 - require(_maxTotalOfferFeePercentage <= 10000, FEE_PERCENTAGE_INVALID); + checkMaxPercententage(_maxTotalOfferFeePercentage); // Store fee percentage protocolLimits().maxTotalOfferFeePercentage = _maxTotalOfferFeePercentage; @@ -318,10 +318,10 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { */ function setMaxRoyaltyPecentage(uint16 _maxRoyaltyPecentage) public override onlyRole(ADMIN) nonReentrant { // Make sure percentage is greater than 0 - checkNonZero(_maxRoyaltyPecentage); + checkNonZeroValue(_maxRoyaltyPecentage); // Make sure percentage is less than 10000 - require(_maxRoyaltyPecentage <= 10000, FEE_PERCENTAGE_INVALID); + checkMaxPercententage(_maxRoyaltyPecentage); // Store fee percentage protocolLimits().maxRoyaltyPecentage = _maxRoyaltyPecentage; @@ -357,7 +357,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { uint256 _buyerEscalationDepositPercentage ) public override onlyRole(ADMIN) nonReentrant { // Make sure percentage is less than 10000 - require(_buyerEscalationDepositPercentage <= 10000, FEE_PERCENTAGE_INVALID); + checkMaxPercententage(_buyerEscalationDepositPercentage); // Store fee percentage protocolFees().buyerEscalationDepositPercentage = _buyerEscalationDepositPercentage; @@ -394,11 +394,9 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { AuthTokenType _authTokenType, address _authTokenContract ) external override onlyRole(ADMIN) nonReentrant { - require( - _authTokenType != AuthTokenType.None && _authTokenType != AuthTokenType.Custom, - INVALID_AUTH_TOKEN_TYPE - ); - require(_authTokenContract != address(0), INVALID_ADDRESS); + if (_authTokenType == AuthTokenType.None || _authTokenType == AuthTokenType.Custom) + revert InvalidAuthTokenType(); + checkNonZeroAddress(_authTokenContract); protocolLookups().authTokenContracts[_authTokenType] = _authTokenContract; emit AuthTokenContractChanged(_authTokenType, _authTokenContract, msgSender()); } @@ -426,13 +424,13 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { */ function setMinResolutionPeriod(uint256 _minResolutionPeriod) public override onlyRole(ADMIN) nonReentrant { // Make sure _maxResolutionPeriod is greater than 0 - checkNonZero(_minResolutionPeriod); + checkNonZeroValue(_minResolutionPeriod); // cache protocol limits ProtocolLib.ProtocolLimits storage limits = protocolLimits(); // Make sure _minResolutionPeriod is less than _maxResolutionPeriod - require(_minResolutionPeriod <= limits.maxResolutionPeriod, INVALID_RESOLUTION_PERIOD); + if (_minResolutionPeriod > limits.maxResolutionPeriod) revert InvalidResolutionPeriod(); limits.minResolutionPeriod = _minResolutionPeriod; emit MinResolutionPeriodChanged(_minResolutionPeriod, msgSender()); @@ -460,13 +458,13 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { */ function setMaxResolutionPeriod(uint256 _maxResolutionPeriod) public override onlyRole(ADMIN) nonReentrant { // Make sure _maxResolutionPeriod is greater than 0 - checkNonZero(_maxResolutionPeriod); + checkNonZeroValue(_maxResolutionPeriod); // cache protocol limits ProtocolLib.ProtocolLimits storage limits = protocolLimits(); // Make sure _maxResolutionPeriod is greater than _minResolutionPeriod - require(_maxResolutionPeriod >= limits.minResolutionPeriod, INVALID_RESOLUTION_PERIOD); + if (_maxResolutionPeriod < limits.minResolutionPeriod) revert InvalidResolutionPeriod(); limits.maxResolutionPeriod = _maxResolutionPeriod; emit MaxResolutionPeriodChanged(_maxResolutionPeriod, msgSender()); @@ -492,7 +490,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { */ function setMinDisputePeriod(uint256 _minDisputePeriod) public override onlyRole(ADMIN) nonReentrant { // Make sure _minDisputePeriod is greater than 0 - checkNonZero(_minDisputePeriod); + checkNonZeroValue(_minDisputePeriod); protocolLimits().minDisputePeriod = _minDisputePeriod; emit MinDisputePeriodChanged(_minDisputePeriod, msgSender()); @@ -519,7 +517,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { function setAccessControllerAddress( address _accessControllerAddress ) external override onlyRole(ADMIN) nonReentrant { - require(_accessControllerAddress != address(0), INVALID_ADDRESS); + checkNonZeroAddress(_accessControllerAddress); DiamondLib.diamondStorage().accessController = IAccessControl(_accessControllerAddress); emit AccessControllerAddressChanged(_accessControllerAddress, msgSender()); } @@ -533,7 +531,30 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { return address(DiamondLib.diamondStorage().accessController); } - function checkNonZero(uint256 _value) internal pure { - require(_value != 0, VALUE_ZERO_NOT_ALLOWED); + /** + * @notice Checks that supplied value is not 0. + * + * Reverts if the value is zero + */ + function checkNonZeroValue(uint256 _value) internal pure { + if (_value == 0) revert ValueZeroNotAllowed(); + } + + /** + * @notice Checks that supplied value is not address 0. + * + * Reverts if the value is address zero + */ + function checkNonZeroAddress(address _address) internal pure { + if (_address == address(0)) revert InvalidAddress(); + } + + /** + * @notice Checks that supplied value is less or equal to 10000 (100%). + * + * Reverts if the value more than 10000 + */ + function checkMaxPercententage(uint256 _percentage) internal pure { + if (_percentage > 10000) revert InvalidFeePercentage(); } } diff --git a/contracts/protocol/facets/DisputeHandlerFacet.sol b/contracts/protocol/facets/DisputeHandlerFacet.sol index 7247af871..06c5c238a 100644 --- a/contracts/protocol/facets/DisputeHandlerFacet.sol +++ b/contracts/protocol/facets/DisputeHandlerFacet.sol @@ -77,10 +77,10 @@ contract DisputeHandlerFacet is DisputeBase, IBosonDisputeHandler { // If dispute was escalated, make sure that escalation period is not over yet if (dispute.state == DisputeState.Escalated) { // make sure the dispute escalation period not expired already - require(block.timestamp <= disputeDates.timeout, DISPUTE_HAS_EXPIRED); + if (block.timestamp > disputeDates.timeout) revert DisputeHasExpired(); } else { // If dispute is not escalated, make sure the it is in the resolving state - require(dispute.state == DisputeState.Resolving, INVALID_STATE); + if (dispute.state != DisputeState.Resolving) revert InvalidState(); } // Finalize the dispute @@ -126,19 +126,19 @@ contract DisputeHandlerFacet is DisputeBase, IBosonDisputeHandler { address sender = msgSender(); // Caller must be seller's assistant address - require(seller.assistant == sender, NOT_ASSISTANT); + if (seller.assistant != sender) revert NotAssistant(); // Fetch the dispute, it exists if exchange is in Disputed state (, Dispute storage dispute, DisputeDates storage disputeDates) = fetchDispute(_exchangeId); // Dispute must be in a resolving state - require(dispute.state == DisputeState.Resolving, INVALID_STATE); + if (dispute.state != DisputeState.Resolving) revert InvalidState(); // If expired already, it cannot be extended - require(block.timestamp <= disputeDates.timeout, DISPUTE_HAS_EXPIRED); + if (block.timestamp > disputeDates.timeout) revert DisputeHasExpired(); // New dispute timeout should be after the current dispute timeout - require(_newDisputeTimeout > disputeDates.timeout, INVALID_DISPUTE_TIMEOUT); + if (_newDisputeTimeout <= disputeDates.timeout) revert InvalidDisputeTimeout(); // Update the timeout disputeDates.timeout = _newDisputeTimeout; @@ -169,10 +169,10 @@ contract DisputeHandlerFacet is DisputeBase, IBosonDisputeHandler { (, Dispute storage dispute, DisputeDates storage disputeDates) = fetchDispute(_exchangeId); // Make sure the dispute is in the resolving state - require(dispute.state == DisputeState.Resolving, INVALID_STATE); + if (dispute.state != DisputeState.Resolving) revert InvalidState(); // make sure the dispute not expired already - require(block.timestamp > disputeDates.timeout, DISPUTE_STILL_VALID); + if (block.timestamp <= disputeDates.timeout) revert DisputeStillValid(); // Finalize the dispute finalizeDispute(_exchangeId, exchange, dispute, disputeDates, DisputeState.Retracted, 0); @@ -238,7 +238,7 @@ contract DisputeHandlerFacet is DisputeBase, IBosonDisputeHandler { uint8 _sigV ) external override nonReentrant { // buyer should get at most 100% - require(_buyerPercent <= 10000, INVALID_BUYER_PERCENT); + if (_buyerPercent > 10000) revert InvalidBuyerPercent(); // Get the exchange, should be in disputed state (Exchange storage exchange, ) = getValidExchange(_exchangeId, ExchangeState.Disputed); @@ -247,10 +247,10 @@ contract DisputeHandlerFacet is DisputeBase, IBosonDisputeHandler { (, Dispute storage dispute, DisputeDates storage disputeDates) = fetchDispute(_exchangeId); // Make sure the dispute is in the resolving or escalated state - require(dispute.state == DisputeState.Resolving || dispute.state == DisputeState.Escalated, INVALID_STATE); + if (dispute.state != DisputeState.Resolving && dispute.state != DisputeState.Escalated) revert InvalidState(); // Make sure the dispute not expired already - require(block.timestamp <= disputeDates.timeout, DISPUTE_HAS_EXPIRED); + if (block.timestamp > disputeDates.timeout) revert DisputeHasExpired(); // wrap the code in a separate block to avoid stack too deep error { @@ -272,7 +272,7 @@ contract DisputeHandlerFacet is DisputeBase, IBosonDisputeHandler { } else { uint256 buyerId; (exists, buyerId) = getBuyerIdByWallet(msgSender()); - require(exists && buyerId == exchange.buyerId, NOT_BUYER_OR_SELLER); + if (!exists || buyerId != exchange.buyerId) revert NotBuyerOrSeller(); // caller is the buyer // get the seller's address, which should be the signer of the resolution @@ -281,10 +281,8 @@ contract DisputeHandlerFacet is DisputeBase, IBosonDisputeHandler { } // verify that the signature belongs to the expectedSigner - require( - EIP712Lib.verify(expectedSigner, hashResolution(_exchangeId, _buyerPercent), _sigR, _sigS, _sigV), - SIGNER_AND_SIGNATURE_DO_NOT_MATCH - ); + if (!EIP712Lib.verify(expectedSigner, hashResolution(_exchangeId, _buyerPercent), _sigR, _sigS, _sigV)) + revert SignerAndSignatureDoNotMatch(); } // finalize the dispute @@ -342,7 +340,7 @@ contract DisputeHandlerFacet is DisputeBase, IBosonDisputeHandler { */ function decideDispute(uint256 _exchangeId, uint256 _buyerPercent) external override nonReentrant { // Buyer should get at most 100% - require(_buyerPercent <= 10000, INVALID_BUYER_PERCENT); + if (_buyerPercent > 10000) revert InvalidBuyerPercent(); // Make sure the dispute is valid and the caller is the dispute resolver (Exchange storage exchange, Dispute storage dispute, DisputeDates storage disputeDates) = disputeResolverChecks( @@ -406,10 +404,10 @@ contract DisputeHandlerFacet is DisputeBase, IBosonDisputeHandler { (, Dispute storage dispute, DisputeDates storage disputeDates) = fetchDispute(_exchangeId); // Make sure the dispute is in the escalated state - require(dispute.state == DisputeState.Escalated, INVALID_STATE); + if (dispute.state != DisputeState.Escalated) revert InvalidState(); // make sure the dispute escalation has expired already - require(block.timestamp > disputeDates.timeout, DISPUTE_STILL_VALID); + if (block.timestamp <= disputeDates.timeout) revert DisputeStillValid(); // Finalize the dispute finalizeDispute(_exchangeId, exchange, dispute, disputeDates, DisputeState.Refused, 0); @@ -543,20 +541,18 @@ contract DisputeHandlerFacet is DisputeBase, IBosonDisputeHandler { (, dispute, disputeDates) = fetchDispute(_exchangeId); // Make sure the dispute is in the escalated state - require(dispute.state == DisputeState.Escalated, INVALID_STATE); + if (dispute.state != DisputeState.Escalated) revert InvalidState(); // Make sure the dispute escalation period not expired already - require(block.timestamp <= disputeDates.timeout, DISPUTE_HAS_EXPIRED); + if (block.timestamp > disputeDates.timeout) revert DisputeHasExpired(); // Fetch the offer to get the info who the seller is (, Offer storage offer) = fetchOffer(exchange.offerId); // get dispute resolver id to check if caller is the dispute resolver uint256 disputeResolverId = protocolLookups().disputeResolverIdByAssistant[msgSender()]; - require( - disputeResolverId == fetchDisputeResolutionTerms(offer.id).disputeResolverId, - NOT_DISPUTE_RESOLVER_ASSISTANT - ); + if (disputeResolverId != fetchDisputeResolutionTerms(offer.id).disputeResolverId) + revert NotDisputeResolverAssistant(); } /** diff --git a/contracts/protocol/facets/DisputeResolverHandlerFacet.sol b/contracts/protocol/facets/DisputeResolverHandlerFacet.sol index 2bac3ebef..30156c8ef 100644 --- a/contracts/protocol/facets/DisputeResolverHandlerFacet.sol +++ b/contracts/protocol/facets/DisputeResolverHandlerFacet.sol @@ -53,15 +53,14 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { ProtocolLib.ProtocolLookups storage lookups = protocolLookups(); // Check for zero address - require( - _disputeResolver.admin != address(0) && - _disputeResolver.assistant != address(0) && - _disputeResolver.treasury != address(0), - INVALID_ADDRESS - ); + if ( + _disputeResolver.admin == address(0) || + _disputeResolver.assistant == address(0) || + _disputeResolver.treasury == address(0) + ) revert InvalidAddress(); // Check active is not set to false - require(_disputeResolver.active, MUST_BE_ACTIVE); + if (!_disputeResolver.active) revert MustBeActive(); // Scope to avoid stack too deep errors { @@ -69,8 +68,8 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { address sender = msgSender(); // Check that caller is the supplied admin and assistant - require(_disputeResolver.admin == sender && _disputeResolver.assistant == sender, NOT_ADMIN_AND_ASSISTANT); - require(_disputeResolver.clerk == address(0), CLERK_DEPRECATED); + if (_disputeResolver.admin != sender || _disputeResolver.assistant != sender) revert NotAdminAndAssistant(); + if (_disputeResolver.clerk != address(0)) revert ClerkDeprecated(); } // Get the next account id and increment the counter @@ -79,13 +78,14 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { // Check that the addresses are unique to one dispute resolver id, across all rolls mapping(address => uint256) storage disputeResolverIdByAssistant = lookups.disputeResolverIdByAssistant; mapping(address => uint256) storage disputeResolverIdByAdmin = lookups.disputeResolverIdByAdmin; - require( - disputeResolverIdByAssistant[_disputeResolver.assistant] == 0 && - disputeResolverIdByAssistant[_disputeResolver.admin] == 0 && - disputeResolverIdByAdmin[_disputeResolver.admin] == 0 && - disputeResolverIdByAdmin[_disputeResolver.assistant] == 0, - DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE - ); + if ( + disputeResolverIdByAssistant[_disputeResolver.assistant] != 0 || + disputeResolverIdByAssistant[_disputeResolver.admin] != 0 || + disputeResolverIdByAdmin[_disputeResolver.admin] != 0 || + disputeResolverIdByAdmin[_disputeResolver.assistant] != 0 + ) { + revert DisputeResolverAddressMustBeUnique(); + } // Scope to avoid stack too deep errors { @@ -93,11 +93,10 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { ProtocolLib.ProtocolLimits storage limits = protocolLimits(); // Escalation period must be greater than zero and less than or equal to the max allowed - require( - _disputeResolver.escalationResponsePeriod > 0 && - _disputeResolver.escalationResponsePeriod <= limits.maxEscalationResponsePeriod, - INVALID_ESCALATION_PERIOD - ); + if ( + _disputeResolver.escalationResponsePeriod == 0 || + _disputeResolver.escalationResponsePeriod > limits.maxEscalationResponsePeriod + ) revert InvalidEscalationPeriod(); } _disputeResolver.id = disputeResolverId; @@ -111,13 +110,11 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { ]; for (uint256 i = 0; i < _disputeResolverFees.length; ) { - require( - disputeResolverFeeTokens[_disputeResolverFees[i].tokenAddress] == 0, - DUPLICATE_DISPUTE_RESOLVER_FEES - ); + if (disputeResolverFeeTokens[_disputeResolverFees[i].tokenAddress] != 0) + revert DuplicateDisputeResolverFees(); // Protocol doesn't yet support DR fees - require(_disputeResolverFees[i].feeAmount == 0, FEE_AMOUNT_NOT_YET_SUPPORTED); + if (_disputeResolverFees[i].feeAmount != 0) revert FeeAmountNotYetSupported(); disputeResolverFees.push(_disputeResolverFees[i]); @@ -176,13 +173,14 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { ProtocolLib.ProtocolLookups storage lookups = protocolLookups(); // Check for zero address - require( - _disputeResolver.admin != address(0) && - _disputeResolver.assistant != address(0) && - _disputeResolver.treasury != address(0), - INVALID_ADDRESS - ); - require(_disputeResolver.clerk == address(0), CLERK_DEPRECATED); + if ( + _disputeResolver.admin == address(0) || + _disputeResolver.assistant == address(0) || + _disputeResolver.treasury == address(0) + ) { + revert InvalidAddress(); + } + if (_disputeResolver.clerk != address(0)) revert ClerkDeprecated(); bool exists; DisputeResolver storage disputeResolver; @@ -191,13 +189,13 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { (exists, disputeResolver, ) = fetchDisputeResolver(_disputeResolver.id); // Dispute resolver must already exist - require(exists, NO_SUCH_DISPUTE_RESOLVER); + if (!exists) revert NoSuchDisputeResolver(); // Get message sender address sender = msgSender(); // Check that caller is the admin address for this dispute resolver - require(disputeResolver.admin == sender, NOT_ADMIN); + if (disputeResolver.admin != sender) revert NotAdmin(); // Clean old dispute resolver pending update data if exists delete lookups.pendingAddressUpdatesByDisputeResolver[_disputeResolver.id]; @@ -234,11 +232,12 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { if (_disputeResolver.escalationResponsePeriod != disputeResolver.escalationResponsePeriod) { // Escalation period must be greater than zero and less than or equal to the max allowed - require( - _disputeResolver.escalationResponsePeriod > 0 && - _disputeResolver.escalationResponsePeriod <= protocolLimits().maxEscalationResponsePeriod, - INVALID_ESCALATION_PERIOD - ); + if ( + _disputeResolver.escalationResponsePeriod == 0 || + _disputeResolver.escalationResponsePeriod > protocolLimits().maxEscalationResponsePeriod + ) { + revert InvalidEscalationPeriod(); + } // Update escalation response period disputeResolver.escalationResponsePeriod = _disputeResolver.escalationResponsePeriod; @@ -268,7 +267,7 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { ); } - require(updateApplied || needsApproval, NO_UPDATE_APPLIED); + if (!updateApplied && !needsApproval) revert NoUpdateApplied(); } /** @@ -299,7 +298,7 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { _disputeResolverId ); - require(exists, NO_PENDING_UPDATE_FOR_ACCOUNT); + if (!exists) revert NoPendingUpdateForAccount(); bool updateApplied; @@ -311,7 +310,7 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { if (role == DisputeResolverUpdateFields.Admin && disputeResolverPendingUpdate.admin != address(0)) { // Approve admin update - require(disputeResolverPendingUpdate.admin == sender, UNAUTHORIZED_CALLER_UPDATE); + if (disputeResolverPendingUpdate.admin != sender) revert UnauthorizedCallerUpdate(); preUpdateDisputeResolverCheck(_disputeResolverId, sender, lookups); @@ -332,7 +331,7 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { role == DisputeResolverUpdateFields.Assistant && disputeResolverPendingUpdate.assistant != address(0) ) { // Approve assistant update - require(disputeResolverPendingUpdate.assistant == sender, UNAUTHORIZED_CALLER_UPDATE); + if (disputeResolverPendingUpdate.assistant != sender) revert UnauthorizedCallerUpdate(); preUpdateDisputeResolverCheck(_disputeResolverId, sender, lookups); @@ -350,7 +349,7 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { updateApplied = true; } else if (role == DisputeResolverUpdateFields.Clerk) { - revert(CLERK_DEPRECATED); + revert ClerkDeprecated(); } unchecked { @@ -401,25 +400,24 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { (exists, disputeResolver, disputeResolverFees) = fetchDisputeResolver(_disputeResolverId); // Dispute resolver must already exist - require(exists, NO_SUCH_DISPUTE_RESOLVER); + if (!exists) revert NoSuchDisputeResolver(); // Get message sender address sender = msgSender(); // Check that msg.sender is the admin address for this dispute resolver - require(disputeResolver.admin == sender, NOT_ADMIN); + if (disputeResolver.admin != sender) revert NotAdmin(); // At least one fee must be specified - require(_disputeResolverFees.length > 0, INEXISTENT_DISPUTE_RESOLVER_FEES); + if (_disputeResolverFees.length == 0) revert InexistentDisputeResolverFees(); // Set dispute resolver fees. Must loop because calldata structs cannot be converted to storage structs for (uint256 i = 0; i < _disputeResolverFees.length; ) { - require( - lookups.disputeResolverFeeTokenIndex[_disputeResolverId][_disputeResolverFees[i].tokenAddress] == 0, - DUPLICATE_DISPUTE_RESOLVER_FEES - ); + if (lookups.disputeResolverFeeTokenIndex[_disputeResolverId][_disputeResolverFees[i].tokenAddress] != 0) + revert DuplicateDisputeResolverFees(); + // Protocol doesn't yet support DR fees - require(_disputeResolverFees[i].feeAmount == 0, FEE_AMOUNT_NOT_YET_SUPPORTED); + if (_disputeResolverFees[i].feeAmount != 0) revert FeeAmountNotYetSupported(); disputeResolverFees.push(_disputeResolverFees[i]); lookups.disputeResolverFeeTokenIndex[_disputeResolverId][ @@ -464,23 +462,22 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { (exists, disputeResolver, disputeResolverFees) = fetchDisputeResolver(_disputeResolverId); // Dispute resolver must already exist - require(exists, NO_SUCH_DISPUTE_RESOLVER); + if (!exists) revert NoSuchDisputeResolver(); // Get message sender address sender = msgSender(); // Check that msg.sender is the admin address for this dispute resolver - require(disputeResolver.admin == sender, NOT_ADMIN); + if (disputeResolver.admin != sender) revert NotAdmin(); // At least one fee must be specified and - require(_feeTokenAddresses.length > 0, INEXISTENT_DISPUTE_RESOLVER_FEES); + if (_feeTokenAddresses.length == 0) revert InexistentDisputeResolverFees(); // Set dispute resolver fees. Must loop because calldata structs cannot be converted to storage structs for (uint256 i = 0; i < _feeTokenAddresses.length; ) { - require( - lookups.disputeResolverFeeTokenIndex[_disputeResolverId][_feeTokenAddresses[i]] != 0, - DISPUTE_RESOLVER_FEE_NOT_FOUND - ); + if (lookups.disputeResolverFeeTokenIndex[_disputeResolverId][_feeTokenAddresses[i]] == 0) + revert DisputeResolverFeeNotFound(); + uint256 disputeResolverFeeArrayIndex = lookups.disputeResolverFeeTokenIndex[_disputeResolverId][ _feeTokenAddresses[i] ] - 1; //Get the index in the DisputeResolverFees array, which is 1 less than the disputeResolverFeeTokenIndex index @@ -527,7 +524,8 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { uint256[] calldata _sellerAllowList ) external disputeResolversNotPaused nonReentrant { // At least one seller id must be specified - require(_sellerAllowList.length > 0, INEXISTENT_ALLOWED_SELLERS_LIST); + if (_sellerAllowList.length == 0) revert InexistentAllowedSellersList(); + bool exists; DisputeResolver storage disputeResolver; @@ -535,13 +533,13 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { (exists, disputeResolver, ) = fetchDisputeResolver(_disputeResolverId); // Dispute resolver must already exist - require(exists, NO_SUCH_DISPUTE_RESOLVER); + if (!exists) revert NoSuchDisputeResolver(); // Get message sender address sender = msgSender(); // Check that msg.sender is the admin address for this dispute resolver - require(disputeResolver.admin == sender, NOT_ADMIN); + if (disputeResolver.admin != sender) revert NotAdmin(); storeSellerAllowList(_disputeResolverId, _sellerAllowList); @@ -571,7 +569,7 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { ProtocolLib.ProtocolLookups storage lookups = protocolLookups(); // At least one seller id must be specified - require(_sellerAllowList.length > 0, INEXISTENT_ALLOWED_SELLERS_LIST); + if (_sellerAllowList.length == 0) revert InexistentAllowedSellersList(); bool exists; DisputeResolver storage disputeResolver; @@ -580,17 +578,17 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { (exists, disputeResolver, ) = fetchDisputeResolver(_disputeResolverId); // Dispute resolver must already exist - require(exists, NO_SUCH_DISPUTE_RESOLVER); + if (!exists) revert NoSuchDisputeResolver(); // Get message sender address sender = msgSender(); // Check that msg.sender is the admin address for this dispute resolver - require(disputeResolver.admin == sender, NOT_ADMIN); + if (disputeResolver.admin != sender) revert NotAdmin(); for (uint256 i = 0; i < _sellerAllowList.length; ) { uint256 sellerToRemoveIndex = lookups.allowedSellerIndex[_disputeResolverId][_sellerAllowList[i]]; - require(sellerToRemoveIndex > 0, SELLER_NOT_APPROVED); + if (sellerToRemoveIndex == 0) revert SellerNotApproved(); // remove index mapping delete lookups.allowedSellerIndex[_disputeResolverId][_sellerAllowList[i]]; @@ -772,10 +770,10 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { (bool exists, , ) = fetchSeller(sellerId); // Seller must already exist - require(exists, NO_SUCH_SELLER); + if (!exists) revert NoSuchSeller(); // Seller should not be approved already - require(lookups.allowedSellerIndex[_disputeResolverId][sellerId] == 0, SELLER_ALREADY_APPROVED); + if (lookups.allowedSellerIndex[_disputeResolverId][sellerId] != 0) revert SellerAlreadyApproved(); // Update the mappings lookups.allowedSellers[_disputeResolverId].push(sellerId); @@ -808,10 +806,9 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { uint256 check1 = _lookups.disputeResolverIdByAssistant[_role]; uint256 check2 = _lookups.disputeResolverIdByAdmin[_role]; - require( - (check1 == 0 || check1 == _disputeResolverId) && (check2 == 0 || check2 == _disputeResolverId), - DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE - ); + if ((check1 != 0 && check1 != _disputeResolverId) || (check2 != 0 && check2 != _disputeResolverId)) { + revert DisputeResolverAddressMustBeUnique(); + } } /** diff --git a/contracts/protocol/facets/ExchangeHandlerFacet.sol b/contracts/protocol/facets/ExchangeHandlerFacet.sol index 0c8c0f42f..940fcba1f 100644 --- a/contracts/protocol/facets/ExchangeHandlerFacet.sol +++ b/contracts/protocol/facets/ExchangeHandlerFacet.sol @@ -21,7 +21,7 @@ import { Address } from "@openzeppelin/contracts/utils/Address.sol"; * * @notice Handles exchanges associated with offers within the protocol. */ -contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, IERC721Receiver { +contract ExchangeHandlerFacet is DisputeBase, BuyerBase, IBosonExchangeHandler, IERC721Receiver { using Address for address; using Address for address payable; @@ -80,10 +80,10 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, uint256 _offerId ) external payable override exchangesNotPaused buyersNotPaused nonReentrant { // Make sure buyer address is not zero address - require(_buyer != address(0), INVALID_ADDRESS); + if (_buyer == address(0)) revert InvalidAddress(); Offer storage offer = getValidOffer(_offerId); - require(offer.priceType == PriceType.Static, INVALID_PRICE_TYPE); + if (offer.priceType != PriceType.Static) revert InvalidPriceType(); // For there to be a condition, there must be a group. (bool exists, uint256 groupId) = getGroupIdByOffer(offer.id); @@ -92,7 +92,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, Condition storage condition = fetchCondition(groupId); // Make sure group doesn't have a condition. If it does, use commitToConditionalOffer instead. - require(condition.method == EvaluationMethod.None, GROUP_HAS_CONDITION); + if (condition.method != EvaluationMethod.None) revert GroupHasCondition(); } commitToOfferInternal(_buyer, offer, 0, false); @@ -133,16 +133,16 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, uint256 _tokenId ) external payable override exchangesNotPaused buyersNotPaused nonReentrant { // Make sure buyer address is not zero address - require(_buyer != address(0), INVALID_ADDRESS); + if (_buyer == address(0)) revert InvalidAddress(); Offer storage offer = getValidOffer(_offerId); - require(offer.priceType == PriceType.Static, INVALID_PRICE_TYPE); + if (offer.priceType != PriceType.Static) revert InvalidPriceType(); // For there to be a condition, there must be a group. (bool exists, uint256 groupId) = getGroupIdByOffer(offer.id); // Make sure the group exists - require(exists, NO_SUCH_GROUP); + if (!exists) revert NoSuchGroup(); // Get the condition Condition storage condition = fetchCondition(groupId); @@ -196,12 +196,12 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, uint256 _offerId = _offer.id; // Make sure offer is available, expired, or sold out OfferDates storage offerDates = fetchOfferDates(_offerId); - require(block.timestamp >= offerDates.validFrom, OFFER_NOT_AVAILABLE); - require(block.timestamp <= offerDates.validUntil, OFFER_HAS_EXPIRED); + if (block.timestamp < offerDates.validFrom) revert OfferNotAvailable(); + if (block.timestamp > offerDates.validUntil) revert OfferHasExpired(); if (!_isPreminted) { // For non-preminted offers, quantityAvailable must be greater than zero, since it gets decremented - require(_offer.quantityAvailable > 0, OFFER_SOLD_OUT); + if (_offer.quantityAvailable == 0) revert OfferSoldOut(); // Get next exchange id for non-preminted offers _exchangeId = protocolCounters().nextExchangeId++; @@ -209,7 +209,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, // Exchange must not exist already (bool exists, ) = fetchExchange(_exchangeId); - require(!exists, EXCHANGE_ALREADY_EXISTS); + if (exists) revert ExchangeAlreadyExists(); } // Fetch or create buyer @@ -307,7 +307,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, // N.B. An existing buyer or seller may be the "anyone else" on an exchange they are not a part of if (!buyerExists || buyerId != exchange.buyerId) { uint256 elapsed = block.timestamp - voucher.redeemedDate; - require(elapsed >= fetchOfferDurations(offerId).disputePeriod, DISPUTE_PERIOD_NOT_ELAPSED); + if (elapsed < fetchOfferDurations(offerId).disputePeriod) revert DisputePeriodNotElapsed(); } // Finalize the exchange @@ -369,7 +369,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, (, Offer storage offer) = fetchOffer(offerId); // Only seller's assistant may call - require(sellerExists && offer.sellerId == sellerId, NOT_ASSISTANT); + if (!sellerExists || offer.sellerId != sellerId) revert NotAssistant(); // Finalize the exchange, burning the voucher finalizeExchange(exchange, ExchangeState.Revoked); @@ -423,7 +423,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, (Exchange storage exchange, Voucher storage voucher) = getValidExchange(_exchangeId, ExchangeState.Committed); // Make sure that the voucher has expired - require(block.timestamp > voucher.validUntilDate, VOUCHER_STILL_VALID); + if (block.timestamp <= voucher.validUntilDate) revert VoucherStillValid(); // Finalize the exchange, burning the voucher finalizeExchange(exchange, ExchangeState.Canceled); @@ -468,10 +468,10 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, (sellerExists, sellerId) = getSellerIdByAssistant(sender); // Only seller's assistant may call - require(sellerExists && offer.sellerId == sellerId, NOT_ASSISTANT); + if (!sellerExists || offer.sellerId != sellerId) revert NotAssistant(); // Make sure the proposed date is later than the current one - require(_validUntilDate > voucher.validUntilDate, VOUCHER_EXTENSION_NOT_VALID); + if (_validUntilDate <= voucher.validUntilDate) revert VoucherExtensionNotValid(); // Extend voucher voucher.validUntilDate = _validUntilDate; @@ -507,11 +507,11 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, checkBuyer(exchange.buyerId); // Make sure the voucher is redeemable - require( - block.timestamp >= fetchOfferDates(offerId).voucherRedeemableFrom && - block.timestamp <= voucher.validUntilDate, - VOUCHER_NOT_REDEEMABLE - ); + if ( + block.timestamp < fetchOfferDates(offerId).voucherRedeemableFrom || block.timestamp > voucher.validUntilDate + ) { + revert VoucherNotRedeemable(); + } // Store the time the exchange was redeemed voucher.redeemedDate = block.timestamp; @@ -560,12 +560,12 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, (Exchange storage exchange, Voucher storage voucher) = getValidExchange(exchangeId, ExchangeState.Committed); // Make sure that the voucher is still valid - require(block.timestamp <= voucher.validUntilDate, VOUCHER_HAS_EXPIRED); + if (block.timestamp > voucher.validUntilDate) revert VoucherHasExpired(); (, Offer storage offer) = fetchOffer(exchange.offerId); // Make sure that the voucher was issued on the clone that is making a call - require(msg.sender == getCloneAddress(lookups, offer.sellerId, offer.collectionIndex), ACCESS_DENIED); + if (msg.sender != getCloneAddress(lookups, offer.sellerId, offer.collectionIndex)) revert AccessDenied(); // Decrease voucher counter for old buyer lookups.voucherCount[exchange.buyerId]--; @@ -585,7 +585,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, if (ps.incomingVoucherCloneAddress != address(0)) { uint256 incomingVoucherId = ps.incomingVoucherId; if (incomingVoucherId != _tokenId) { - require(incomingVoucherId == 0, INCOMING_VOUCHER_ALREADY_SET); + if (incomingVoucherId != 0) revert IncomingVoucherAlreadySet(); ps.incomingVoucherId = _tokenId; } } @@ -623,7 +623,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, // Make sure that protocol is not reentered // Cannot use modifier `nonReentrant` since it also changes reentrancyStatus to `ENTERED` // This would break the flow since the protocol should be allowed to re-enter in this case. - require(ps.reentrancyStatus != ENTERED, REENTRANCY_GUARD); + if (ps.reentrancyStatus == ENTERED) revert ReentrancyGuard(); // Derive the offer id uint256 offerId = _tokenId >> 128; @@ -638,7 +638,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, address bosonVoucher = getCloneAddress(lookups, offer.sellerId, offer.collectionIndex); // Make sure that the voucher was issued on the clone that is making a call - require(msg.sender == bosonVoucher, ACCESS_DENIED); + if (msg.sender != bosonVoucher) revert AccessDenied(); (bool conditionExists, uint256 groupId) = getGroupIdByOffer(offerId); @@ -655,7 +655,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, uint256 minTokenId = condition.minTokenId; uint256 maxTokenId = condition.maxTokenId; - require(minTokenId == maxTokenId || maxTokenId == 0, CANNOT_COMMIT); // legacy conditions have maxTokenId == 0 + if (minTokenId != maxTokenId && maxTokenId != 0) revert CannotCommit(); // legacy conditions have maxTokenId == 0 // Uses token id from the condition tokenId = minTokenId; @@ -675,10 +675,8 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, // not resulte in a commit yet. The commit should happen when the voucher is transferred // from the protocol to the buyer. if (_to == address(this)) { - // can someone buys on protocol's behalf? what happens then - // Avoid reentrancy - require(ps.incomingVoucherId == 0, INCOMING_VOUCHER_ALREADY_SET); + if (ps.incomingVoucherId != 0) revert IncomingVoucherAlreadySet(); // Store the information about incoming voucher ps.incomingVoucherId = _tokenId; @@ -689,7 +687,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, } else { // In other cases voucher was already once transferred to the protocol, // so ps.incomingVoucherId is set already. The incoming _tokenId must match. - require(ps.incomingVoucherId == _tokenId, TOKEN_ID_MISMATCH); + if (ps.incomingVoucherId != _tokenId) revert TokenIdMismatch(); } commitToOfferInternal(_to, offer, exchangeId, true); @@ -709,14 +707,12 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, // 1. and 2. are allowed, while 3. and 4. and must revert. 3. and 4. should be executed via `commitToPriceDiscoveryOffer` if (_from == _rangeOwner) { // case 1. ["deposit"] - if (!_to.isContract()) { - // Prevent direct transfer to EOA (case 4.) - revert(VOUCHER_TRANSFER_NOT_ALLOWED); - } + // Prevent direct transfer to EOA (case 4.) + if (!_to.isContract()) revert VoucherTransferNotAllowed(); } else { // Case 2. ["withdraw"] // Prevent transfer to the buyer (case 3.) - require(_to == _rangeOwner, VOUCHER_TRANSFER_NOT_ALLOWED); + if (_to != _rangeOwner) revert VoucherTransferNotAllowed(); } } else if (offer.priceType == PriceType.Static) { // If price type is static, transaction can start from anywhere @@ -1181,13 +1177,13 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, uint256 commitCount = conditionalCommits[_groupId]; uint256 maxCommits = _condition.maxCommits; - require(commitCount < maxCommits, MAX_COMMITS_REACHED); + if (commitCount >= maxCommits) revert MaxCommitsReached(); bool allow = _condition.method == EvaluationMethod.Threshold ? holdsThreshold(_buyer, _condition, _tokenId) : holdsSpecificToken(_buyer, _condition, _tokenId); - require(allow, CANNOT_COMMIT); + if (!allow) revert CannotCommit(); // Increment number of commits to the group conditionalCommits[_groupId] = ++commitCount; @@ -1252,11 +1248,11 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, function getReceipt(uint256 _exchangeId) external view returns (Receipt memory receipt) { // Get the exchange (bool exists, Exchange storage exchange) = fetchExchange(_exchangeId); - require(exists, NO_SUCH_EXCHANGE); + if (!exists) revert NoSuchExchange(); // Verify if exchange is finalized, returns true if exchange is in one of the final states (, bool isFinalized) = isExchangeFinalized(_exchangeId); - require(isFinalized, EXCHANGE_IS_NOT_IN_A_FINAL_STATE); + if (!isFinalized) revert ExchangeIsNotInAFinalState(); // Add exchange to receipt receipt.exchangeId = exchange.id; @@ -1333,10 +1329,10 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, ) public virtual override returns (bytes4) { ProtocolLib.ProtocolStatus storage ps = protocolStatus(); - require( - ps.incomingVoucherId == _tokenId && ps.incomingVoucherCloneAddress == msg.sender, - UNEXPECTED_ERC721_RECEIVED - ); + if (ps.incomingVoucherId != _tokenId || ps.incomingVoucherCloneAddress != msg.sender) { + revert UnexpectedERC721Received(); + } + return this.onERC721Received.selector; } @@ -1393,7 +1389,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, EvaluationMethod method = _condition.method; bool isMultitoken = _condition.tokenType == TokenType.MultiToken; - require(method != EvaluationMethod.None, GROUP_HAS_NO_CONDITION); + if (method == EvaluationMethod.None) revert GroupHasNoCondition(); if (method == EvaluationMethod.SpecificToken || isMultitoken) { // In this cases, the token id is specified by the caller must be within the range of the condition @@ -1401,12 +1397,12 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase, uint256 maxTokenId = _condition.maxTokenId; if (maxTokenId == 0) maxTokenId = minTokenId; // legacy conditions have maxTokenId == 0 - require(_tokenId >= minTokenId && _tokenId <= maxTokenId, TOKEN_ID_NOT_IN_CONDITION_RANGE); + if (_tokenId < minTokenId || _tokenId > maxTokenId) revert TokenIdNotInConditionRange(); } // ERC20 and ERC721 threshold does not require a token id if (method == EvaluationMethod.Threshold && !isMultitoken) { - require(_tokenId == 0, INVALID_TOKEN_ID); + if (_tokenId != 0) revert InvalidTokenId(); } } } diff --git a/contracts/protocol/facets/FundsHandlerFacet.sol b/contracts/protocol/facets/FundsHandlerFacet.sol index 37fa66995..06fc9199e 100644 --- a/contracts/protocol/facets/FundsHandlerFacet.sol +++ b/contracts/protocol/facets/FundsHandlerFacet.sol @@ -50,21 +50,21 @@ contract FundsHandlerFacet is IBosonFundsHandler, ProtocolBase { address _tokenAddress, uint256 _amount ) external payable override fundsNotPaused nonReentrant { - require(_amount > 0, ZERO_DEPOSIT_NOT_ALLOWED); + if (_amount == 0) revert ZeroDepositNotAllowed(); // Check seller exists in sellers mapping (bool exists, , ) = fetchSeller(_sellerId); // Seller must exist - require(exists, NO_SUCH_SELLER); + if (!exists) revert NoSuchSeller(); if (msg.value != 0) { // Receiving native currency - require(_tokenAddress == address(0), NATIVE_WRONG_ADDRESS); - require(_amount == msg.value, NATIVE_WRONG_AMOUNT); + if (_tokenAddress != address(0)) revert NativeWrongAddress(); + if (_amount != msg.value) revert NativeWrongAmount(); } else { // Transfer tokens from the caller - require(_tokenAddress != address(0), INVALID_ADDRESS); + if (_tokenAddress == address(0)) revert InvalidAddress(); FundsLib.transferFundsToProtocol(_tokenAddress, _amount); } @@ -120,7 +120,7 @@ contract FundsHandlerFacet is IBosonFundsHandler, ProtocolBase { destinationAddress = sender; } else { // In this branch, caller is neither buyer, assistant or agent or does not match the _entityId - revert(NOT_AUTHORIZED); + revert NotAuthorized(); } } } @@ -284,7 +284,7 @@ contract FundsHandlerFacet is IBosonFundsHandler, ProtocolBase { ProtocolLib.ProtocolLookups storage lookups = protocolLookups(); // Make sure that the data is complete - require(_tokenList.length == _tokenAmounts.length, TOKEN_AMOUNT_MISMATCH); + if (_tokenList.length != _tokenAmounts.length) revert TokenAmountMismatch(); // Two possible options: withdraw all, or withdraw only specified tokens and amounts if (_tokenList.length == 0) { @@ -294,7 +294,7 @@ contract FundsHandlerFacet is IBosonFundsHandler, ProtocolBase { address[] memory tokenList = lookups.tokenList[_entityId]; // Make sure that at least something will be withdrawn - require(tokenList.length != 0, NOTHING_TO_WITHDRAW); + if (tokenList.length == 0) revert NothingToWithdraw(); // Get entity's availableFunds storage pointer mapping(address => uint256) storage entityFunds = lookups.availableFunds[_entityId]; @@ -312,7 +312,7 @@ contract FundsHandlerFacet is IBosonFundsHandler, ProtocolBase { } else { for (uint256 i = 0; i < _tokenList.length; ) { // Make sure that at least something will be withdrawn - require(_tokenAmounts[i] > 0, NOTHING_TO_WITHDRAW); + if (_tokenAmounts[i] == 0) revert NothingToWithdraw(); // Transfer funds FundsLib.transferFundsFromProtocol(_entityId, _tokenList[i], _destinationAddress, _tokenAmounts[i]); diff --git a/contracts/protocol/facets/GroupHandlerFacet.sol b/contracts/protocol/facets/GroupHandlerFacet.sol index fde0aef5e..30a1a90c1 100644 --- a/contracts/protocol/facets/GroupHandlerFacet.sol +++ b/contracts/protocol/facets/GroupHandlerFacet.sol @@ -97,7 +97,7 @@ contract GroupHandlerFacet is IBosonGroupHandler, GroupBase { // Offer should belong to the group (, uint256 groupId) = getGroupIdByOffer(offerId); - require(_groupId == groupId, OFFER_NOT_IN_GROUP); + if (_groupId != groupId) revert OfferNotInGroup(); // Remove groupIdByOffer mapping delete lookups.groupIdByOffer[offerId]; @@ -153,11 +153,11 @@ contract GroupHandlerFacet is IBosonGroupHandler, GroupBase { Condition calldata _condition ) external override groupsNotPaused nonReentrant { // Validate condition parameters - require(validateCondition(_condition), INVALID_CONDITION_PARAMETERS); + if (!validateCondition(_condition)) revert InvalidConditionParameters(); // Verify group exists (bool exists, Group storage group) = fetchGroup(_groupId); - require(exists, NO_SUCH_GROUP); + if (!exists) revert NoSuchGroup(); // Get message sender address sender = msgSender(); @@ -166,7 +166,7 @@ contract GroupHandlerFacet is IBosonGroupHandler, GroupBase { (, uint256 sellerId) = getSellerIdByAssistant(sender); // Caller's seller id must match group seller id - require(sellerId == group.sellerId, NOT_ASSISTANT); + if (sellerId != group.sellerId) revert NotAssistant(); // Store new condition storeCondition(_groupId, _condition); diff --git a/contracts/protocol/facets/MetaTransactionsHandlerFacet.sol b/contracts/protocol/facets/MetaTransactionsHandlerFacet.sol index 72de932b0..1129cf8ba 100644 --- a/contracts/protocol/facets/MetaTransactionsHandlerFacet.sol +++ b/contracts/protocol/facets/MetaTransactionsHandlerFacet.sol @@ -206,16 +206,16 @@ contract MetaTransactionsHandlerFacet is IBosonMetaTransactionsHandler, Protocol ProtocolLib.ProtocolMetaTxInfo storage pmti = protocolMetaTxInfo(); // Nonce should be unused - require(!pmti.usedNonce[_userAddress][_nonce], NONCE_USED_ALREADY); + if (pmti.usedNonce[_userAddress][_nonce]) revert NonceUsedAlready(); // Function must be allowlisted bytes32 functionNameHash = keccak256(abi.encodePacked(_functionName)); - require(pmti.isAllowlisted[functionNameHash], FUNCTION_NOT_ALLOWLISTED); + if (!pmti.isAllowlisted[functionNameHash]) revert FunctionNotAllowlisted(); // Function name must correspond to selector bytes4 destinationFunctionSig = convertBytesToBytes4(_functionSignature); bytes4 functionNameSig = bytes4(functionNameHash); - require(destinationFunctionSig == functionNameSig, INVALID_FUNCTION_NAME); + if (destinationFunctionSig != functionNameSig) revert InvalidFunctionName(); } /** @@ -320,7 +320,7 @@ contract MetaTransactionsHandlerFacet is IBosonMetaTransactionsHandler, Protocol // Make sure that protocol is not reentered through meta transactions // Cannot use modifier `nonReentrant` since it also changes reentrancyStatus to `ENTERED`, // but that then breaks meta transaction functionality - require(protocolStatus().reentrancyStatus != ENTERED, REENTRANCY_GUARD); + if (protocolStatus().reentrancyStatus == ENTERED) revert ReentrancyGuard(); validateTx(_functionName, _functionSignature, _nonce, _userAddress); @@ -333,10 +333,8 @@ contract MetaTransactionsHandlerFacet is IBosonMetaTransactionsHandler, Protocol ? bytes(_functionSignature[4:]) : _functionSignature; - require( - EIP712Lib.verify(_userAddress, hashMetaTransaction(metaTx), _sigR, _sigS, _sigV), - SIGNER_AND_SIGNATURE_DO_NOT_MATCH - ); + if (!EIP712Lib.verify(_userAddress, hashMetaTransaction(metaTx), _sigR, _sigS, _sigV)) + revert SignerAndSignatureDoNotMatch(); return executeTx(_userAddress, _functionName, _functionSignature, _nonce); } diff --git a/contracts/protocol/facets/OfferHandlerFacet.sol b/contracts/protocol/facets/OfferHandlerFacet.sol index 82edd2777..1fa06e055 100644 --- a/contracts/protocol/facets/OfferHandlerFacet.sol +++ b/contracts/protocol/facets/OfferHandlerFacet.sol @@ -108,13 +108,14 @@ contract OfferHandlerFacet is IBosonOfferHandler, OfferBase { uint256[] calldata _agentIds ) external override offersNotPaused nonReentrant { // Number of offer dates structs, offer durations structs and _disputeResolverIds must match the number of offers - require( - _offers.length == _offerDates.length && - _offers.length == _offerDurations.length && - _offers.length == _disputeResolverIds.length && - _offers.length == _agentIds.length, - ARRAY_LENGTH_MISMATCH - ); + if ( + _offers.length != _offerDates.length || + _offers.length != _offerDurations.length || + _offers.length != _disputeResolverIds.length || + _offers.length != _agentIds.length + ) { + revert ArrayLengthMismatch(); + } for (uint256 i = 0; i < _offers.length; ) { // Create offer and update structs values to represent true state @@ -224,11 +225,11 @@ contract OfferHandlerFacet is IBosonOfferHandler, OfferBase { OfferDates storage offerDates = fetchOfferDates(_offerId); // New valid until date must be greater than existing one - require(offerDates.validUntil < _validUntilDate, OFFER_PERIOD_INVALID); + if (offerDates.validUntil >= _validUntilDate) revert InvalidOfferPeriod(); // If voucherRedeemableUntil is set, _validUntilDate must be less or equal than that if (offerDates.voucherRedeemableUntil > 0) { - require(_validUntilDate <= offerDates.voucherRedeemableUntil, OFFER_PERIOD_INVALID); + if (_validUntilDate > offerDates.voucherRedeemableUntil) revert InvalidOfferPeriod(); } // Update the valid until property diff --git a/contracts/protocol/facets/PauseHandlerFacet.sol b/contracts/protocol/facets/PauseHandlerFacet.sol index 52031e16c..d6beac171 100644 --- a/contracts/protocol/facets/PauseHandlerFacet.sol +++ b/contracts/protocol/facets/PauseHandlerFacet.sol @@ -5,7 +5,7 @@ import "../../domain/BosonConstants.sol"; import { DiamondLib } from "../../diamond/DiamondLib.sol"; import "../../domain/BosonConstants.sol"; import { BosonTypes } from "../../domain/BosonTypes.sol"; -import { ProtocolBase } from "../bases/OfferBase.sol"; +import { ProtocolBase } from "../bases/ProtocolBase.sol"; import { ProtocolLib } from "../libs/ProtocolLib.sol"; import { IBosonPauseHandler } from "../../interfaces/handlers/IBosonPauseHandler.sol"; @@ -54,7 +54,7 @@ contract PauseHandlerFacet is ProtocolBase, IBosonPauseHandler { ProtocolLib.ProtocolStatus storage status = protocolStatus(); // Make sure the protocol is paused - require(status.pauseScenario > 0, NOT_PAUSED); + if (status.pauseScenario == 0) revert NotPaused(); togglePause(_regions, false); diff --git a/contracts/protocol/facets/PriceDiscoveryHandlerFacet.sol b/contracts/protocol/facets/PriceDiscoveryHandlerFacet.sol index 8acabfdc1..7027a161a 100644 --- a/contracts/protocol/facets/PriceDiscoveryHandlerFacet.sol +++ b/contracts/protocol/facets/PriceDiscoveryHandlerFacet.sol @@ -77,13 +77,7 @@ contract PriceDiscoveryHandlerFacet is IBosonPriceDiscoveryHandler, PriceDiscove PriceDiscovery calldata _priceDiscovery ) external payable override exchangesNotPaused buyersNotPaused { // Make sure buyer address is not zero address - require(_buyer != address(0), INVALID_ADDRESS); - - // Make sure caller provided price discovery data - require( - _priceDiscovery.priceDiscoveryContract != address(0) && _priceDiscovery.priceDiscoveryData.length > 0, - INVALID_PRICE_DISCOVERY - ); + if (_buyer == address(0)) revert InvalidAddress(); bool isTokenId; uint256 offerId = _tokenIdOrOfferId >> 128; @@ -104,7 +98,7 @@ contract PriceDiscoveryHandlerFacet is IBosonPriceDiscoveryHandler, PriceDiscove Offer storage offer = getValidOffer(offerId); // Make sure offer type is price discovery. Otherwise, use commitToOffer - require(offer.priceType == PriceType.Discovery, INVALID_PRICE_TYPE); + if (offer.priceType != PriceType.Discovery) revert InvalidPriceType(); uint256 sellerId = offer.sellerId; uint256 actualPrice; @@ -137,7 +131,7 @@ contract PriceDiscoveryHandlerFacet is IBosonPriceDiscoveryHandler, PriceDiscove ).royaltyInfo(exchangeId, actualPrice); // Verify that fees and royalties are not higher than the price. - require((protocolFeeAmount + royaltyAmount) <= actualPrice, FEE_AMOUNT_TOO_HIGH); + if (protocolFeeAmount + royaltyAmount > actualPrice) revert FeeAmountTooHigh(); // Store exchange costs so it can be released later. This is the first cost entry for this exchange. exchangeCosts.push( diff --git a/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol b/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol index 0e15675ca..59d1961f1 100644 --- a/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol +++ b/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol @@ -22,7 +22,7 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl */ modifier onlyUninitializedVersion(bytes32 _version) { ProtocolLib.ProtocolStatus storage ps = protocolStatus(); - require(!ps.initializedVersions[_version], ALREADY_INITIALIZED); + if (ps.initializedVersions[_version]) revert AlreadyInitialized(); ps.initializedVersions[_version] = true; _; } @@ -68,9 +68,9 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl bytes4[] calldata _interfacesToRemove, bytes4[] calldata _interfacesToAdd ) external onlyUninitializedVersion(_version) { - require(address(this) != thisAddress, DIRECT_INITIALIZATION_NOT_ALLOWED); - require(_version != bytes32(0), VERSION_MUST_BE_SET); - require(_addresses.length == _calldata.length, ADDRESSES_AND_CALLDATA_LENGTH_MISMATCH); + if (address(this) == thisAddress) revert DirectInitializationNotAllowed(); + if (_version == bytes32(0)) revert VersionMustBeSet(); + if (_addresses.length != _calldata.length) revert AddressesAndCalldataLengthMismatch(); // Delegate call to initialize methods of facets declared in _addresses for (uint256 i = 0; i < _addresses.length; ) { @@ -85,7 +85,7 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl } } else { // Reverts with default message - revert(PROTOCOL_INITIALIZATION_FAILED); + revert ProtocolInitializationFailed(); } } @@ -122,11 +122,11 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl */ function initV2_2_0(bytes calldata _initializationData) internal { // v2.2.0 can only be initialized if the current version does not exist yet - require(protocolStatus().version == 0x0, WRONG_CURRENT_VERSION); + if (protocolStatus().version != bytes32(0)) revert WrongCurrentVersion(); // Initialize limits.maxPremintedVouchers (configHandlerFacet initializer) uint256 _maxPremintedVouchers = abi.decode(_initializationData, (uint256)); - require(_maxPremintedVouchers != 0, VALUE_ZERO_NOT_ALLOWED); + if (_maxPremintedVouchers == 0) revert ValueZeroNotAllowed(); protocolLimits().maxPremintedVouchers = _maxPremintedVouchers; emit MaxPremintedVouchersChanged(_maxPremintedVouchers, msgSender()); } @@ -136,7 +136,7 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl */ function initV2_2_1() internal view { // Current version must be 2.2.0 - require(protocolStatus().version == bytes32("2.2.0"), WRONG_CURRENT_VERSION); + if (protocolStatus().version != bytes32("2.2.0")) revert WrongCurrentVersion(); } /** @@ -154,9 +154,9 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl */ function initV2_3_0(bytes calldata _initializationData) internal { // Current version must be 2.2.1 - require(protocolStatus().version == bytes32("2.2.1"), WRONG_CURRENT_VERSION); + if (protocolStatus().version != bytes32("2.2.1")) revert WrongCurrentVersion(); - require(protocolCounters().nextTwinId == 1, TWINS_ALREADY_EXIST); + if (protocolCounters().nextTwinId != 1) revert TwinsAlreadyExist(); // Decode initialization data uint256 _minResolutionPeriod = abi.decode(_initializationData, (uint256)); @@ -165,10 +165,10 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl ProtocolLib.ProtocolLimits storage limits = protocolLimits(); // make sure _minResolutionPeriod is less than maxResolutionPeriod - require(limits.maxResolutionPeriod >= _minResolutionPeriod, INVALID_RESOLUTION_PERIOD); + if (limits.maxResolutionPeriod < _minResolutionPeriod) revert InvalidResolutionPeriod(); // Initialize limits.maxPremintedVouchers (configHandlerFacet initializer) - require(_minResolutionPeriod != 0, VALUE_ZERO_NOT_ALLOWED); + if (_minResolutionPeriod == 0) revert ValueZeroNotAllowed(); limits.minResolutionPeriod = _minResolutionPeriod; emit MinResolutionPeriodChanged(_minResolutionPeriod, msgSender()); diff --git a/contracts/protocol/facets/SellerHandlerFacet.sol b/contracts/protocol/facets/SellerHandlerFacet.sol index 452185063..874d882e6 100644 --- a/contracts/protocol/facets/SellerHandlerFacet.sol +++ b/contracts/protocol/facets/SellerHandlerFacet.sol @@ -89,20 +89,21 @@ contract SellerHandlerFacet is SellerBase { AuthToken storage authToken; // Admin address or AuthToken data must be present. A seller can have one or the other - require( - (_seller.admin == address(0) && _authToken.tokenType != AuthTokenType.None) || - (_seller.admin != address(0) && _authToken.tokenType == AuthTokenType.None), - ADMIN_OR_AUTH_TOKEN - ); - require(_seller.clerk == address(0), CLERK_DEPRECATED); + if ( + (_seller.admin == address(0) && _authToken.tokenType == AuthTokenType.None) || + (_seller.admin != address(0) && _authToken.tokenType != AuthTokenType.None) + ) { + revert AdminOrAuthToken(); + } + if (_seller.clerk != address(0)) revert ClerkDeprecated(); - require(_authToken.tokenType != AuthTokenType.Custom, INVALID_AUTH_TOKEN_TYPE); + if (_authToken.tokenType == AuthTokenType.Custom) revert InvalidAuthTokenType(); // Check Seller exists in sellers mapping (exists, seller, authToken) = fetchSeller(_seller.id); // Seller must already exist - require(exists, NO_SUCH_SELLER); + if (!exists) revert NoSuchSeller(); // Get message sender address sender = msgSender(); @@ -124,8 +125,8 @@ contract SellerHandlerFacet is SellerBase { // If AuthToken data is different from the one in storage, then set it as pending update if (authToken.tokenType != _authToken.tokenType || authToken.tokenId != _authToken.tokenId) { // Check that auth token is unique to this seller - uint256 check = lookups.sellerIdByAuthToken[_authToken.tokenType][_authToken.tokenId]; - require(check == 0, AUTH_TOKEN_MUST_BE_UNIQUE); + if (lookups.sellerIdByAuthToken[_authToken.tokenType][_authToken.tokenId] != 0) + revert AuthTokenMustBeUnique(); // Auth token owner must approve the update to prevent front-running authTokenPendingUpdate.tokenType = _authToken.tokenType; @@ -141,7 +142,8 @@ contract SellerHandlerFacet is SellerBase { if (_seller.assistant != seller.assistant) { preUpdateSellerCheck(_seller.id, _seller.assistant, lookups); - require(_seller.assistant != address(0), INVALID_ADDRESS); + if (_seller.assistant == address(0)) revert InvalidAddress(); + // Assistant address owner must approve the update to prevent front-running sellerPendingUpdate.assistant = _seller.assistant; needsApproval = true; @@ -150,7 +152,7 @@ contract SellerHandlerFacet is SellerBase { bool updateApplied; if (_seller.treasury != seller.treasury) { - require(_seller.treasury != address(0), INVALID_ADDRESS); + if (_seller.treasury == address(0)) revert InvalidAddress(); // Update treasury seller.treasury = _seller.treasury; @@ -182,7 +184,7 @@ contract SellerHandlerFacet is SellerBase { emit SellerUpdatePending(_seller.id, sellerPendingUpdate, authTokenPendingUpdate, sender); } - require(updateApplied || needsApproval, NO_UPDATE_APPLIED); + if (!updateApplied && !needsApproval) revert NoUpdateApplied(); } /** @@ -215,7 +217,7 @@ contract SellerHandlerFacet is SellerBase { (exists, sellerPendingUpdate, authTokenPendingUpdate) = fetchSellerPendingUpdate(_sellerId); // Be sure an update is pending - require(exists, NO_PENDING_UPDATE_FOR_ACCOUNT); + if (!exists) revert NoPendingUpdateForAccount(); } bool updateApplied; @@ -233,7 +235,7 @@ contract SellerHandlerFacet is SellerBase { // Approve admin update if (role == SellerUpdateFields.Admin && sellerPendingUpdate.admin != address(0)) { - require(sellerPendingUpdate.admin == sender, UNAUTHORIZED_CALLER_UPDATE); + if (sellerPendingUpdate.admin != sender) revert UnauthorizedCallerUpdate(); preUpdateSellerCheck(_sellerId, sender, lookups); @@ -258,7 +260,7 @@ contract SellerHandlerFacet is SellerBase { updateApplied = true; } else if (role == SellerUpdateFields.Assistant && sellerPendingUpdate.assistant != address(0)) { // Approve assistant update - require(sellerPendingUpdate.assistant == sender, UNAUTHORIZED_CALLER_UPDATE); + if (sellerPendingUpdate.assistant != sender) revert UnauthorizedCallerUpdate(); preUpdateSellerCheck(_sellerId, sender, lookups); @@ -292,13 +294,11 @@ contract SellerHandlerFacet is SellerBase { // Approve auth token update address authTokenContract = lookups.authTokenContracts[authTokenPendingUpdate.tokenType]; address tokenIdOwner = IERC721(authTokenContract).ownerOf(authTokenPendingUpdate.tokenId); - require(tokenIdOwner == sender, UNAUTHORIZED_CALLER_UPDATE); + if (tokenIdOwner != sender) revert UnauthorizedCallerUpdate(); // Check that auth token is unique to this seller - uint256 check = lookups.sellerIdByAuthToken[authTokenPendingUpdate.tokenType][ - authTokenPendingUpdate.tokenId - ]; - require(check == 0, AUTH_TOKEN_MUST_BE_UNIQUE); + if (lookups.sellerIdByAuthToken[authTokenPendingUpdate.tokenType][authTokenPendingUpdate.tokenId] != 0) + revert AuthTokenMustBeUnique(); // Delete old seller id by auth token mapping delete lookups.sellerIdByAuthToken[authToken.tokenType][authToken.tokenId]; @@ -322,7 +322,7 @@ contract SellerHandlerFacet is SellerBase { updateApplied = true; } else if (role == SellerUpdateFields.Clerk) { - revert(CLERK_DEPRECATED); + revert ClerkDeprecated(); } unchecked { @@ -363,7 +363,7 @@ contract SellerHandlerFacet is SellerBase { address assistant = msgSender(); (bool exists, uint256 sellerId) = getSellerIdByAssistant(assistant); - require(exists, NO_SUCH_SELLER); + if (!exists) revert NoSuchSeller(); Collection[] storage sellersAdditionalCollections = lookups.additionalCollections[sellerId]; uint256 collectionIndex = sellersAdditionalCollections.length + 1; // 0 is reserved for the original collection @@ -378,7 +378,7 @@ contract SellerHandlerFacet is SellerBase { admin = IERC721(lookups.authTokenContracts[authToken.tokenType]).ownerOf(authToken.tokenId); } sellerSalt = keccak256(abi.encodePacked(admin, _voucherInitValues.collectionSalt)); - require(!lookups.isUsedSellerSalt[sellerSalt], SELLER_SALT_NOT_UNIQUE); + if (lookups.isUsedSellerSalt[sellerSalt]) revert SellerSaltNotUnique(); lookups.sellerSalt[sellerId] = sellerSalt; lookups.isUsedSellerSalt[sellerSalt] = true; } @@ -422,14 +422,14 @@ contract SellerHandlerFacet is SellerBase { (bool exists, Seller storage seller, AuthToken storage authToken) = fetchSeller(_sellerId); // Seller must already exist - require(exists, NO_SUCH_SELLER); + if (!exists) revert NoSuchSeller(); // Check that caller is authorized to call this function authorizeAdmin(lookups, authToken, seller.admin, admin); bytes32 sellerSalt = keccak256(abi.encodePacked(admin, _newSalt)); - require(!lookups.isUsedSellerSalt[sellerSalt], SELLER_SALT_NOT_UNIQUE); + if (lookups.isUsedSellerSalt[sellerSalt]) revert SellerSaltNotUnique(); lookups.isUsedSellerSalt[lookups.sellerSalt[_sellerId]] = false; lookups.sellerSalt[_sellerId] = sellerSalt; lookups.isUsedSellerSalt[sellerSalt] = true; @@ -592,10 +592,8 @@ contract SellerHandlerFacet is SellerBase { uint256 check1 = _lookups.sellerIdByAssistant[_role]; uint256 check2 = _lookups.sellerIdByAdmin[_role]; - require( - (check1 == 0 || check1 == _sellerId) && (check2 == 0 || check2 == _sellerId), - SELLER_ADDRESS_MUST_BE_UNIQUE - ); + if ((check1 != 0 && check1 != _sellerId) || (check2 != 0 && check2 != _sellerId)) + revert SellerAddressMustBeUnique(); } } @@ -624,11 +622,11 @@ contract SellerHandlerFacet is SellerBase { address _sender ) internal view { if (_admin != address(0)) { - require(_admin == _sender, NOT_ADMIN); + if (_admin != _sender) revert NotAdmin(); } else { address authTokenContract = _lookups.authTokenContracts[_authToken.tokenType]; address tokenIdOwner = IERC721(authTokenContract).ownerOf(_authToken.tokenId); - require(tokenIdOwner == _sender, NOT_ADMIN); + if (tokenIdOwner != _sender) revert NotAdmin(); } } } diff --git a/contracts/protocol/facets/SequentialCommitHandlerFacet.sol b/contracts/protocol/facets/SequentialCommitHandlerFacet.sol index 53f7be6b9..75dcd7dd9 100644 --- a/contracts/protocol/facets/SequentialCommitHandlerFacet.sol +++ b/contracts/protocol/facets/SequentialCommitHandlerFacet.sol @@ -81,13 +81,7 @@ contract SequentialCommitHandlerFacet is IBosonSequentialCommitHandler, PriceDis PriceDiscovery calldata _priceDiscovery ) external payable exchangesNotPaused buyersNotPaused nonReentrant { // Make sure buyer address is not zero address - require(_buyer != address(0), INVALID_ADDRESS); - - // Make sure caller provided price discovery data - require( - _priceDiscovery.priceDiscoveryContract != address(0) && _priceDiscovery.priceDiscoveryData.length > 0, - INVALID_PRICE_DISCOVERY - ); + if (_buyer == address(0)) revert InvalidAddress(); uint256 exchangeId = _tokenId & type(uint128).max; @@ -95,7 +89,7 @@ contract SequentialCommitHandlerFacet is IBosonSequentialCommitHandler, PriceDis (Exchange storage exchange, Voucher storage voucher) = getValidExchange(exchangeId, ExchangeState.Committed); // Make sure the voucher is still valid - require(block.timestamp <= voucher.validUntilDate, VOUCHER_HAS_EXPIRED); + if (block.timestamp > voucher.validUntilDate) revert VoucherHasExpired(); // Create a memory struct for sequential commit and populate it as we go // This is done to avoid stack too deep error, while still keeping the number of SLOADs to a minimum @@ -137,10 +131,9 @@ contract SequentialCommitHandlerFacet is IBosonSequentialCommitHandler, PriceDis ).royaltyInfo(exchangeId, exchangeCost.price); // Verify that fees and royalties are not higher than the price. - require( - (exchangeCost.protocolFeeAmount + exchangeCost.royaltyAmount) <= exchangeCost.price, - FEE_AMOUNT_TOO_HIGH - ); + if (exchangeCost.protocolFeeAmount + exchangeCost.royaltyAmount > exchangeCost.price) { + revert FeeAmountTooHigh(); + } // Get price paid by current buyer uint256 len = exchangeCosts.length; diff --git a/contracts/protocol/facets/TwinHandlerFacet.sol b/contracts/protocol/facets/TwinHandlerFacet.sol index 37cd2ecbc..308b0ddfa 100644 --- a/contracts/protocol/facets/TwinHandlerFacet.sol +++ b/contracts/protocol/facets/TwinHandlerFacet.sol @@ -62,7 +62,7 @@ contract TwinHandlerFacet is IBosonTwinHandler, TwinBase { // Get storage location for twin (bool exists, Twin memory twin) = fetchTwin(_twinId); - require(exists, NO_SUCH_TWIN); + if (!exists) revert NoSuchTwin(); // Get message sender address sender = msgSender(); @@ -70,11 +70,11 @@ contract TwinHandlerFacet is IBosonTwinHandler, TwinBase { // Get seller id (, uint256 sellerId) = getSellerIdByAssistant(sender); // Caller's seller id must match twin seller id - require(sellerId == twin.sellerId, NOT_ASSISTANT); + if (sellerId != twin.sellerId) revert NotAssistant(); // Check if there are bundles for this twin (bool bundleForTwinExist, ) = fetchBundleIdByTwin(_twinId); - require(!bundleForTwinExist, BUNDLE_FOR_TWIN_EXISTS); + if (bundleForTwinExist) revert BundleForTwinExists(); // Delete struct delete protocolEntities().twins[_twinId]; diff --git a/contracts/protocol/libs/EIP712Lib.sol b/contracts/protocol/libs/EIP712Lib.sol index 14e7d12fd..c5bbf4b20 100644 --- a/contracts/protocol/libs/EIP712Lib.sol +++ b/contracts/protocol/libs/EIP712Lib.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import "../../domain/BosonConstants.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { ProtocolLib } from "../libs/ProtocolLib.sol"; /** @@ -55,14 +56,13 @@ library EIP712Lib { ) internal returns (bool) { // Ensure signature is unique // See https://github.com/OpenZeppelin/openzeppelin-contracts/blob/04695aecbd4d17dddfd55de766d10e3805d6f42f/contracts/cryptography/ECDSA.sol#63 - require( - uint256(_sigS) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 && - (_sigV == 27 || _sigV == 28), - INVALID_SIGNATURE - ); + if ( + uint256(_sigS) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 || + (_sigV != 27 && _sigV != 28) + ) revert BosonErrors.InvalidSignature(); address signer = ecrecover(toTypedMessageHash(_hashedMetaTx), _sigV, _sigR, _sigS); - require(signer != address(0), INVALID_SIGNATURE); + if (signer == address(0)) revert BosonErrors.InvalidSignature(); return signer == _user; } @@ -124,7 +124,7 @@ library EIP712Lib { // Get sender from the storage if this is a meta transaction if (isItAMetaTransaction) { address sender = getCurrentSenderAddress(); - require(sender != address(0), INVALID_ADDRESS); + if (sender == address(0)) revert BosonErrors.InvalidAddress(); return sender; } else { diff --git a/contracts/protocol/libs/FundsLib.sol b/contracts/protocol/libs/FundsLib.sol index 77aafb6a7..22b102274 100644 --- a/contracts/protocol/libs/FundsLib.sol +++ b/contracts/protocol/libs/FundsLib.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.21; import "../../domain/BosonConstants.sol"; +import { BosonErrors } from "../../domain/BosonErrors.sol"; import { BosonTypes } from "../../domain/BosonTypes.sol"; import { EIP712Lib } from "../libs/EIP712Lib.sol"; import { ProtocolLib } from "../libs/ProtocolLib.sol"; @@ -117,11 +118,11 @@ library FundsLib { */ function validateIncomingPayment(address _exchangeToken, uint256 _value) internal { if (_exchangeToken == address(0)) { - // if transfer is in the native currency, msg.value must match price - require(msg.value == _value, INSUFFICIENT_VALUE_RECEIVED); + // if transfer is in the native currency, msg.value must match offer price + if (msg.value != _value) revert BosonErrors.InsufficientValueReceived(); } else { // when price is in an erc20 token, transferring the native currency is not allowed - require(msg.value == 0, NATIVE_NOT_ALLOWED); + if (msg.value != 0) revert BosonErrors.NativeNotAllowed(); // if transfer is in ERC20 token, try to transfer the amount from buyer to the protocol transferFundsToProtocol(_exchangeToken, _value); @@ -403,7 +404,8 @@ library FundsLib { uint256 protocolTokenBalanceAfter = IERC20(_tokenAddress).balanceOf(address(this)); // make sure that expected amount of tokens was transferred - require(protocolTokenBalanceAfter - protocolTokenBalanceBefore == _amount, INSUFFICIENT_VALUE_RECEIVED); + if (protocolTokenBalanceAfter - protocolTokenBalanceBefore != _amount) + revert BosonErrors.InsufficientValueReceived(); } } @@ -469,7 +471,7 @@ library FundsLib { if (_tokenAddress == address(0)) { // transfer native currency (bool success, ) = _to.call{ value: _amount }(""); - require(success, TOKEN_TRANSFER_FAILED); + if (!success) revert BosonErrors.TokenTransferFailed(); } else { // transfer ERC20 tokens IERC20(_tokenAddress).safeTransfer(_to, _amount); @@ -518,7 +520,7 @@ library FundsLib { uint256 entityFunds = availableFunds[_tokenAddress]; // make sure that seller has enough funds in the pool and reduce the available funds - require(entityFunds >= _amount, INSUFFICIENT_AVAILABLE_FUNDS); + if (entityFunds < _amount) revert BosonErrors.InsufficientAvailableFunds(); // Use unchecked to optimize execution cost. The math is safe because of the require above. unchecked { diff --git a/scripts/config/revert-reasons-old.js b/scripts/config/revert-reasons-old.js new file mode 100644 index 000000000..21ed1a0ab --- /dev/null +++ b/scripts/config/revert-reasons-old.js @@ -0,0 +1,212 @@ +/** + * Reasons for Boson Protocol transactions to revert + */ +exports.RevertReasons = { + // Access related + ACCESS_DENIED: "Access denied, caller doesn't have role", + NOT_BUYER_OR_SELLER: "Not buyer or seller", + NOT_VOUCHER_HOLDER: "Not current voucher holder", + CAN_ONLY_REVOKE_SELF: "AccessControl: can only renounce roles for self", + + // Pause related + NOT_PAUSED: "Protocol is not currently paused", + REGION_PAUSED: "This region of the protocol is currently paused", + + // General + INVALID_ADDRESS: "Invalid address", + INVALID_STATE: "Invalid state", + ARRAY_LENGTH_MISMATCH: "Array length mismatch", + REENTRANCY_GUARD: "ReentrancyGuard: reentrant call", + + // Facet initializer related + ALREADY_INITIALIZED: "Already initialized", + PROTOCOL_INITIALIZATION_FAILED: "Protocol initialization failed", + VERSION_MUST_BE_SET: "Version cannot be empty", + ADDRESSES_AND_CALLDATA_LENGTH_MISMATCH: "Addresses and calldata must be same length", + WRONG_CURRENT_VERSION: "Wrong current protocol version", + DIRECT_INITIALIZATION_NOT_ALLOWED: "Direct initializtion is not allowed", + TWINS_ALREADY_EXIST: "Should not have any twins yet", + + // Offer related + NOT_ASSISTANT: "Not seller's assistant", + NO_SUCH_OFFER: "No such offer", + OFFER_HAS_BEEN_VOIDED: "Offer has been voided", + OFFER_PERIOD_INVALID: "Offer period invalid", + OFFER_PENALTY_INVALID: "Offer penalty invalid", + OFFER_MUST_BE_ACTIVE: "Offer must be active", + OFFER_MUST_BE_UNIQUE: "Offer must be unique to a group", + CANNOT_COMMIT: "Caller cannot commit", + EXCHANGE_FOR_OFFER_EXISTS: "Exchange for offer exists", + AMBIGUOUS_VOUCHER_EXPIRY: "Exactly one of voucherRedeemableUntil and voucherValid must be non zero", + REDEMPTION_PERIOD_INVALID: "Redemption period invalid", + INVALID_DISPUTE_PERIOD: "Invalid dispute period", + INVALID_RESOLUTION_PERIOD: "Invalid resolution period", + INVALID_DISPUTE_RESOLVER: "Invalid dispute resolver", + INVALID_QUANTITY_AVAILABLE: "Invalid quantity available", + DR_UNSUPPORTED_FEE: "Dispute resolver does not accept this token", + AGENT_FEE_AMOUNT_TOO_HIGH: "Sum of agent fee amount and protocol fee amount should be <= offer fee limit", + OFFER_NOT_AVAILABLE: "Offer is not yet available", + OFFER_HAS_EXPIRED: "Offer has expired", + OFFER_SOLD_OUT: "Offer has sold out", + NO_SUCH_COLLECTION: "No such collection", + + // Group related + NO_SUCH_GROUP: "No such group", + OFFER_NOT_IN_GROUP: "Offer not part of the group", + NOTHING_UPDATED: "Nothing updated", + INVALID_CONDITION_PARAMETERS: "Invalid condition parameters", + MAX_COMMITS_REACHED: "Max commits reached", + GROUP_HAS_NO_CONDITION: "Offer belongs to a group without a condition. Use commitToOffer instead", + GROUP_HAS_CONDITION: "Offer belongs to a group with a condition. Use commitToConditionalOffer instead", + TOKEN_ID_NOT_IN_CONDITION_RANGE: "Token id not in condition range", + INVALID_TOKEN_ID: "ERC721 and ERC20 require zero tokenId", + + // Account-related + MUST_BE_ACTIVE: "Account must be active", + NO_SUCH_SELLER: "No such seller", + SELLER_ADDRESS_MUST_BE_UNIQUE: "Seller address cannot be assigned to another seller Id", + BUYER_ADDRESS_MUST_BE_UNIQUE: "Buyer address cannot be assigned to another buyer Id", + DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE: "Dispute resolver address cannot be assigned to another dispute resolver Id", + AGENT_ADDRESS_MUST_BE_UNIQUE: "Agent address cannot be assigned to another agent Id", + NOT_ADMIN: "Not admin", + CLERK_DEPRECATED: "Clerk is deprecated and must be set to address 0", + NOT_ADMIN_AND_ASSISTANT: "Not admin and assistant", + NOT_BUYER_WALLET: "Not buyer's wallet address", + NOT_AGENT_WALLET: "Not agent's wallet address", + NO_SUCH_BUYER: "No such buyer", + NO_SUCH_AGENT: "No such agent", + WALLET_OWNS_VOUCHERS: "Wallet address owns vouchers", + NOT_DISPUTE_RESOLVER_ASSISTANT: "Not dispute resolver's assistant address", + NO_SUCH_DISPUTE_RESOLVER: "No such dispute resolver", + INVALID_ESCALATION_PERIOD: "Invalid escalation period", + INEXISTENT_DISPUTE_RESOLVER_FEES: "Dispute resolver fees are not present", + DUPLICATE_DISPUTE_RESOLVER_FEES: "Duplicate dispute resolver fee", + DISPUTE_RESOLVER_FEE_NOT_FOUND: "Dispute resolver fee not found", + FEE_AMOUNT_NOT_YET_SUPPORTED: "Non-zero dispute resolver fees not yet supported", + INVALID_AUTH_TOKEN_TYPE: "Invalid AuthTokenType", + ADMIN_OR_AUTH_TOKEN: "An admin address or an auth token is required", + AUTH_TOKEN_MUST_BE_UNIQUE: "Auth token cannot be assigned to another entity of the same type", + SELLER_ALREADY_APPROVED: "Seller id is approved already", + SELLER_NOT_APPROVED: "Seller id is not approved", + INEXISTENT_ALLOWED_SELLERS_LIST: "Allowed sellers are not present", + INVALID_AGENT_FEE_PERCENTAGE: + "Sum of agent fee percentage and protocol fee percentage should be <= max fee percentage limit", + NO_PENDING_UPDATE_FOR_ACCOUNT: "No pending updates for the given account", + UNAUTHORIZED_CALLER_UPDATE: "Caller has no permission to approve this update", + NO_UPDATE_APPLIED: "No update applied or requested approval", + CLONE_CREATION_FAILED: "Clone creation failed", + SELLER_SALT_NOT_UNIQUE: "Seller salt not unique", + + // Twin related + NO_SUCH_TWIN: "No such twin", + NO_TRANSFER_APPROVED: "No transfer approved", + UNSUPPORTED_TOKEN: "Unsupported token", + BUNDLE_FOR_TWIN_EXISTS: "Bundle for twin exists", + INVALID_SUPPLY_AVAILABLE: "supplyAvailable can't be zero", + INVALID_AMOUNT: "Invalid twin amount", + INVALID_TWIN_PROPERTY: "Invalid property for selected token type", + INVALID_TWIN_TOKEN_RANGE: "Token range is already being used in another twin", + INVALID_TOKEN_ADDRESS: "Token address is a contract that doesn't implement the interface for selected token type", + + // Bundle related + NO_SUCH_BUNDLE: "No such bundle", + TWIN_NOT_IN_BUNDLE: "Twin not part of the bundle", + OFFER_NOT_IN_BUNDLE: "Offer not part of the bundle", + BUNDLE_OFFER_MUST_BE_UNIQUE: "Offer must be unique to a bundle", + BUNDLE_TWIN_MUST_BE_UNIQUE: "Twin must be unique to a bundle", + INSUFFICIENT_TWIN_SUPPLY_TO_COVER_BUNDLE_OFFERS: + "Insufficient twin supplyAvailable to cover total quantity of bundle offers", + BUNDLE_REQUIRES_AT_LEAST_ONE_TWIN_AND_ONE_OFFER: "Bundle must have at least one twin and one offer", + + // Exchange related + NO_SUCH_EXCHANGE: "No such exchange", + DISPUTE_PERIOD_NOT_ELAPSED: "Dispute period has not yet elapsed", + EXCHANGE_FOR_BUNDLED_OFFERS_EXISTS: "Exchange for the bundled offers exists", + VOUCHER_NOT_REDEEMABLE: "Voucher not yet valid or already expired", + VOUCHER_EXTENSION_NOT_VALID: "Proposed date is not later than the current one", + VOUCHER_STILL_VALID: "Voucher still valid", + VOUCHER_HAS_EXPIRED: "Voucher has expired", + EXCHANGE_IS_NOT_IN_A_FINAL_STATE: "Exchange is not in a final state", + INVALID_RANGE_LENGTH: "Range length is too large or zero", + EXCHANGE_ALREADY_EXISTS: "Exchange already exists", + + // Voucher related + EXCHANGE_ID_IN_RESERVED_RANGE: "Exchange id falls within a pre-minted offer's range", + NO_RESERVED_RANGE_FOR_OFFER: "Offer id not associated with a reserved range", + OFFER_RANGE_ALREADY_RESERVED: "Offer id already associated with a reserved range", + INVALID_RANGE_START: "Range start too low", + INVALID_AMOUNT_TO_MINT: "Amount to mint is greater than remaining un-minted in range", + NO_SILENT_MINT_ALLOWED: "Only owner's mappings can be updated without event", + OFFER_EXPIRED_OR_VOIDED: "Offer expired or voided", + OFFER_STILL_VALID: "Offer still valid", + AMOUNT_EXCEEDS_RANGE_OR_NOTHING_TO_BURN: "Amount exceeds the range or there is nothing to burn", + NOT_COMMITTABLE: "Token not committable", + INVALID_TO_ADDRESS: "Tokens can only be pre-mined to the contract or contract owner address", + EXTERNAL_CALL_FAILED: "External call failed", + INTERACTION_NOT_ALLOWED: "Interaction not allowed", + + // Funds related + NATIVE_WRONG_ADDRESS: "Native token address must be 0", + NATIVE_WRONG_AMOUNT: "Transferred value must match amount", + TOKEN_TRANSFER_FAILED: "Token transfer failed", + INSUFFICIENT_VALUE_RECEIVED: "Insufficient value received", + INSUFFICIENT_AVAILABLE_FUNDS: "Insufficient available funds", + NATIVE_NOT_ALLOWED: "Transfer of native currency not allowed", + TOKEN_AMOUNT_MISMATCH: "Number of amounts should match number of tokens", + NOTHING_TO_WITHDRAW: "Nothing to withdraw", + NOT_AUTHORIZED: "Not authorized to withdraw", + + // Outside the protocol revert reasons + ERC20_EXCEEDS_BALANCE: "ERC20: transfer amount exceeds balance", + ERC20_INSUFFICIENT_ALLOWANCE: "ERC20: insufficient allowance", + ERC20_PAUSED: "ERC20Pausable: token transfer while paused", + EOA_FUNCTION_CALL: "Transaction reverted: function call to a non-contract account", + EOA_FUNCTION_CALL_SAFE_ERC20: "Address: call to non-contract", + ERC721_INVALID_TOKEN_ID: "ERC721: invalid token ID", + ERC721_CALLER_NOT_OWNER_OR_APPROVED: "ERC721: caller is not token owner or approved", + OWNABLE_NOT_OWNER: "Ownable: caller is not the owner", + OWNABLE_ZERO_ADDRESS: "Ownable: new owner is the zero address", + SAFE_ERC20_LOW_LEVEL_CALL: "SafeERC20: low-level call failed", + SAFE_ERC20_OPERATION_FAILED: "SafeERC20: ERC20 operation did not succeed", + INITIALIZABLE_ALREADY_INITIALIZED: "Initializable: contract is already initialized", + + // Meta-Transactions related + NONCE_USED_ALREADY: "Nonce used already", + FUNCTION_CALL_NOT_SUCCESSFUL: "Function call not successful", + INVALID_SIGNATURE: "Invalid signature", + SIGNER_AND_SIGNATURE_DO_NOT_MATCH: "Signer and signature do not match", + INVALID_FUNCTION_NAME: "Invalid function name", + FUNCTION_NOT_ALLOWLISTED: "Function can not be executed via meta transaction", + + // Dispute related + DISPUTE_PERIOD_HAS_ELAPSED: "Dispute period has already elapsed", + DISPUTE_HAS_EXPIRED: "Dispute has expired", + INVALID_BUYER_PERCENT: "Invalid buyer percent", + DISPUTE_STILL_VALID: "Dispute still valid", + INVALID_DISPUTE_TIMEOUT: "Invalid dispute timeout", + ESCALATION_NOT_ALLOWED: "Disputes without dispute resolver cannot be escalated", + + // Config related + FEE_PERCENTAGE_INVALID: "Percentage representation must be less than 10000", + VALUE_ZERO_NOT_ALLOWED: "Value must be greater than 0", + + // ERC2981 related + ROYALTY_FEE_INVALID: "ERC2981: royalty fee exceeds protocol limit", + + // Diamond related + TOO_MANY_FUNCTIONS: "Too many functions on facet.", + ONLY_UPGRADER: "Caller must have UPGRADER role", + NO_SELECTORS_TO_CUT: "LibDiamondCut: No selectors in facet to cut", + FUNCTION_ALREADY_EXISTS: "LibDiamondCut: Can't add function that already exists", + REMOVING_FUNCTION_DOES_NOT_EXIST: "LibDiamondCut: Can't remove function that doesn't exist", + REMOVING_NON_ZERO_ADDRESS_FACET: "LibDiamondCut: Remove facet address must be address(0)", + REMOVING_IMMUTABLE_FUNCTION: "LibDiamondCut: Can't remove immutable function", + REPLACING_IMMUTABLE_FUNCTION: "LibDiamondCut: Can't replace immutable function", + REPLACING_WITH_SAME_FUNCTION: "LibDiamondCut: Can't replace function with same function", + REPLACING_FUNCTION_DOES_NOT_EXIST: "LibDiamondCut: Can't replace function that doesn't exist", + CONTRACT_NOT_ALLOWED: "Address cannot be a contract", + INIT_REVERTED: "LibDiamondCut: _init function reverted", + INIT_ZERO_ADDRESS_NON_EMPTY_CALLDATA: "LibDiamondCut: _init is address(0) but _calldata is not empty", + INIT_EMPTY_CALLDATA_NON_ZERO_ADDRESS: "LibDiamondCut: _calldata is empty but _init is not address(0)", + INIT_ADDRESS_WITH_NO_CODE: "LibDiamondCut: _init address has no code", +}; diff --git a/scripts/config/revert-reasons.js b/scripts/config/revert-reasons.js index e0e57d5f1..a753936d3 100644 --- a/scripts/config/revert-reasons.js +++ b/scripts/config/revert-reasons.js @@ -3,164 +3,155 @@ */ exports.RevertReasons = { // Access related - ACCESS_DENIED: "Access denied, caller doesn't have role", - NOT_BUYER_OR_SELLER: "Not buyer or seller", - NOT_VOUCHER_HOLDER: "Not current voucher holder", + ACCESS_DENIED: "AccessDenied", + NOT_BUYER_OR_SELLER: "NotBuyerOrSeller", + NOT_VOUCHER_HOLDER: "NotVoucherHolder", CAN_ONLY_REVOKE_SELF: "AccessControl: can only renounce roles for self", // Pause related - NOT_PAUSED: "Protocol is not currently paused", - REGION_PAUSED: "This region of the protocol is currently paused", - ZERO_DEPOSIT_NOT_ALLOWED: "Zero deposit not allowed", + NOT_PAUSED: "NotPaused", + REGION_PAUSED: "RegionPaused", // General - INVALID_ADDRESS: "Invalid address", - INVALID_STATE: "Invalid state", - ARRAY_LENGTH_MISMATCH: "Array length mismatch", - REENTRANCY_GUARD: "ReentrancyGuard: reentrant call", + INVALID_ADDRESS: "InvalidAddress", + INVALID_STATE: "InvalidState", + ARRAY_LENGTH_MISMATCH: "ArrayLengthMismatch", + REENTRANCY_GUARD: "ReentrancyGuard", // Facet initializer related - ALREADY_INITIALIZED: "Already initialized", - PROTOCOL_INITIALIZATION_FAILED: "Protocol initialization failed", - VERSION_MUST_BE_SET: "Version cannot be empty", - ADDRESSES_AND_CALLDATA_MUST_BE_SAME_LENGTH: "Addresses and calldata must be same length", - WRONG_CURRENT_VERSION: "Wrong current protocol version", - DIRECT_INITIALIZATION_NOT_ALLOWED: "Direct initializtion is not allowed", - TWINS_ALREADY_EXIST: "Should not have any twins yet", + ALREADY_INITIALIZED: "AlreadyInitialized", + PROTOCOL_INITIALIZATION_FAILED: "ProtocolInitializationFailed", + VERSION_MUST_BE_SET: "VersionMustBeSet", + ADDRESSES_AND_CALLDATA_LENGTH_MISMATCH: "AddressesAndCalldataLengthMismatch", + WRONG_CURRENT_VERSION: "WrongCurrentVersion", + DIRECT_INITIALIZATION_NOT_ALLOWED: "DirectInitializationNotAllowed", + TWINS_ALREADY_EXIST: "TwinsAlreadyExist", // Offer related - NOT_ASSISTANT: "Not seller's assistant", - NO_SUCH_OFFER: "No such offer", - OFFER_HAS_BEEN_VOIDED: "Offer has been voided", - OFFER_PERIOD_INVALID: "Offer period invalid", - OFFER_PENALTY_INVALID: "Offer penalty invalid", - OFFER_MUST_BE_ACTIVE: "Offer must be active", - OFFER_MUST_BE_UNIQUE: "Offer must be unique to a group", - CANNOT_COMMIT: "Caller cannot commit", - EXCHANGE_FOR_OFFER_EXISTS: "Exchange for offer exists", - AMBIGUOUS_VOUCHER_EXPIRY: "Exactly one of voucherRedeemableUntil and voucherValid must be non zero", - REDEMPTION_PERIOD_INVALID: "Redemption period invalid", - INVALID_DISPUTE_PERIOD: "Invalid dispute period", - INVALID_RESOLUTION_PERIOD: "Invalid resolution period", - INVALID_DISPUTE_RESOLVER: "Invalid dispute resolver", - INVALID_QUANTITY_AVAILABLE: "Invalid quantity available", - DR_UNSUPPORTED_FEE: "Dispute resolver does not accept this token", - AGENT_FEE_AMOUNT_TOO_HIGH: "Sum of agent fee amount and protocol fee amount should be <= offer fee limit", - OFFER_NOT_AVAILABLE: "Offer is not yet available", - OFFER_HAS_EXPIRED: "Offer has expired", - OFFER_SOLD_OUT: "Offer has sold out", - NO_SUCH_COLLECTION: "No such collection", + NOT_ASSISTANT: "NotAssistant", + NO_SUCH_OFFER: "NoSuchOffer", + OFFER_HAS_BEEN_VOIDED: "OfferHasBeenVoided", + OFFER_PERIOD_INVALID: "InvalidOfferPeriod", + OFFER_PENALTY_INVALID: "InvalidOfferPenalty", + OFFER_MUST_BE_ACTIVE: "OfferMustBeActive", + OFFER_MUST_BE_UNIQUE: "OfferMustBeUnique", + CANNOT_COMMIT: "CannotCommit", + EXCHANGE_FOR_OFFER_EXISTS: "ExchangeForOfferExists", + AMBIGUOUS_VOUCHER_EXPIRY: "AmbiguousVoucherExpiry", + REDEMPTION_PERIOD_INVALID: "InvalidRedemptionPeriod", + INVALID_DISPUTE_PERIOD: "InvalidDisputePeriod", + INVALID_RESOLUTION_PERIOD: "InvalidResolutionPeriod", + INVALID_DISPUTE_RESOLVER: "InvalidDisputeResolver", + INVALID_QUANTITY_AVAILABLE: "InvalidQuantityAvailable", + DR_UNSUPPORTED_FEE: "DRUnsupportedFee", + AGENT_FEE_AMOUNT_TOO_HIGH: "AgentFeeAmountTooHigh", + OFFER_NOT_AVAILABLE: "OfferNotAvailable", + OFFER_HAS_EXPIRED: "OfferHasExpired", + OFFER_SOLD_OUT: "OfferSoldOut", + NO_SUCH_COLLECTION: "NoSuchCollection", // Group related - NO_SUCH_GROUP: "No such group", - OFFER_NOT_IN_GROUP: "Offer not part of the group", - NOTHING_UPDATED: "Nothing updated", - INVALID_CONDITION_PARAMETERS: "Invalid condition parameters", - MAX_COMMITS_REACHED: "Max commits reached", - GROUP_HAS_NO_CONDITION: "Offer belongs to a group without a condition. Use commitToOffer instead", - GROUP_HAS_CONDITION: "Offer belongs to a group with a condition. Use commitToConditionalOffer instead", - TOKEN_ID_NOT_IN_CONDITION_RANGE: "Token id not in condition range", - INVALID_TOKEN_ID: "ERC721 and ERC20 require zero tokenId", + NO_SUCH_GROUP: "NoSuchGroup", + OFFER_NOT_IN_GROUP: "OfferNotInGroup", + NOTHING_UPDATED: "NothingUpdated", + INVALID_CONDITION_PARAMETERS: "InvalidConditionParameters", + MAX_COMMITS_REACHED: "MaxCommitsReached", + GROUP_HAS_NO_CONDITION: "GroupHasNoCondition", + GROUP_HAS_CONDITION: "GroupHasCondition", + TOKEN_ID_NOT_IN_CONDITION_RANGE: "TokenIdNotInConditionRange", + INVALID_TOKEN_ID: "InvalidTokenId", // Account-related - MUST_BE_ACTIVE: "Account must be active", - NO_SUCH_SELLER: "No such seller", - SELLER_ADDRESS_MUST_BE_UNIQUE: "Seller address cannot be assigned to another seller Id", - BUYER_ADDRESS_MUST_BE_UNIQUE: "Buyer address cannot be assigned to another buyer Id", - DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE: "Dispute resolver address cannot be assigned to another dispute resolver Id", - AGENT_ADDRESS_MUST_BE_UNIQUE: "Agent address cannot be assigned to another agent Id", - NOT_ADMIN: "Not admin", - CLERK_DEPRECATED: "Clerk is deprecated and must be set to address 0", - NOT_ADMIN_AND_ASSISTANT: "Not admin and assistant", - NOT_BUYER_WALLET: "Not buyer's wallet address", - NOT_AGENT_WALLET: "Not agent's wallet address", - NO_SUCH_BUYER: "No such buyer", - NO_SUCH_AGENT: "No such agent", - WALLET_OWNS_VOUCHERS: "Wallet address owns vouchers", - NOT_DISPUTE_RESOLVER_ASSISTANT: "Not dispute resolver's assistant address", - NO_SUCH_DISPUTE_RESOLVER: "No such dispute resolver", - INVALID_ESCALATION_PERIOD: "Invalid escalation period", - INEXISTENT_DISPUTE_RESOLVER_FEES: "Dispute resolver fees are not present", - DUPLICATE_DISPUTE_RESOLVER_FEES: "Duplicate dispute resolver fee", - DISPUTE_RESOLVER_FEE_NOT_FOUND: "Dispute resolver fee not found", - FEE_AMOUNT_NOT_YET_SUPPORTED: "Non-zero dispute resolver fees not yet supported", - INVALID_AUTH_TOKEN_TYPE: "Invalid AuthTokenType", - ADMIN_OR_AUTH_TOKEN: "An admin address or an auth token is required", - AUTH_TOKEN_MUST_BE_UNIQUE: "Auth token cannot be assigned to another entity of the same type", - SELLER_ALREADY_APPROVED: "Seller id is approved already", - SELLER_NOT_APPROVED: "Seller id is not approved", - INEXISTENT_ALLOWED_SELLERS_LIST: "Allowed sellers are not present", - INVALID_AGENT_FEE_PERCENTAGE: - "Sum of agent fee percentage and protocol fee percentage should be <= max fee percentage limit", - NO_PENDING_UPDATE_FOR_ACCOUNT: "No pending updates for the given account", - UNAUTHORIZED_CALLER_UPDATE: "Caller has no permission to approve this update", - NO_UPDATE_APPLIED: "No update applied or requested approval", - CLONE_CREATION_FAILED: "Clone creation failed", - SELLER_SALT_NOT_UNIQUE: "Seller salt not unique", + MUST_BE_ACTIVE: "MustBeActive", + NO_SUCH_SELLER: "NoSuchSeller", + SELLER_ADDRESS_MUST_BE_UNIQUE: "SellerAddressMustBeUnique", + BUYER_ADDRESS_MUST_BE_UNIQUE: "BuyerAddressMustBeUnique", + DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE: "DisputeResolverAddressMustBeUnique", + AGENT_ADDRESS_MUST_BE_UNIQUE: "AgentAddressMustBeUnique", + NOT_ADMIN: "NotAdmin", + CLERK_DEPRECATED: "ClerkDeprecated", + NOT_ADMIN_AND_ASSISTANT: "NotAdminAndAssistant", + NOT_BUYER_WALLET: "NotBuyerWallet", + NOT_AGENT_WALLET: "NotAgentWallet", + NO_SUCH_BUYER: "NoSuchBuyer", + NO_SUCH_AGENT: "NoSuchAgent", + WALLET_OWNS_VOUCHERS: "WalletOwnsVouchers", + NOT_DISPUTE_RESOLVER_ASSISTANT: "NotDisputeResolverAssistant", + NO_SUCH_DISPUTE_RESOLVER: "NoSuchDisputeResolver", + INVALID_ESCALATION_PERIOD: "InvalidEscalationPeriod", + INEXISTENT_DISPUTE_RESOLVER_FEES: "InexistentDisputeResolverFees", + DUPLICATE_DISPUTE_RESOLVER_FEES: "DuplicateDisputeResolverFees", + DISPUTE_RESOLVER_FEE_NOT_FOUND: "DisputeResolverFeeNotFound", + FEE_AMOUNT_NOT_YET_SUPPORTED: "FeeAmountNotYetSupported", + INVALID_AUTH_TOKEN_TYPE: "InvalidAuthTokenType", + ADMIN_OR_AUTH_TOKEN: "AdminOrAuthToken", + AUTH_TOKEN_MUST_BE_UNIQUE: "AuthTokenMustBeUnique", + SELLER_ALREADY_APPROVED: "SellerAlreadyApproved", + SELLER_NOT_APPROVED: "SellerNotApproved", + INEXISTENT_ALLOWED_SELLERS_LIST: "InexistentAllowedSellersList", + INVALID_AGENT_FEE_PERCENTAGE: "InvalidAgentFeePercentage", + NO_PENDING_UPDATE_FOR_ACCOUNT: "NoPendingUpdateForAccount", + UNAUTHORIZED_CALLER_UPDATE: "UnauthorizedCallerUpdate", + NO_UPDATE_APPLIED: "NoUpdateApplied", + CLONE_CREATION_FAILED: "CloneCreationFailed", + SELLER_SALT_NOT_UNIQUE: "SellerSaltNotUnique", // Twin related - NO_SUCH_TWIN: "No such twin", - NO_TRANSFER_APPROVED: "No transfer approved", - UNSUPPORTED_TOKEN: "Unsupported token", - BUNDLE_FOR_TWIN_EXISTS: "Bundle for twin exists", - INVALID_SUPPLY_AVAILABLE: "supplyAvailable can't be zero", - INVALID_AMOUNT: "Invalid twin amount", - INVALID_TWIN_PROPERTY: "Invalid property for selected token type", - INVALID_TWIN_TOKEN_RANGE: "Token range is already being used in another twin", - INVALID_TOKEN_ADDRESS: "Token address is a contract that doesn't implement the interface for selected token type", + NO_SUCH_TWIN: "NoSuchTwin", + NO_TRANSFER_APPROVED: "NoTransferApproved", + UNSUPPORTED_TOKEN: "UnsupportedToken", + BUNDLE_FOR_TWIN_EXISTS: "BundleForTwinExists", + INVALID_SUPPLY_AVAILABLE: "InvalidSupplyAvailable", + INVALID_AMOUNT: "InvalidAmount", + INVALID_TWIN_PROPERTY: "InvalidTwinProperty", + INVALID_TWIN_TOKEN_RANGE: "InvalidTwinTokenRange", + INVALID_TOKEN_ADDRESS: "InvalidTokenAddress", // Bundle related - NO_SUCH_BUNDLE: "No such bundle", - TWIN_NOT_IN_BUNDLE: "Twin not part of the bundle", - OFFER_NOT_IN_BUNDLE: "Offer not part of the bundle", - BUNDLE_OFFER_MUST_BE_UNIQUE: "Offer must be unique to a bundle", - BUNDLE_TWIN_MUST_BE_UNIQUE: "Twin must be unique to a bundle", - INSUFFICIENT_TWIN_SUPPLY_TO_COVER_BUNDLE_OFFERS: - "Insufficient twin supplyAvailable to cover total quantity of bundle offers", - BUNDLE_REQUIRES_AT_LEAST_ONE_TWIN_AND_ONE_OFFER: "Bundle must have at least one twin and one offer", + NO_SUCH_BUNDLE: "NoSuchBundle", + TWIN_NOT_IN_BUNDLE: "TwinsNotInBundle", + OFFER_NOT_IN_BUNDLE: "OfferNotInBundle", + BUNDLE_OFFER_MUST_BE_UNIQUE: "BundleOfferMustBeUnique", + BUNDLE_TWIN_MUST_BE_UNIQUE: "BundleTwinMustBeUnique", + INSUFFICIENT_TWIN_SUPPLY_TO_COVER_BUNDLE_OFFERS: "InsufficientTwinSupplyToCoverBundleOffers", + BUNDLE_REQUIRES_AT_LEAST_ONE_TWIN_AND_ONE_OFFER: "BundleRequiresAtLeastOneTwinAndOneOffer", // Exchange related - NO_SUCH_EXCHANGE: "No such exchange", - DISPUTE_PERIOD_NOT_ELAPSED: "Dispute period has not yet elapsed", - EXCHANGE_FOR_BUNDLED_OFFERS_EXISTS: "Exchange for the bundled offers exists", - VOUCHER_NOT_REDEEMABLE: "Voucher not yet valid or already expired", - VOUCHER_EXTENSION_NOT_VALID: "Proposed date is not later than the current one", - VOUCHER_STILL_VALID: "Voucher still valid", - VOUCHER_HAS_EXPIRED: "Voucher has expired", - EXCHANGE_IS_NOT_IN_A_FINAL_STATE: "Exchange is not in a final state", - INVALID_RANGE_LENGTH: "Range length is too large or zero", - EXCHANGE_ALREADY_EXISTS: "Exchange already exists", - - // Sequential commit related - UNEXPECTED_ERC721_RECEIVED: "Unexpected ERC721 received", - FEE_AMOUNT_TOO_HIGH: "Fee amount is too high", - VOUCHER_NOT_RECEIVED: "Voucher not received", + NO_SUCH_EXCHANGE: "NoSuchExchange", + DISPUTE_PERIOD_NOT_ELAPSED: "DisputePeriodNotElapsed", + VOUCHER_NOT_REDEEMABLE: "VoucherNotRedeemable", + VOUCHER_EXTENSION_NOT_VALID: "VoucherExtensionNotValid", + VOUCHER_STILL_VALID: "VoucherStillValid", + VOUCHER_HAS_EXPIRED: "VoucherHasExpired", + EXCHANGE_IS_NOT_IN_A_FINAL_STATE: "ExchangeIsNotInAFinalState", + INVALID_RANGE_LENGTH: "InvalidRangeLength", + EXCHANGE_ALREADY_EXISTS: "ExchangeAlreadyExists", // Voucher related - EXCHANGE_ID_IN_RESERVED_RANGE: "Exchange id falls within a pre-minted offer's range", - NO_RESERVED_RANGE_FOR_OFFER: "Offer id not associated with a reserved range", - OFFER_RANGE_ALREADY_RESERVED: "Offer id already associated with a reserved range", - INVALID_RANGE_START: "Range start too low", - INVALID_AMOUNT_TO_MINT: "Amount to mint is greater than remaining un-minted in range", - NO_SILENT_MINT_ALLOWED: "Only owner's mappings can be updated without event", - OFFER_EXPIRED_OR_VOIDED: "Offer expired or voided", - OFFER_STILL_VALID: "Offer still valid", - AMOUNT_EXCEEDS_RANGE_OR_NOTHING_TO_BURN: "Amount exceeds the range or there is nothing to burn", - NOT_COMMITTABLE: "Token not committable", - INVALID_TO_ADDRESS: "Tokens can only be pre-mined to the contract or contract owner address", - EXTERNAL_CALL_FAILED: "External call failed", - INTERACTION_NOT_ALLOWED: "Interaction not allowed", + EXCHANGE_ID_IN_RESERVED_RANGE: "ExchangeIdInReservedRange", + NO_RESERVED_RANGE_FOR_OFFER: "NoReservedRangeForOffer", + OFFER_RANGE_ALREADY_RESERVED: "OfferRangeAlreadyReserved", + INVALID_RANGE_START: "InvalidRangeStart", + INVALID_AMOUNT_TO_MINT: "InvalidAmountToMint", + NO_SILENT_MINT_ALLOWED: "NoSilentMintAllowed", + OFFER_EXPIRED_OR_VOIDED: "OfferExpiredOrVoided", + OFFER_STILL_VALID: "OfferStillValid", + AMOUNT_EXCEEDS_RANGE_OR_NOTHING_TO_BURN: "AmountExceedsRangeOrNothingToBurn", + INVALID_TO_ADDRESS: "InvalidToAddress", + EXTERNAL_CALL_FAILED: "ExternalCallFailed", + INTERACTION_NOT_ALLOWED: "InteractionNotAllowed", // Funds related - NATIVE_WRONG_ADDRESS: "Native token address must be 0", - NATIVE_WRONG_AMOUNT: "Transferred value must match amount", - TOKEN_TRANSFER_FAILED: "Token transfer failed", - INSUFFICIENT_VALUE_RECEIVED: "Insufficient value received", - INSUFFICIENT_AVAILABLE_FUNDS: "Insufficient available funds", - NATIVE_NOT_ALLOWED: "Transfer of native currency not allowed", - TOKEN_AMOUNT_MISMATCH: "Number of amounts should match number of tokens", - NOTHING_TO_WITHDRAW: "Nothing to withdraw", - NOT_AUTHORIZED: "Not authorized to withdraw", + NATIVE_WRONG_ADDRESS: "NativeWrongAddress", + NATIVE_WRONG_AMOUNT: "NativeWrongAmount", + TOKEN_TRANSFER_FAILED: "TokenTransferFailed", + INSUFFICIENT_VALUE_RECEIVED: "InsufficientValueReceived", + INSUFFICIENT_AVAILABLE_FUNDS: "InsufficientAvailableFunds", + NATIVE_NOT_ALLOWED: "NativeNotAllowed", + TOKEN_AMOUNT_MISMATCH: "TokenAmountMismatch", + NOTHING_TO_WITHDRAW: "NothingToWithdraw", + NOT_AUTHORIZED: "NotAuthorized", + ZERO_DEPOSIT_NOT_ALLOWED: "ZeroDepositNotAllowed", // Outside the protocol revert reasons ERC20_EXCEEDS_BALANCE: "ERC20: transfer amount exceeds balance", @@ -177,27 +168,27 @@ exports.RevertReasons = { INITIALIZABLE_ALREADY_INITIALIZED: "Initializable: contract is already initialized", // Meta-Transactions related - NONCE_USED_ALREADY: "Nonce used already", + NONCE_USED_ALREADY: "NonceUsedAlready", FUNCTION_CALL_NOT_SUCCESSFUL: "Function call not successful", - INVALID_SIGNATURE: "Invalid signature", - SIGNER_AND_SIGNATURE_DO_NOT_MATCH: "Signer and signature do not match", - INVALID_FUNCTION_NAME: "Invalid function name", - FUNCTION_NOT_ALLOWLISTED: "Function can not be executed via meta transaction", + INVALID_SIGNATURE: "InvalidSignature", + SIGNER_AND_SIGNATURE_DO_NOT_MATCH: "SignerAndSignatureDoNotMatch", + INVALID_FUNCTION_NAME: "InvalidFunctionName", + FUNCTION_NOT_ALLOWLISTED: "FunctionNotAllowlisted", // Dispute related - DISPUTE_PERIOD_HAS_ELAPSED: "Dispute period has already elapsed", - DISPUTE_HAS_EXPIRED: "Dispute has expired", - INVALID_BUYER_PERCENT: "Invalid buyer percent", - DISPUTE_STILL_VALID: "Dispute still valid", - INVALID_DISPUTE_TIMEOUT: "Invalid dispute timeout", - ESCALATION_NOT_ALLOWED: "Disputes without dispute resolver cannot be escalated", + DISPUTE_PERIOD_HAS_ELAPSED: "DisputePeriodHasElapsed", + DISPUTE_HAS_EXPIRED: "DisputeHasExpired", + INVALID_BUYER_PERCENT: "InvalidBuyerPercent", + DISPUTE_STILL_VALID: "DisputeStillValid", + INVALID_DISPUTE_TIMEOUT: "InvalidDisputeTimeout", + ESCALATION_NOT_ALLOWED: "EscalationNotAllowed", // Config related - FEE_PERCENTAGE_INVALID: "Percentage representation must be less than 10000", - VALUE_ZERO_NOT_ALLOWED: "Value must be greater than 0", + FEE_PERCENTAGE_INVALID: "InvalidFeePercentage", + VALUE_ZERO_NOT_ALLOWED: "ValueZeroNotAllowed", // ERC2981 related - ROYALTY_FEE_INVALID: "ERC2981: royalty fee exceeds protocol limit", + ROYALTY_FEE_INVALID: "InvalidRoyaltyFee", // Diamond related TOO_MANY_FUNCTIONS: "Too many functions on facet.", @@ -217,8 +208,12 @@ exports.RevertReasons = { INIT_ADDRESS_WITH_NO_CODE: "LibDiamondCut: _init address has no code", // Price discovery related - PRICE_TOO_HIGH: "Price discovery returned a price that is too high", - PRICE_TOO_LOW: "Price discovery returned a price that is too low", - TOKEN_ID_MISMATCH: "Token id mismatch", - VOUCHER_TRANSFER_NOT_ALLOWED: "Voucher transfer not allowed", + PRICE_TOO_LOW: "PriceTooLow", + TOKEN_ID_MISMATCH: "TokenIdMismatch", + VOUCHER_TRANSFER_NOT_ALLOWED: "VoucherTransferNotAllowed", + VOUCHER_NOT_RECEIVED: "VoucherNotReceived", + UNEXPECTED_ERC721_RECEIVED: "UnexpectedERC721Received", + FEE_AMOUNT_TOO_HIGH: "FeeAmountTooHigh", + INVALID_PRICE_DISCOVERY: "InvalidPriceDiscovery", + INVALID_CONDUIT_ADDRESS: "InvalidConduitAddress", }; diff --git a/test/example/SnapshotGateTest.js b/test/example/SnapshotGateTest.js index 8d510a900..6bc1467f3 100644 --- a/test/example/SnapshotGateTest.js +++ b/test/example/SnapshotGateTest.js @@ -62,6 +62,7 @@ describe("SnapshotGate", function () { let offer, offers, otherSellerOfferId; let offerDates, offerDurations; let snapshot, snapshotTokenSupplies, snapshotTokenCount, holders, holderByAddress; + let bosonErrors; beforeEach(async function () { // Reset the accountId iterator @@ -177,6 +178,8 @@ describe("SnapshotGate", function () { // Cast Diamond to IBosonExchangeHandler exchangeHandler = await getContractAt("IBosonExchangeHandler", await protocolDiamond.getAddress()); + bosonErrors = await getContractAt("BosonErrors", await protocolDiamond.getAddress()); + accountId.next(true); // Deploy the SnapshotGate example @@ -716,7 +719,7 @@ describe("SnapshotGate", function () { // Commit to the offer await expect( snapshotGate.connect(holder).commitToGatedOffer(entry.owner, offerId, entry.tokenId, { value: price }) - ).to.revertedWith(RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); }); it("offer is from another seller", async function () { @@ -920,7 +923,7 @@ describe("SnapshotGate", function () { // Check that holder cannot commit directly to the offer on the protocol itself await expect( exchangeHandler.connect(holder).commitToConditionalOffer(await holder.getAddress(), offerId, entry.tokenId) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); }); }); diff --git a/test/integration/01-update-account-roles-addresses.js b/test/integration/01-update-account-roles-addresses.js index 9722a9c48..d885206a3 100644 --- a/test/integration/01-update-account-roles-addresses.js +++ b/test/integration/01-update-account-roles-addresses.js @@ -1,5 +1,5 @@ const { ethers } = require("hardhat"); -const { ZeroAddress, provider } = ethers; +const { ZeroAddress, provider, getContractAt } = ethers; const { expect } = require("chai"); const { @@ -37,6 +37,7 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { let buyerEscalationDepositPercentage, redeemedDate; let snapshotId; let beaconProxyAddress; + let bosonErrors; before(async function () { accountId.next(true); @@ -58,6 +59,8 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { protocolConfig: [, , { buyerEscalationDepositPercentage }], } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", await accountHandler.getAddress()); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -269,7 +272,7 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { // Attempt to withdraw funds with old buyer wallet, should fail await expect( fundsHandler.connect(buyer).withdrawFunds(buyerAccount.id, [ZeroAddress], [buyerPayoff]) - ).to.revertedWith(RevertReasons.NOT_AUTHORIZED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_AUTHORIZED); // Attempt to withdraw funds with new buyer wallet, should succeed await expect(fundsHandler.connect(rando).withdrawFunds(buyerAccount.id, [ZeroAddress], [buyerPayoff])) @@ -304,7 +307,7 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { // Attempt to withdraw funds with old seller assistant, should fail await expect( fundsHandler.connect(assistant).withdrawFunds(seller.id, [ZeroAddress], [sellerPayoff]) - ).to.revertedWith(RevertReasons.NOT_AUTHORIZED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_AUTHORIZED); // Attempt to withdraw funds with new seller assistant, should succeed await expect(fundsHandler.connect(rando).withdrawFunds(seller.id, [ZeroAddress], [sellerPayoff])) @@ -338,7 +341,7 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { // Attempt to withdraw funds with old agent wallet, should fail await expect( fundsHandler.connect(agent).withdrawFunds(agentAccount.id, [ZeroAddress], [agentPayoff]) - ).to.revertedWith(RevertReasons.NOT_AUTHORIZED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_AUTHORIZED); // Attempt to withdraw funds with new agent wallet, should fail await expect(fundsHandler.connect(rando).withdrawFunds(agentAccount.id, [ZeroAddress], [agentPayoff])) @@ -356,7 +359,8 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { .withArgs(buyerAccount.id, buyerAccount.toStruct(), await buyer.getAddress()); // Attempt to raise a dispute with old buyer wallet, should fail - await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER ); @@ -448,7 +452,7 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { // Attempt to resolve a dispute with old seller assistant, should fail await expect( disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercent, r, s, v) - ).to.revertedWith(RevertReasons.NOT_BUYER_OR_SELLER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_BUYER_OR_SELLER); // Attempt to resolve a dispute with new seller assistant, should succeed await expect(disputeHandler.connect(rando).resolveDispute(exchangeId, buyerPercent, r, s, v)) @@ -475,9 +479,9 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { ); // Attempt to resolve a dispute with old buyer wallet, should fail - await expect(disputeHandler.connect(buyer).resolveDispute(exchangeId, buyerPercent, r, s, v)).to.revertedWith( - RevertReasons.NOT_BUYER_OR_SELLER - ); + await expect( + disputeHandler.connect(buyer).resolveDispute(exchangeId, buyerPercent, r, s, v) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_BUYER_OR_SELLER); // Attempt to resolve a dispute with new buyer wallet, should succeed await expect(disputeHandler.connect(rando).resolveDispute(exchangeId, buyerPercent, r, s, v)) @@ -506,7 +510,7 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { // Attempt to resolve a dispute with old buyer wallet, should fail await expect( disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercent, r, s, v) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); it("If the seller assistant address was changed, the buyer should not be able to resolve a dispute with the old signature", async function () { @@ -543,9 +547,9 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { ); // Attempt to resolve a dispute with old buyer wallet, should fail - await expect(disputeHandler.connect(buyer).resolveDispute(exchangeId, buyerPercent, r, s, v)).to.revertedWith( - RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH - ); + await expect( + disputeHandler.connect(buyer).resolveDispute(exchangeId, buyerPercent, r, s, v) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); it("Buyer should be able to retract dispute after updating wallet address", async function () { @@ -558,7 +562,8 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { .withArgs(buyerAccount.id, buyerAccount.toStruct(), await buyer.getAddress()); // Attempt to retract a dispute with old buyer, should fail - await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.be.revertedWith( + await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER ); @@ -592,9 +597,9 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { const buyerPercent = "1234"; // Attempt to decide a dispute with old dispute resolver assistant, should fail - await expect(disputeHandler.connect(assistantDR).decideDispute(exchangeId, buyerPercent)).to.revertedWith( - RevertReasons.NOT_DISPUTE_RESOLVER_ASSISTANT - ); + await expect( + disputeHandler.connect(assistantDR).decideDispute(exchangeId, buyerPercent) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_DISPUTE_RESOLVER_ASSISTANT); // Attempt to decide a dispute with new dispute resolver assistant, should fail await expect(disputeHandler.connect(rando).decideDispute(exchangeId, buyerPercent)) @@ -604,9 +609,9 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { it("Dispute resolver should be able to refuse to decide a dispute after change the assistant address", async function () { // Attempt to refuse to decide a dispute with old dispute resolver assistant, should fail - await expect(disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId)).to.revertedWith( - RevertReasons.NOT_DISPUTE_RESOLVER_ASSISTANT - ); + await expect( + disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_DISPUTE_RESOLVER_ASSISTANT); // Attempt to refuse a dispute with new dispute resolver assistant, should fail await expect(disputeHandler.connect(rando).refuseEscalatedDispute(exchangeId)) diff --git a/test/integration/02-Upgraded-facet.js b/test/integration/02-Upgraded-facet.js index 4f72735dc..4fe841a8e 100644 --- a/test/integration/02-Upgraded-facet.js +++ b/test/integration/02-Upgraded-facet.js @@ -50,6 +50,7 @@ describe("[@skip-on-coverage] After facet upgrade, everything is still operation let customSignatureType, message; let protocolDiamondAddress; let snapshotId; + let bosonErrors; before(async function () { accountId.next(true); @@ -70,6 +71,8 @@ describe("[@skip-on-coverage] After facet upgrade, everything is still operation diamondAddress: protocolDiamondAddress, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", protocolDiamondAddress); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -854,12 +857,12 @@ describe("[@skip-on-coverage] After facet upgrade, everything is still operation // Attempt to withdraw the funds, expecting revert await expect( fundsHandler.connect(assistant).withdrawFunds(seller.id, tokenListSeller, tokenAmountsSeller) - ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); // buyer withdrawal await expect( fundsHandler.connect(buyer).withdrawFunds(buyerId, tokenListBuyer, tokenAmountsBuyer) - ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); }); }); }); diff --git a/test/protocol/AgentHandlerTest.js b/test/protocol/AgentHandlerTest.js index 1aed229dd..b6457c224 100644 --- a/test/protocol/AgentHandlerTest.js +++ b/test/protocol/AgentHandlerTest.js @@ -1,5 +1,5 @@ const { ethers } = require("hardhat"); -const { ZeroAddress } = ethers; +const { ZeroAddress, getContractAt } = ethers; const { expect } = require("chai"); const Agent = require("../../scripts/domain/Agent"); @@ -21,6 +21,7 @@ describe("AgentHandler", function () { let nextAccountId; let invalidAccountId, id, id2, key, value, exists; let snapshotId; + let bosonErrors; before(async function () { // Specify contracts needed for this test @@ -34,6 +35,8 @@ describe("AgentHandler", function () { contractInstances: { accountHandler, pauseHandler }, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", await accountHandler.getAddress()); + // Get snapshot id snapshotId = await getSnapshot(); }); @@ -161,21 +164,30 @@ describe("AgentHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Agents]); // Attempt to create an agent, expecting revert - await expect(accountHandler.connect(rando).createAgent(agent)).to.revertedWith(RevertReasons.REGION_PAUSED); + await expect(accountHandler.connect(rando).createAgent(agent)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.REGION_PAUSED + ); }); it("active is false", async function () { agent.active = false; // Attempt to Create an Agent, expecting revert - await expect(accountHandler.connect(rando).createAgent(agent)).to.revertedWith(RevertReasons.MUST_BE_ACTIVE); + await expect(accountHandler.connect(rando).createAgent(agent)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.MUST_BE_ACTIVE + ); }); it("addresses are the zero address", async function () { agent.wallet = ZeroAddress; // Attempt to Create an Agent, expecting revert - await expect(accountHandler.connect(rando).createAgent(agent)).to.revertedWith(RevertReasons.INVALID_ADDRESS); + await expect(accountHandler.connect(rando).createAgent(agent)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.INVALID_ADDRESS + ); }); it("wallet address is not unique to this agentId", async function () { @@ -183,7 +195,8 @@ describe("AgentHandler", function () { await accountHandler.connect(rando).createAgent(agent); // Attempt to create another buyer with same wallet address - await expect(accountHandler.connect(rando).createAgent(agent)).to.revertedWith( + await expect(accountHandler.connect(rando).createAgent(agent)).to.revertedWithCustomError( + bosonErrors, RevertReasons.AGENT_ADDRESS_MUST_BE_UNIQUE ); }); @@ -195,7 +208,8 @@ describe("AgentHandler", function () { expect(agent.isValid()).is.true; // Attempt to create another buyer with same wallet address - await expect(accountHandler.connect(rando).createAgent(agent)).to.revertedWith( + await expect(accountHandler.connect(rando).createAgent(agent)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_AGENT_FEE_PERCENTAGE ); }); @@ -383,7 +397,10 @@ describe("AgentHandler", function () { .withArgs(agent.id, agentStruct, await other2.getAddress()); // Attempt to update the agent with original wallet address, expecting revert - await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWith(RevertReasons.NOT_AGENT_WALLET); + await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NOT_AGENT_WALLET + ); }); it("should allow feePercentage of 0", async function () { @@ -438,7 +455,10 @@ describe("AgentHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Agents]); // Attempt to update an agent, expecting revert - await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWith(RevertReasons.REGION_PAUSED); + await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.REGION_PAUSED + ); }); it("Agent does not exist", async function () { @@ -446,18 +466,25 @@ describe("AgentHandler", function () { agent.id = "444"; // Attempt to update the agent, expecting revert - await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWith(RevertReasons.NO_SUCH_AGENT); + await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NO_SUCH_AGENT + ); // Set invalid id agent.id = "0"; // Attempt to update the agent, expecting revert - await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWith(RevertReasons.NO_SUCH_AGENT); + await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NO_SUCH_AGENT + ); }); it("Caller is not agent wallet address", async function () { // Attempt to update the agent, expecting revert - await expect(accountHandler.connect(other2).updateAgent(agent)).to.revertedWith( + await expect(accountHandler.connect(other2).updateAgent(agent)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_AGENT_WALLET ); }); @@ -466,7 +493,8 @@ describe("AgentHandler", function () { agent.wallet = ZeroAddress; // Attempt to update the agent, expecting revert - await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWith( + await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ADDRESS ); }); @@ -478,7 +506,8 @@ describe("AgentHandler", function () { expect(agent.isValid()).is.true; // Attempt to update the agent, expecting revert - await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWith( + await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_AGENT_FEE_PERCENTAGE ); }); @@ -500,7 +529,8 @@ describe("AgentHandler", function () { agent2.wallet = await other1.getAddress(); //already being used by agent 1 // Attempt to update agent 2 with non-unique wallet address, expecting revert - await expect(accountHandler.connect(other2).updateAgent(agent2)).to.revertedWith( + await expect(accountHandler.connect(other2).updateAgent(agent2)).to.revertedWithCustomError( + bosonErrors, RevertReasons.AGENT_ADDRESS_MUST_BE_UNIQUE ); }); diff --git a/test/protocol/BundleHandlerTest.js b/test/protocol/BundleHandlerTest.js index 2d4980726..0fdb71c85 100644 --- a/test/protocol/BundleHandlerTest.js +++ b/test/protocol/BundleHandlerTest.js @@ -1,5 +1,5 @@ const { ethers } = require("hardhat"); -const { ZeroAddress, getContractFactory, MaxUint256 } = ethers; +const { ZeroAddress, getContractFactory, MaxUint256, getContractAt } = ethers; const { expect, assert } = require("chai"); const Bundle = require("../../scripts/domain/Bundle"); @@ -52,6 +52,7 @@ describe("IBosonBundleHandler", function () { let emptyAuthToken; let agentId; let snapshotId; + let bosonErrors; before(async function () { // get interface Ids @@ -93,6 +94,8 @@ describe("IBosonBundleHandler", function () { }, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", await accountHandler.getAddress()); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -326,7 +329,8 @@ describe("IBosonBundleHandler", function () { bundle.offerIds = [...bundle.offerIds, newOfferId, newOfferId2]; bundle.twinIds = ["6"]; - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INSUFFICIENT_TWIN_SUPPLY_TO_COVER_BUNDLE_OFFERS ); @@ -351,21 +355,26 @@ describe("IBosonBundleHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Bundles]); // Attempt to create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); it("Caller not assistant of any seller", async function () { // Attempt to Create a bundle, expecting revert - await expect(bundleHandler.connect(rando).createBundle(bundle)).to.revertedWith(RevertReasons.NOT_ASSISTANT); + await expect(bundleHandler.connect(rando).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NOT_ASSISTANT + ); }); it("Bundle has no offers", async function () { bundle.offerIds = []; // Attempt to Create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.BUNDLE_REQUIRES_AT_LEAST_ONE_TWIN_AND_ONE_OFFER ); }); @@ -374,7 +383,8 @@ describe("IBosonBundleHandler", function () { bundle.twinIds = []; // Attempt to Create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.BUNDLE_REQUIRES_AT_LEAST_ONE_TWIN_AND_ONE_OFFER ); }); @@ -384,7 +394,8 @@ describe("IBosonBundleHandler", function () { bundle.offerIds = []; // Attempt to Create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.BUNDLE_REQUIRES_AT_LEAST_ONE_TWIN_AND_ONE_OFFER ); }); @@ -411,7 +422,8 @@ describe("IBosonBundleHandler", function () { bundle.offerIds = ["2", "6"]; // Attempt to create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ASSISTANT ); }); @@ -421,7 +433,8 @@ describe("IBosonBundleHandler", function () { bundle.offerIds = ["1", "999"]; // Attempt to create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_OFFER ); @@ -429,7 +442,8 @@ describe("IBosonBundleHandler", function () { bundle.offerIds = ["0", "4"]; // Attempt to create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_OFFER ); }); @@ -455,7 +469,8 @@ describe("IBosonBundleHandler", function () { bundle.twinIds = ["2", "6"]; // Attempt to create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ASSISTANT ); }); @@ -465,7 +480,8 @@ describe("IBosonBundleHandler", function () { bundle.twinIds = ["1", "999"]; // Attempt to create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_TWIN ); @@ -473,7 +489,8 @@ describe("IBosonBundleHandler", function () { bundle.twinIds = ["0", "4"]; // Attempt to create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_TWIN ); }); @@ -486,7 +503,8 @@ describe("IBosonBundleHandler", function () { bundle.offerIds = ["1", "2", "4"]; // Attempt to create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.BUNDLE_OFFER_MUST_BE_UNIQUE ); }); @@ -496,7 +514,8 @@ describe("IBosonBundleHandler", function () { bundle.offerIds = ["1", "1", "4"]; // Attempt to create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.BUNDLE_OFFER_MUST_BE_UNIQUE ); }); @@ -506,7 +525,8 @@ describe("IBosonBundleHandler", function () { bundle.twinIds = ["1", "1", "4"]; // Attempt to create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.BUNDLE_TWIN_MUST_BE_UNIQUE ); }); @@ -524,7 +544,8 @@ describe("IBosonBundleHandler", function () { .commitToOffer(await buyer.getAddress(), offerIdToCommit, { value: price }); // Attempt to Create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.EXCHANGE_FOR_OFFER_EXISTS ); }); @@ -543,7 +564,8 @@ describe("IBosonBundleHandler", function () { expectedBundle.id = expectedNextBundleId; // Attempt to Create a bundle, expecting revert - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.BUNDLE_TWIN_MUST_BE_UNIQUE ); }); @@ -555,7 +577,8 @@ describe("IBosonBundleHandler", function () { await twinHandler.connect(assistant).createTwin(newTwin); // creates a twin with id 6 bundle.twinIds = ["1", expectedNewTwinId]; - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INSUFFICIENT_TWIN_SUPPLY_TO_COVER_BUNDLE_OFFERS ); }); @@ -570,7 +593,8 @@ describe("IBosonBundleHandler", function () { .createOffer(newOffer, offerDates, offerDurations, disputeResolverId, agentId); bundle.offerIds = [expectedNewOfferId]; - await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWith( + await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INSUFFICIENT_TWIN_SUPPLY_TO_COVER_BUNDLE_OFFERS ); }); diff --git a/test/protocol/BuyerHandlerTest.js b/test/protocol/BuyerHandlerTest.js index d24ac8ca9..049512642 100644 --- a/test/protocol/BuyerHandlerTest.js +++ b/test/protocol/BuyerHandlerTest.js @@ -41,6 +41,7 @@ describe("BuyerHandler", function () { let bosonVoucher; let voucherInitValues; let snapshotId; + let bosonErrors; before(async function () { accountId.next(true); @@ -59,6 +60,8 @@ describe("BuyerHandler", function () { contractInstances: { accountHandler, offerHandler, exchangeHandler, fundsHandler, pauseHandler }, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", await accountHandler.getAddress()); + // make all account the same assistant = admin; clerk = { address: ZeroAddress }; @@ -136,21 +139,30 @@ describe("BuyerHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Buyers]); // Attempt to create a buyer, expecting revert - await expect(accountHandler.connect(rando).createBuyer(buyer)).to.revertedWith(RevertReasons.REGION_PAUSED); + await expect(accountHandler.connect(rando).createBuyer(buyer)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.REGION_PAUSED + ); }); it("active is false", async function () { buyer.active = false; // Attempt to Create a Buyer, expecting revert - await expect(accountHandler.connect(rando).createBuyer(buyer)).to.revertedWith(RevertReasons.MUST_BE_ACTIVE); + await expect(accountHandler.connect(rando).createBuyer(buyer)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.MUST_BE_ACTIVE + ); }); it("addresses are the zero address", async function () { buyer.wallet = ZeroAddress; // Attempt to Create a Buyer, expecting revert - await expect(accountHandler.connect(rando).createBuyer(buyer)).to.revertedWith(RevertReasons.INVALID_ADDRESS); + await expect(accountHandler.connect(rando).createBuyer(buyer)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.INVALID_ADDRESS + ); }); it("wallet address is not unique to this buyerId", async function () { @@ -158,7 +170,8 @@ describe("BuyerHandler", function () { await accountHandler.connect(rando).createBuyer(buyer); // Attempt to create another buyer with same wallet address - await expect(accountHandler.connect(rando).createBuyer(buyer)).to.revertedWith( + await expect(accountHandler.connect(rando).createBuyer(buyer)).to.revertedWithCustomError( + bosonErrors, RevertReasons.BUYER_ADDRESS_MUST_BE_UNIQUE ); }); @@ -319,7 +332,10 @@ describe("BuyerHandler", function () { .withArgs(buyer.id, buyerStruct, await other2.getAddress()); // Attempt to update the buyer with original wallet address, expecting revert - await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWith(RevertReasons.NOT_BUYER_WALLET); + await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NOT_BUYER_WALLET + ); }); context("💔 Revert Reasons", async function () { @@ -427,7 +443,10 @@ describe("BuyerHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Buyers]); // Attempt to update a buyer, expecting revert - await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWith(RevertReasons.REGION_PAUSED); + await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.REGION_PAUSED + ); }); it("Buyer does not exist", async function () { @@ -435,18 +454,25 @@ describe("BuyerHandler", function () { buyer.id = "444"; // Attempt to update the buyer, expecting revert - await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWith(RevertReasons.NO_SUCH_BUYER); + await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NO_SUCH_BUYER + ); // Set invalid id buyer.id = "0"; // Attempt to update the buyer, expecting revert - await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWith(RevertReasons.NO_SUCH_BUYER); + await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NO_SUCH_BUYER + ); }); it("Caller is not buyer wallet address", async function () { // Attempt to update the buyer, expecting revert - await expect(accountHandler.connect(other2).updateBuyer(buyer)).to.revertedWith( + await expect(accountHandler.connect(other2).updateBuyer(buyer)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_BUYER_WALLET ); }); @@ -455,7 +481,8 @@ describe("BuyerHandler", function () { buyer.wallet = ZeroAddress; // Attempt to update the buyer, expecting revert - await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWith( + await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ADDRESS ); }); @@ -476,7 +503,8 @@ describe("BuyerHandler", function () { buyer2.wallet = await other1.getAddress(); //already being used by buyer 1 // Attempt to update buyer 2 with non-unique wallet address, expecting revert - await expect(accountHandler.connect(other2).updateBuyer(buyer2)).to.revertedWith( + await expect(accountHandler.connect(other2).updateBuyer(buyer2)).to.revertedWithCustomError( + bosonErrors, RevertReasons.BUYER_ADDRESS_MUST_BE_UNIQUE ); }); @@ -485,7 +513,8 @@ describe("BuyerHandler", function () { buyer.wallet = await other4.getAddress(); // Attempt to update the buyer, expecting revert - await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWith( + await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWithCustomError( + bosonErrors, RevertReasons.WALLET_OWNS_VOUCHERS ); }); diff --git a/test/protocol/ConfigHandlerTest.js b/test/protocol/ConfigHandlerTest.js index 3f1e99030..6cad4bd3e 100644 --- a/test/protocol/ConfigHandlerTest.js +++ b/test/protocol/ConfigHandlerTest.js @@ -37,6 +37,7 @@ describe("IBosonConfigHandler", function () { let protocolFeePercentage, protocolFeeFlatBoson; let erc165, protocolDiamond, accessController, configHandler; let snapshotId; + let bosonErrors; before(async function () { // get interface Ids @@ -79,6 +80,8 @@ describe("IBosonConfigHandler", function () { // Cast Diamond to IBosonConfigHandler configHandler = await getContractAt("IBosonConfigHandler", await protocolDiamond.getAddress()); + bosonErrors = await getContractAt("BosonErrors", await protocolDiamond.getAddress()); + // Get snapshot id snapshotId = await getSnapshot(); }); @@ -275,14 +278,15 @@ describe("IBosonConfigHandler", function () { context("💔 Revert Reasons", async function () { it("caller is not the admin", async function () { // Attempt to set new token address, expecting revert - await expect(configHandler.connect(rando).setTokenAddress(await token.getAddress())).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); + await expect( + configHandler.connect(rando).setTokenAddress(await token.getAddress()) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("token address is the zero address", async function () { // Attempt to set new token address, expecting revert - await expect(configHandler.connect(deployer).setTokenAddress(ZeroAddress)).to.revertedWith( + await expect(configHandler.connect(deployer).setTokenAddress(ZeroAddress)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ADDRESS ); }); @@ -314,14 +318,15 @@ describe("IBosonConfigHandler", function () { context("💔 Revert Reasons", async function () { it("caller is not the admin", async function () { // Attempt to set new treasury address, expecting revert - await expect(configHandler.connect(rando).setTreasuryAddress(await treasury.getAddress())).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); + await expect( + configHandler.connect(rando).setTreasuryAddress(await treasury.getAddress()) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("treasury address is the zero address", async function () { // Attempt to set new treasury address, expecting revert - await expect(configHandler.connect(deployer).setTreasuryAddress(ZeroAddress)).to.revertedWith( + await expect(configHandler.connect(deployer).setTreasuryAddress(ZeroAddress)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ADDRESS ); }); @@ -355,14 +360,14 @@ describe("IBosonConfigHandler", function () { // Attempt to set new beacon address, expecting revert await expect( configHandler.connect(rando).setVoucherBeaconAddress(await beacon.getAddress()) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("voucher beacon address is the zero address", async function () { // Attempt to set new beacon address, expecting revert - await expect(configHandler.connect(deployer).setVoucherBeaconAddress(ZeroAddress)).to.revertedWith( - RevertReasons.INVALID_ADDRESS - ); + await expect( + configHandler.connect(deployer).setVoucherBeaconAddress(ZeroAddress) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); }); }); @@ -392,14 +397,15 @@ describe("IBosonConfigHandler", function () { context("💔 Revert Reasons", async function () { it("caller is not the admin", async function () { // Attempt to set new proxy address, expecting revert - await expect(configHandler.connect(rando).setBeaconProxyAddress(await proxy.getAddress())).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); + await expect( + configHandler.connect(rando).setBeaconProxyAddress(await proxy.getAddress()) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("beacon proxy address is the zero address", async function () { // Attempt to set new proxy address, expecting revert - await expect(configHandler.connect(deployer).setBeaconProxyAddress(ZeroAddress)).to.revertedWith( + await expect(configHandler.connect(deployer).setBeaconProxyAddress(ZeroAddress)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ADDRESS ); }); @@ -431,9 +437,9 @@ describe("IBosonConfigHandler", function () { context("💔 Revert Reasons", async function () { it("caller is not the admin", async function () { // Attempt to set new protocol fee precentage, expecting revert - await expect(configHandler.connect(rando).setProtocolFeePercentage(protocolFeePercentage)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); + await expect( + configHandler.connect(rando).setProtocolFeePercentage(protocolFeePercentage) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("protocolFeePercentage must be less than 10000", async function () { @@ -441,7 +447,7 @@ describe("IBosonConfigHandler", function () { protocolFeePercentage = 10001; await expect( configHandler.connect(deployer).setProtocolFeePercentage(protocolFeePercentage) - ).to.revertedWith(RevertReasons.FEE_PERCENTAGE_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FEE_PERCENTAGE_INVALID); }); }); }); @@ -471,9 +477,9 @@ describe("IBosonConfigHandler", function () { context("💔 Revert Reasons", async function () { it("caller is not the admin", async function () { // Attempt to set new voucher address, expecting revert - await expect(configHandler.connect(rando).setProtocolFeeFlatBoson(protocolFeeFlatBoson)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); + await expect( + configHandler.connect(rando).setProtocolFeeFlatBoson(protocolFeeFlatBoson) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); }); }); @@ -507,14 +513,14 @@ describe("IBosonConfigHandler", function () { // Attempt to set new value, expecting revert await expect( configHandler.connect(rando).setMaxEscalationResponsePeriod(maxEscalationResponsePeriod) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("maxEscalationResponsePeriod is zero", async function () { maxEscalationResponsePeriod = 0; await expect( configHandler.connect(deployer).setMaxEscalationResponsePeriod(maxEscalationResponsePeriod) - ).to.revertedWith(RevertReasons.VALUE_ZERO_NOT_ALLOWED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VALUE_ZERO_NOT_ALLOWED); }); }); }); @@ -550,7 +556,7 @@ describe("IBosonConfigHandler", function () { // Attempt to set new buyer escalation deposit percentage, expecting revert await expect( configHandler.connect(rando).setBuyerEscalationDepositPercentage(buyerEscalationDepositPercentage) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("protocolFeePercentage must be less than 10000", async function () { @@ -558,7 +564,7 @@ describe("IBosonConfigHandler", function () { buyerEscalationDepositPercentage = 10001; await expect( configHandler.connect(deployer).setBuyerEscalationDepositPercentage(buyerEscalationDepositPercentage) - ).to.revertedWith(RevertReasons.FEE_PERCENTAGE_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FEE_PERCENTAGE_INVALID); }); }); }); @@ -592,7 +598,7 @@ describe("IBosonConfigHandler", function () { // Attempt to set new value for Max Total Offer Fee Percentage, expecting revert await expect( configHandler.connect(rando).setMaxTotalOfferFeePercentage(maxTotalOfferFeePercentage) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("maxTotalOfferFeePercentage must be less than 10000", async function () { @@ -600,7 +606,7 @@ describe("IBosonConfigHandler", function () { maxTotalOfferFeePercentage = 10001; await expect( configHandler.connect(deployer).setMaxTotalOfferFeePercentage(maxTotalOfferFeePercentage) - ).to.revertedWith(RevertReasons.FEE_PERCENTAGE_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FEE_PERCENTAGE_INVALID); }); }); }); @@ -630,24 +636,24 @@ describe("IBosonConfigHandler", function () { context("💔 Revert Reasons", async function () { it("caller is not the admin", async function () { // Attempt to set new value for Max Royalty Percentage, expecting revert - await expect(configHandler.connect(rando).setMaxRoyaltyPecentage(maxRoyaltyPecentage)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); + await expect( + configHandler.connect(rando).setMaxRoyaltyPecentage(maxRoyaltyPecentage) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("maxRoyaltyPecentage must be less than 10000", async function () { // Attempt to set new value for Max Royalty Percentage, expecting revert maxRoyaltyPecentage = 10001; - await expect(configHandler.connect(deployer).setMaxRoyaltyPecentage(maxRoyaltyPecentage)).to.revertedWith( - RevertReasons.FEE_PERCENTAGE_INVALID - ); + await expect( + configHandler.connect(deployer).setMaxRoyaltyPecentage(maxRoyaltyPecentage) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FEE_PERCENTAGE_INVALID); }); it("maxRoyaltyPecentage is zero", async function () { maxRoyaltyPecentage = 0; - await expect(configHandler.connect(deployer).setMaxRoyaltyPecentage(maxRoyaltyPecentage)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); + await expect( + configHandler.connect(deployer).setMaxRoyaltyPecentage(maxRoyaltyPecentage) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VALUE_ZERO_NOT_ALLOWED); }); }); }); @@ -687,7 +693,7 @@ describe("IBosonConfigHandler", function () { // Attempt to set new auth token contract, expecting revert await expect( configHandler.connect(rando).setAuthTokenContract(AuthTokenType.ENS, await authTokenContract.getAddress()) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("_authTokenType is None", async function () { @@ -696,7 +702,7 @@ describe("IBosonConfigHandler", function () { configHandler .connect(deployer) .setAuthTokenContract(AuthTokenType.None, await authTokenContract.getAddress()) - ).to.revertedWith(RevertReasons.INVALID_AUTH_TOKEN_TYPE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_AUTH_TOKEN_TYPE); }); it("_authTokenType is Custom", async function () { @@ -705,14 +711,14 @@ describe("IBosonConfigHandler", function () { configHandler .connect(deployer) .setAuthTokenContract(AuthTokenType.Custom, await authTokenContract.getAddress()) - ).to.revertedWith(RevertReasons.INVALID_AUTH_TOKEN_TYPE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_AUTH_TOKEN_TYPE); }); it("_authTokenContract is the zero address", async function () { // Attempt to set new auth token contract, expecting revert await expect( configHandler.connect(deployer).setAuthTokenContract(AuthTokenType.ENS, ZeroAddress) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); }); }); @@ -742,16 +748,16 @@ describe("IBosonConfigHandler", function () { context("💔 Revert Reasons", async function () { it("caller is not the admin", async function () { // Attempt to set new value, expecting revert - await expect(configHandler.connect(rando).setMinResolutionPeriod(minResolutionPeriod)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); + await expect( + configHandler.connect(rando).setMinResolutionPeriod(minResolutionPeriod) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("minResolutionPeriod is zero", async function () { minResolutionPeriod = 0; - await expect(configHandler.connect(deployer).setMinResolutionPeriod(minResolutionPeriod)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); + await expect( + configHandler.connect(deployer).setMinResolutionPeriod(minResolutionPeriod) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VALUE_ZERO_NOT_ALLOWED); }); it("minResolutionPeriod is greater than maxResolutionPeriod", async function () { @@ -759,9 +765,9 @@ describe("IBosonConfigHandler", function () { await configHandler.connect(deployer).setMaxResolutionPeriod(maxResolutionPeriod); minResolutionPeriod = maxResolutionPeriod + 1n; - await expect(configHandler.connect(deployer).setMinResolutionPeriod(minResolutionPeriod)).to.revertedWith( - RevertReasons.INVALID_RESOLUTION_PERIOD - ); + await expect( + configHandler.connect(deployer).setMinResolutionPeriod(minResolutionPeriod) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RESOLUTION_PERIOD); }); }); }); @@ -791,16 +797,16 @@ describe("IBosonConfigHandler", function () { context("💔 Revert Reasons", async function () { it("caller is not the admin", async function () { // Attempt to set new value, expecting revert - await expect(configHandler.connect(rando).setMaxResolutionPeriod(maxResolutionPeriod)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); + await expect( + configHandler.connect(rando).setMaxResolutionPeriod(maxResolutionPeriod) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("maxResolutionPeriod is zero", async function () { maxResolutionPeriod = 0; - await expect(configHandler.connect(deployer).setMaxResolutionPeriod(maxResolutionPeriod)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); + await expect( + configHandler.connect(deployer).setMaxResolutionPeriod(maxResolutionPeriod) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VALUE_ZERO_NOT_ALLOWED); }); it("maxResolutionPeriod is less than minResolutionPeriod", async function () { @@ -808,9 +814,9 @@ describe("IBosonConfigHandler", function () { await configHandler.connect(deployer).setMinResolutionPeriod(minResolutionPeriod); const maxResolutionPeriod = minResolutionPeriod - 1n; - await expect(configHandler.connect(deployer).setMaxResolutionPeriod(maxResolutionPeriod)).to.revertedWith( - RevertReasons.INVALID_RESOLUTION_PERIOD - ); + await expect( + configHandler.connect(deployer).setMaxResolutionPeriod(maxResolutionPeriod) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RESOLUTION_PERIOD); }); }); }); @@ -840,16 +846,17 @@ describe("IBosonConfigHandler", function () { context("💔 Revert Reasons", async function () { it("caller is not the admin", async function () { // Attempt to set new value, expecting revert - await expect(configHandler.connect(rando).setMinDisputePeriod(minDisputePeriod)).to.revertedWith( + await expect(configHandler.connect(rando).setMinDisputePeriod(minDisputePeriod)).to.revertedWithCustomError( + bosonErrors, RevertReasons.ACCESS_DENIED ); }); it("minDisputePeriod is zero", async function () { minDisputePeriod = 0; - await expect(configHandler.connect(deployer).setMinDisputePeriod(minDisputePeriod)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); + await expect( + configHandler.connect(deployer).setMinDisputePeriod(minDisputePeriod) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VALUE_ZERO_NOT_ALLOWED); }); }); }); @@ -886,14 +893,14 @@ describe("IBosonConfigHandler", function () { // Attempt to set new value, expecting revert await expect( configHandler.connect(rando).setAccessControllerAddress(await newAccessController.getAddress()) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("_accessControllerAddress is the zero address", async function () { // Attempt to set new value, expecting revert - await expect(configHandler.connect(deployer).setAccessControllerAddress(ZeroAddress)).to.revertedWith( - RevertReasons.INVALID_ADDRESS - ); + await expect( + configHandler.connect(deployer).setAccessControllerAddress(ZeroAddress) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); }); }); diff --git a/test/protocol/DisputeHandlerTest.js b/test/protocol/DisputeHandlerTest.js index 25162fdab..56131a400 100644 --- a/test/protocol/DisputeHandlerTest.js +++ b/test/protocol/DisputeHandlerTest.js @@ -1,5 +1,5 @@ const { ethers } = require("hardhat"); -const { ZeroAddress, provider, zeroPadBytes, MaxUint256, parseUnits } = ethers; +const { ZeroAddress, provider, zeroPadBytes, MaxUint256, parseUnits, getContractAt } = ethers; const { expect, assert } = require("chai"); const Exchange = require("../../scripts/domain/Exchange"); const Dispute = require("../../scripts/domain/Dispute"); @@ -83,6 +83,7 @@ describe("IBosonDisputeHandler", function () { let emptyAuthToken; let agentId; let snapshotId; + let bosonErrors; before(async function () { accountId.next(true); @@ -115,6 +116,8 @@ describe("IBosonDisputeHandler", function () { protocolConfig: [, , { buyerEscalationDepositPercentage }], } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", await accountHandler.getAddress()); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -289,14 +292,16 @@ describe("IBosonDisputeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]); // Attempt to raise a dispute, expecting revert - await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); it("Caller does not hold a voucher for the given exchange id", async function () { // Attempt to raise a dispute, expecting revert - await expect(disputeHandler.connect(rando).raiseDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).raiseDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER ); }); @@ -306,7 +311,8 @@ describe("IBosonDisputeHandler", function () { const exchangeId = "666"; // Attempt to raise a dispute, expecting revert - await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_EXCHANGE ); }); @@ -329,7 +335,8 @@ describe("IBosonDisputeHandler", function () { await exchangeHandler.connect(assistant).completeExchange(exchangeId); // Attempt to raise a dispute, expecting revert - await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); @@ -339,7 +346,8 @@ describe("IBosonDisputeHandler", function () { await disputeHandler.connect(buyer).raiseDispute(exchangeId); // Attempt to raise a dispute, expecting revert - await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); @@ -353,7 +361,8 @@ describe("IBosonDisputeHandler", function () { await setNextBlockTimestamp(Number(voucherRedeemedDate + BigInt(disputePeriod) + 1n)); // Attempt to raise a dispute, expecting revert - await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.DISPUTE_PERIOD_HAS_ELAPSED ); }); @@ -439,7 +448,8 @@ describe("IBosonDisputeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]); // Attempt to retract a dispute, expecting revert - await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -449,7 +459,8 @@ describe("IBosonDisputeHandler", function () { const exchangeId = "666"; // Attempt to retract the dispute, expecting revert - await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_EXCHANGE ); }); @@ -461,14 +472,16 @@ describe("IBosonDisputeHandler", function () { await exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }); // Attempt to retract the dispute, expecting revert - await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); it("Caller is not the buyer for the given exchange id", async function () { // Attempt to retract the dispute, expecting revert - await expect(disputeHandler.connect(rando).retractDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).retractDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER ); }); @@ -478,7 +491,8 @@ describe("IBosonDisputeHandler", function () { await disputeHandler.connect(buyer).retractDispute(exchangeId); // Attempt to retract the dispute, expecting revert - await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); @@ -496,7 +510,8 @@ describe("IBosonDisputeHandler", function () { await setNextBlockTimestamp(Number(escalatedDate) + Number(escalationPeriod) + 1); // Attempt to retract the dispute, expecting revert - await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.DISPUTE_HAS_EXPIRED ); }); @@ -577,7 +592,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to extend a dispute timeout, expecting revert await expect( disputeHandler.connect(assistant).extendDisputeTimeout(exchangeId, newDisputeTimeout) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Exchange does not exist", async function () { @@ -587,7 +602,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to extend the dispute timeout, expecting revert await expect( disputeHandler.connect(assistant).extendDisputeTimeout(exchangeId, newDisputeTimeout) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("Exchange is not in a disputed state", async function () { @@ -599,14 +614,14 @@ describe("IBosonDisputeHandler", function () { // Attempt to extend the dispute timeout, expecting revert await expect( disputeHandler.connect(assistant).extendDisputeTimeout(exchangeId, newDisputeTimeout) - ).to.revertedWith(RevertReasons.INVALID_STATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("Caller is not the seller", async function () { // Attempt to extend the dispute timeout, expecting revert await expect( disputeHandler.connect(rando).extendDisputeTimeout(exchangeId, newDisputeTimeout) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("Dispute has expired already", async function () { @@ -616,7 +631,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to extend the dispute timeout, expecting revert await expect( disputeHandler.connect(assistant).extendDisputeTimeout(exchangeId, newDisputeTimeout) - ).to.revertedWith(RevertReasons.DISPUTE_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_HAS_EXPIRED); }); it("new dispute timeout is before the current dispute timeout", async function () { @@ -625,7 +640,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to extend the dispute timeout, expecting revert await expect( disputeHandler.connect(assistant).extendDisputeTimeout(exchangeId, newDisputeTimeout) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_TIMEOUT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_TIMEOUT); }); it("Dispute is in some state other than resolving", async function () { @@ -635,7 +650,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to expire the dispute, expecting revert await expect( disputeHandler.connect(assistant).extendDisputeTimeout(exchangeId, newDisputeTimeout) - ).to.revertedWith(RevertReasons.INVALID_STATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); }); }); @@ -718,7 +733,8 @@ describe("IBosonDisputeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]); // Attempt to expire a dispute, expecting revert - await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -728,7 +744,8 @@ describe("IBosonDisputeHandler", function () { const exchangeId = "666"; // Attempt to expire the dispute, expecting revert - await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_EXCHANGE ); }); @@ -740,14 +757,16 @@ describe("IBosonDisputeHandler", function () { await exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }); // Attempt to expire the dispute, expecting revert - await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); it("Dispute has not expired yet", async function () { // Attempt to expire the dispute, expecting revert - await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.DISPUTE_STILL_VALID ); }); @@ -762,7 +781,8 @@ describe("IBosonDisputeHandler", function () { await setNextBlockTimestamp(Number(timeout) + Number(oneWeek)); // Attempt to expire the dispute, expecting revert - await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.DISPUTE_STILL_VALID ); }); @@ -772,7 +792,8 @@ describe("IBosonDisputeHandler", function () { await disputeHandler.connect(buyer).retractDispute(exchangeId); // Attempt to expire the dispute, expecting revert - await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); @@ -1067,7 +1088,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to resolve a dispute, expecting revert await expect( disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Specified buyer percent exceeds 100%", async function () { @@ -1077,7 +1098,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.INVALID_BUYER_PERCENT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_BUYER_PERCENT); }); it("Dispute has expired", async function () { @@ -1087,7 +1108,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.DISPUTE_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_HAS_EXPIRED); }); it("Exchange does not exist", async function () { @@ -1097,7 +1118,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("Exchange is not in a disputed state", async function () { @@ -1109,7 +1130,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.INVALID_STATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("Caller is neither the seller nor the buyer for the given exchange id", async function () { @@ -1117,7 +1138,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(rando).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.NOT_BUYER_OR_SELLER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_BUYER_OR_SELLER); // Wallet with seller account, but not the seller in this exchange // Create a valid seller @@ -1133,7 +1154,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(other1).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.NOT_BUYER_OR_SELLER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_BUYER_OR_SELLER); // Wallet with buyer account, but not the buyer in this exchange // Create a valid buyer @@ -1144,7 +1165,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(other2).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.NOT_BUYER_OR_SELLER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_BUYER_OR_SELLER); }); it("signature does not belong to the address of the other party", async function () { @@ -1160,12 +1181,12 @@ describe("IBosonDisputeHandler", function () { // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(buyer).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); it("signature resolution does not match input buyerPercentBasisPoints ", async function () { @@ -1175,29 +1196,29 @@ describe("IBosonDisputeHandler", function () { // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); it("signature has invalid field", async function () { // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, "0") - ).to.revertedWith(RevertReasons.INVALID_SIGNATURE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_SIGNATURE); await expect( disputeHandler .connect(assistant) .resolveDispute(exchangeId, buyerPercentBasisPoints, r, zeroPadBytes("0x", 32), v) - ).to.revertedWith(RevertReasons.INVALID_SIGNATURE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_SIGNATURE); await expect( disputeHandler .connect(assistant) .resolveDispute(exchangeId, buyerPercentBasisPoints, zeroPadBytes("0x", 32), s, v) - ).to.revertedWith(RevertReasons.INVALID_SIGNATURE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_SIGNATURE); await expect( disputeHandler .connect(assistant) .resolveDispute(exchangeId, buyerPercentBasisPoints, r, toHexString(MaxUint256), v) - ).to.revertedWith(RevertReasons.INVALID_SIGNATURE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_SIGNATURE); }); it("dispute state is neither resolving or escalated", async function () { @@ -1207,7 +1228,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to resolve the dispute, expecting revert await expect( disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v) - ).to.revertedWith(RevertReasons.INVALID_STATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); }); }); @@ -1352,7 +1373,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to escalate a dispute, expecting revert await expect( disputeHandler.connect(buyer).escalateDispute(exchangeId, { value: buyerEscalationDepositNative }) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Exchange does not exist", async function () { @@ -1362,7 +1383,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to escalate the dispute, expecting revert await expect(disputeHandler.connect(buyer).escalateDispute(exchangeId), { value: buyerEscalationDepositNative, - }).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + }).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("Exchange is not in a disputed state", async function () { @@ -1374,14 +1395,14 @@ describe("IBosonDisputeHandler", function () { // Attempt to escalate the dispute, expecting revert await expect(disputeHandler.connect(buyer).escalateDispute(exchangeId), { value: buyerEscalationDepositNative, - }).to.revertedWith(RevertReasons.INVALID_STATE); + }).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("Caller is not the buyer for the given exchange id", async function () { // Attempt to retract the dispute, expecting revert await expect(disputeHandler.connect(rando).escalateDispute(exchangeId), { value: buyerEscalationDepositNative, - }).to.revertedWith(RevertReasons.NOT_VOUCHER_HOLDER); + }).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER); }); it("Dispute has expired", async function () { @@ -1391,7 +1412,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to escalate the dispute, expecting revert await expect(disputeHandler.connect(buyer).escalateDispute(exchangeId), { value: buyerEscalationDepositNative, - }).to.revertedWith(RevertReasons.DISPUTE_HAS_EXPIRED); + }).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_HAS_EXPIRED); }); it("Dispute is in some state other than resolving", async function () { @@ -1399,7 +1420,8 @@ describe("IBosonDisputeHandler", function () { await disputeHandler.connect(buyer).retractDispute(exchangeId); // Attempt to escalate the dispute, expecting revert - await expect(disputeHandler.connect(buyer).escalateDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).escalateDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); @@ -1422,7 +1444,8 @@ describe("IBosonDisputeHandler", function () { await disputeHandler.connect(buyer).raiseDispute(exchangeId); // Attempt to escalate the dispute, expecting revert - await expect(disputeHandler.connect(buyer).escalateDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).escalateDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.ESCALATION_NOT_ALLOWED ); }); @@ -1433,7 +1456,7 @@ describe("IBosonDisputeHandler", function () { disputeHandler.connect(buyer).escalateDispute(exchangeId, { value: BigInt(buyerEscalationDepositNative) - 1n, }) - ).to.revertedWith(RevertReasons.INSUFFICIENT_VALUE_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_VALUE_RECEIVED); }); it("Native currency sent together with ERC20 token transfer", async function () { @@ -1444,7 +1467,7 @@ describe("IBosonDisputeHandler", function () { disputeHandler.connect(buyer).escalateDispute(exchangeId, { value: 1n, }) - ).to.revertedWith(RevertReasons.NATIVE_NOT_ALLOWED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NATIVE_NOT_ALLOWED); }); it.skip("Token address is not a contract", async function () { @@ -1520,7 +1543,8 @@ describe("IBosonDisputeHandler", function () { await disputeHandler.connect(buyer).raiseDispute(exchangeId); // Attempt to escalate the dispute, expecting revert - await expect(disputeHandler.connect(buyer).escalateDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(buyer).escalateDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INSUFFICIENT_VALUE_RECEIVED ); }); @@ -1599,7 +1623,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to decide a dispute, expecting revert await expect( disputeHandler.connect(assistantDR).decideDispute(exchangeId, buyerPercentBasisPoints) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Specified buyer percent exceeds 100%", async function () { @@ -1609,7 +1633,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to decide the dispute, expecting revert await expect( disputeHandler.connect(assistantDR).decideDispute(exchangeId, buyerPercentBasisPoints) - ).to.revertedWith(RevertReasons.INVALID_BUYER_PERCENT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_BUYER_PERCENT); }); it("Exchange does not exist", async function () { @@ -1619,7 +1643,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to decide the dispute, expecting revert await expect( disputeHandler.connect(assistantDR).decideDispute(exchangeId, buyerPercentBasisPoints) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("Exchange is not in a disputed state", async function () { @@ -1631,14 +1655,14 @@ describe("IBosonDisputeHandler", function () { // Attempt to decide the dispute, expecting revert await expect( disputeHandler.connect(assistantDR).decideDispute(exchangeId, buyerPercentBasisPoints) - ).to.revertedWith(RevertReasons.INVALID_STATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("Caller is not the dispute resolver for this dispute", async function () { // Attempt to decide the dispute, expecting revert await expect( disputeHandler.connect(rando).decideDispute(exchangeId, buyerPercentBasisPoints) - ).to.revertedWith(RevertReasons.NOT_DISPUTE_RESOLVER_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_DISPUTE_RESOLVER_ASSISTANT); }); it("Dispute state is not escalated", async function () { @@ -1656,7 +1680,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to decide the dispute, expecting revert await expect( disputeHandler.connect(assistantDR).decideDispute(exchangeId, buyerPercentBasisPoints) - ).to.revertedWith(RevertReasons.INVALID_STATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("Dispute escalation response period has elapsed", async function () { @@ -1666,7 +1690,7 @@ describe("IBosonDisputeHandler", function () { // Attempt to decide the dispute, expecting revert await expect( disputeHandler.connect(assistantDR).decideDispute(exchangeId, buyerPercentBasisPoints) - ).to.revertedWith(RevertReasons.DISPUTE_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_HAS_EXPIRED); }); }); }); @@ -1757,7 +1781,8 @@ describe("IBosonDisputeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]); // Attempt to expire an escalated dispute, expecting revert - await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -1767,7 +1792,8 @@ describe("IBosonDisputeHandler", function () { const exchangeId = "666"; // Attempt to expire the escalated dispute, expecting revert - await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_EXCHANGE ); }); @@ -1779,14 +1805,16 @@ describe("IBosonDisputeHandler", function () { await exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }); // Attempt to expire the escalated dispute, expecting revert - await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); it("Dispute escalation period has not passed yet", async function () { // Attempt to expire the escalated dispute, expecting revert - await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.DISPUTE_STILL_VALID ); }); @@ -1805,7 +1833,8 @@ describe("IBosonDisputeHandler", function () { // dispute raised but not escalated // Attempt to expire the escalated dispute, expecting revert - await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); @@ -1813,7 +1842,8 @@ describe("IBosonDisputeHandler", function () { await disputeHandler.connect(buyer).retractDispute(exchangeId); // Attempt to expire the retracted dispute, expecting revert - await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); @@ -1897,9 +1927,9 @@ describe("IBosonDisputeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]); // Attempt to refuse an escalated dispute, expecting revert - await expect(disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId)).to.revertedWith( - RevertReasons.REGION_PAUSED - ); + await expect( + disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Exchange does not exist", async function () { @@ -1907,9 +1937,9 @@ describe("IBosonDisputeHandler", function () { const exchangeId = "666"; // Attempt to refuse the escalated dispute, expecting revert - await expect(disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId)).to.revertedWith( - RevertReasons.NO_SUCH_EXCHANGE - ); + await expect( + disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("Exchange is not in a disputed state", async function () { @@ -1919,9 +1949,9 @@ describe("IBosonDisputeHandler", function () { await exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }); // Attempt to refuse the escalated dispute, expecting revert - await expect(disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId)).to.revertedWith( - RevertReasons.INVALID_STATE - ); + await expect( + disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("Dispute is in some state other than escalated", async function () { @@ -1938,17 +1968,17 @@ describe("IBosonDisputeHandler", function () { // dispute raised but not escalated // Attempt to refuse the escalated dispute, expecting revert - await expect(disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId)).to.revertedWith( - RevertReasons.INVALID_STATE - ); + await expect( + disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); // Retract the dispute, put it into RETRACTED state await disputeHandler.connect(buyer).retractDispute(exchangeId); // Attempt to refuse the retracted dispute, expecting revert - await expect(disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId)).to.revertedWith( - RevertReasons.INVALID_STATE - ); + await expect( + disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("Dispute escalation response period has elapsed", async function () { @@ -1956,14 +1986,15 @@ describe("IBosonDisputeHandler", function () { await setNextBlockTimestamp(Number(escalatedDate) + Number(escalationPeriod) + 1); // Attempt to refuse the escalated dispute, expecting revert - await expect(disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId)).to.revertedWith( - RevertReasons.DISPUTE_HAS_EXPIRED - ); + await expect( + disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_HAS_EXPIRED); }); it("Caller is not the dispute resolver for this dispute", async function () { // Attempt to refuse the escalated dispute, expecting revert - await expect(disputeHandler.connect(rando).refuseEscalatedDispute(exchangeId)).to.revertedWith( + await expect(disputeHandler.connect(rando).refuseEscalatedDispute(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_DISPUTE_RESOLVER_ASSISTANT ); }); @@ -2489,7 +2520,8 @@ describe("IBosonDisputeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]); // Attempt to expire a dispute batch, expecting revert - await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -2501,7 +2533,8 @@ describe("IBosonDisputeHandler", function () { disputesToExpire.push("666"); // Attempt to expire the disputes, expecting revert - await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_EXCHANGE ); }); @@ -2513,14 +2546,16 @@ describe("IBosonDisputeHandler", function () { disputesToExpire.push("1"); // Attempt to expire the disputes, expecting revert - await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); it("Dispute has not expired yet", async function () { // Attempt to expire the disputes, expecting revert - await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire)).to.revertedWithCustomError( + bosonErrors, RevertReasons.DISPUTE_STILL_VALID ); }); @@ -2532,7 +2567,8 @@ describe("IBosonDisputeHandler", function () { await disputeHandler.connect(buyer).retractDispute("3"); // Attempt to expire the disputes, expecting revert - await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire)).to.revertedWith( + await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); diff --git a/test/protocol/DisputeResolverHandlerTest.js b/test/protocol/DisputeResolverHandlerTest.js index c85bf20e3..1e1727c16 100644 --- a/test/protocol/DisputeResolverHandlerTest.js +++ b/test/protocol/DisputeResolverHandlerTest.js @@ -1,6 +1,6 @@ const { ethers } = require("hardhat"); const { expect, assert } = require("chai"); -const { ZeroAddress } = ethers; +const { ZeroAddress, getContractAt } = ethers; const DisputeResolver = require("../../scripts/domain/DisputeResolver"); const { DisputeResolverFee, DisputeResolverFeeList } = require("../../scripts/domain/DisputeResolverFee"); @@ -38,6 +38,7 @@ describe("DisputeResolverHandler", function () { let invalidAccountId, key, value, exists; let voucherInitValues; let snapshotId; + let bosonErrors; async function isValidDisputeResolverEvent( tx, @@ -103,6 +104,8 @@ describe("DisputeResolverHandler", function () { contractInstances: { accountHandler, configHandler, pauseHandler }, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", await configHandler.getAddress()); + // make all account the same assistant = admin; clerk = { address: ZeroAddress }; @@ -466,7 +469,7 @@ describe("DisputeResolverHandler", function () { // Attempt to create a dispute resolver, expecting revert await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Any address is the zero address", async function () { @@ -475,7 +478,7 @@ describe("DisputeResolverHandler", function () { // Attempt to Create a DisputeResolver, expecting revert await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); disputeResolver.assistant = await assistant.getAddress(); disputeResolver.admin = ZeroAddress; @@ -483,7 +486,7 @@ describe("DisputeResolverHandler", function () { // Attempt to Create a DisputeResolver, expecting revert await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); disputeResolver.admin = await admin.getAddress(); disputeResolver.treasury = ZeroAddress; @@ -491,7 +494,7 @@ describe("DisputeResolverHandler", function () { // Attempt to Create a DisputeResolver, expecting revert await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("Supplied clerk is not a zero address", async function () { @@ -500,7 +503,7 @@ describe("DisputeResolverHandler", function () { // Attempt to Create a DisputeResolver, expecting revert await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.CLERK_DEPRECATED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CLERK_DEPRECATED); }); it("Address is not unique to this dispute resolver Id", async function () { @@ -519,7 +522,7 @@ describe("DisputeResolverHandler", function () { // Attempt to create another dispute resolver with same addresses await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver2, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE); }); it("EscalationResponsePeriod is invalid", async function () { @@ -528,14 +531,14 @@ describe("DisputeResolverHandler", function () { // Attempt to Create a DisputeResolver, expecting revert await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.INVALID_ESCALATION_PERIOD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ESCALATION_PERIOD); disputeResolver.escalationResponsePeriod = 0; // Attempt to Create a DisputeResolver, expecting revert await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.INVALID_ESCALATION_PERIOD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ESCALATION_PERIOD); }); it("Duplicate dispute resolver fees", async function () { @@ -550,7 +553,7 @@ describe("DisputeResolverHandler", function () { // Create a dispute resolver await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees2, sellerAllowList) - ).to.revertedWith(RevertReasons.DUPLICATE_DISPUTE_RESOLVER_FEES); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DUPLICATE_DISPUTE_RESOLVER_FEES); }); it("Duplicate dispute resolver fees", async function () { @@ -560,7 +563,7 @@ describe("DisputeResolverHandler", function () { // Create a dispute resolver await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.NO_SUCH_SELLER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_SELLER); }); it("Some seller id is duplicated", async function () { @@ -570,7 +573,7 @@ describe("DisputeResolverHandler", function () { // Create a dispute resolver await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.SELLER_ALREADY_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_ALREADY_APPROVED); }); it("Caller is not the supplied admin", async function () { @@ -579,7 +582,7 @@ describe("DisputeResolverHandler", function () { // Create a dispute resolver await expect( accountHandler.connect(rando).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.NOT_ADMIN_AND_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN_AND_ASSISTANT); }); it("Caller is not the supplied assistant", async function () { @@ -588,7 +591,7 @@ describe("DisputeResolverHandler", function () { // Create a dispute resolver await expect( accountHandler.connect(rando).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.NOT_ADMIN_AND_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN_AND_ASSISTANT); }); it("Active is false", async function () { @@ -597,7 +600,7 @@ describe("DisputeResolverHandler", function () { // Attempt to Create a DR, expecting revert await expect( accountHandler.connect(rando).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.MUST_BE_ACTIVE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.MUST_BE_ACTIVE); }); it("Fee amount is not 0", async function () { @@ -606,7 +609,7 @@ describe("DisputeResolverHandler", function () { // Attempt to Create a DR, expecting revert await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.FEE_AMOUNT_NOT_YET_SUPPORTED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FEE_AMOUNT_NOT_YET_SUPPORTED); }); }); }); @@ -1071,7 +1074,8 @@ describe("DisputeResolverHandler", function () { ); // Attempt to update the dispute resolver with original admin address, expecting revert - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( + await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ADMIN ); }); @@ -1209,7 +1213,8 @@ describe("DisputeResolverHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.DisputeResolvers]); // Attempt to update a dispute resolver, expecting revert - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( + await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -1219,31 +1224,32 @@ describe("DisputeResolverHandler", function () { disputeResolver.id = "444"; // Attempt to update the dispute resolver, expecting revert - await expect(accountHandler.connect(other1).updateDisputeResolver(disputeResolver)).to.revertedWith( - RevertReasons.NO_SUCH_DISPUTE_RESOLVER - ); + await expect( + accountHandler.connect(other1).updateDisputeResolver(disputeResolver) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_DISPUTE_RESOLVER); // Set invalid id disputeResolver.id = "0"; // Attempt to update the dispute resolver, expecting revert - await expect(accountHandler.connect(other1).updateDisputeResolver(disputeResolver)).to.revertedWith( - RevertReasons.NO_SUCH_DISPUTE_RESOLVER - ); + await expect( + accountHandler.connect(other1).updateDisputeResolver(disputeResolver) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_DISPUTE_RESOLVER); }); it("Caller is not dispute resolver admin address", async function () { // Attempt to update the disputer resolver, expecting revert - await expect(accountHandler.connect(other2).updateDisputeResolver(disputeResolver)).to.revertedWith( - RevertReasons.NOT_ADMIN - ); + await expect( + accountHandler.connect(other2).updateDisputeResolver(disputeResolver) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN); }); it("Any address is the zero address", async function () { disputeResolver.assistant = ZeroAddress; // Attempt to update the disputer resolver, expecting revert - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( + await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ADDRESS ); @@ -1251,7 +1257,8 @@ describe("DisputeResolverHandler", function () { disputeResolver.admin = ZeroAddress; // Attempt to update the disputer resolver, expecting revert - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( + await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ADDRESS ); @@ -1259,7 +1266,8 @@ describe("DisputeResolverHandler", function () { disputeResolver.treasury = ZeroAddress; // Attempt to update the disputer resolver, expecting revert - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( + await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ADDRESS ); }); @@ -1268,7 +1276,8 @@ describe("DisputeResolverHandler", function () { disputeResolver.clerk = await rando.getAddress(); // Attempt to update the disputer resolver, expecting revert - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( + await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWithCustomError( + bosonErrors, RevertReasons.CLERK_DEPRECATED ); }); @@ -1290,7 +1299,8 @@ describe("DisputeResolverHandler", function () { disputeResolver.assistant = await other1.getAddress(); // Attempt to update dispute resolver 1 with non-unique admin address, expecting revert - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( + await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWithCustomError( + bosonErrors, RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE ); @@ -1298,7 +1308,8 @@ describe("DisputeResolverHandler", function () { disputeResolver.admin = await other1.getAddress(); // Attempt to update dispute resolver 1 with non-unique admin address, expecting revert - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( + await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWithCustomError( + bosonErrors, RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE ); }); @@ -1320,18 +1331,18 @@ describe("DisputeResolverHandler", function () { disputeResolver2.admin = await assistant.getAddress(); // Attempt to update dispute resolver 1 with non-unique admin address, expecting revert - await expect(accountHandler.connect(other1).updateDisputeResolver(disputeResolver2)).to.revertedWith( - RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE - ); + await expect( + accountHandler.connect(other1).updateDisputeResolver(disputeResolver2) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE); //Set dispute resolver 2's assistant address to dispute resolver 1's assistant address disputeResolver2.admin = await other2.getAddress(); disputeResolver2.assistant = await assistant.getAddress(); // Attempt to update dispute resolver 1 with non-unique assistant address, expecting revert - await expect(accountHandler.connect(other1).updateDisputeResolver(disputeResolver2)).to.revertedWith( - RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE - ); + await expect( + accountHandler.connect(other1).updateDisputeResolver(disputeResolver2) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE); }); it("EscalationResponsePeriod is invalid", async function () { @@ -1341,19 +1352,22 @@ describe("DisputeResolverHandler", function () { disputeResolver.escalationResponsePeriod = oneWeek + 1n; // Attempt to update a DisputeResolver, expecting revert - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( + await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ESCALATION_PERIOD ); disputeResolver.escalationResponsePeriod = 0; // Attempt to update a DisputeResolver, expecting revert - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( + await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ESCALATION_PERIOD ); }); it("No updates applied or set to pending", async function () { - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( + await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_UPDATE_APPLIED ); }); @@ -1455,7 +1469,7 @@ describe("DisputeResolverHandler", function () { // Attempt to add dispute resolver fees, expecting revert await expect( accountHandler.connect(admin).addFeesToDisputeResolver(disputeResolver.id, disputeResolverFeesToAdd) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Dispute resolver does not exist", async function () { @@ -1465,7 +1479,7 @@ describe("DisputeResolverHandler", function () { // Attempt to add fees to the dispute resolver, expecting revert await expect( accountHandler.connect(admin).addFeesToDisputeResolver(disputeResolver.id, disputeResolverFees) - ).to.revertedWith(RevertReasons.NO_SUCH_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_DISPUTE_RESOLVER); // Set invalid id disputeResolver.id = "0"; @@ -1473,14 +1487,14 @@ describe("DisputeResolverHandler", function () { // Attempt to add fees to the dispute resolver, expecting revert await expect( accountHandler.connect(admin).addFeesToDisputeResolver(disputeResolver.id, disputeResolverFees) - ).to.revertedWith(RevertReasons.NO_SUCH_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_DISPUTE_RESOLVER); }); it("Caller is not dispute resolver admin address", async function () { // Attempt to add fees to the dispute resolver, expecting revert await expect( accountHandler.connect(rando).addFeesToDisputeResolver(disputeResolver.id, disputeResolverFees) - ).to.revertedWith(RevertReasons.NOT_ADMIN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN); }); it("DisputeResolverFees empty", async function () { @@ -1489,7 +1503,7 @@ describe("DisputeResolverHandler", function () { // Attempt to add fees to the dispute resolver, expecting revert await expect( accountHandler.connect(admin).addFeesToDisputeResolver(disputeResolver.id, disputeResolverFees) - ).to.revertedWith(RevertReasons.INEXISTENT_DISPUTE_RESOLVER_FEES); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INEXISTENT_DISPUTE_RESOLVER_FEES); }); it("Duplicate dispute resolver fees", async function () { @@ -1501,7 +1515,7 @@ describe("DisputeResolverHandler", function () { // Attempt to add fees to the dispute resolver, expecting revert await expect( accountHandler.connect(admin).addFeesToDisputeResolver(disputeResolver.id, disputeResolverFees) - ).to.revertedWith(RevertReasons.DUPLICATE_DISPUTE_RESOLVER_FEES); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DUPLICATE_DISPUTE_RESOLVER_FEES); }); it("Fee amount is not 0", async function () { @@ -1510,7 +1524,7 @@ describe("DisputeResolverHandler", function () { // Attempt to Create a DR, expecting revert await expect( accountHandler.connect(admin).addFeesToDisputeResolver(disputeResolver.id, disputeResolverFees) - ).to.revertedWith(RevertReasons.FEE_AMOUNT_NOT_YET_SUPPORTED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FEE_AMOUNT_NOT_YET_SUPPORTED); }); }); }); @@ -1700,7 +1714,7 @@ describe("DisputeResolverHandler", function () { // Attempt to remove dispute resolver fees, expecting revert await expect( accountHandler.connect(admin).removeFeesFromDisputeResolver(disputeResolver.id, feeTokenAddressesToRemove) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Dispute resolver does not exist", async function () { @@ -1710,7 +1724,7 @@ describe("DisputeResolverHandler", function () { // Attempt to remove fees from the dispute resolver, expecting revert await expect( accountHandler.connect(admin).removeFeesFromDisputeResolver(disputeResolver.id, feeTokenAddressesToRemove) - ).to.revertedWith(RevertReasons.NO_SUCH_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_DISPUTE_RESOLVER); // Set invalid id disputeResolver.id = "0"; @@ -1718,14 +1732,14 @@ describe("DisputeResolverHandler", function () { // Attempt to remove fees from the dispute resolver, expecting revert await expect( accountHandler.connect(admin).removeFeesFromDisputeResolver(disputeResolver.id, feeTokenAddressesToRemove) - ).to.revertedWith(RevertReasons.NO_SUCH_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_DISPUTE_RESOLVER); }); it("Caller is not dispute resolver admin address", async function () { // Attempt to remove fees from the dispute resolver, expecting revert await expect( accountHandler.connect(rando).removeFeesFromDisputeResolver(disputeResolver.id, feeTokenAddressesToRemove) - ).to.revertedWith(RevertReasons.NOT_ADMIN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN); }); it("DisputeResolverFees empty", async function () { @@ -1734,7 +1748,7 @@ describe("DisputeResolverHandler", function () { // Attempt to remove fees from the dispute resolver, expecting revert await expect( accountHandler.connect(admin).removeFeesFromDisputeResolver(disputeResolver.id, feeTokenAddressesToRemove) - ).to.revertedWith(RevertReasons.INEXISTENT_DISPUTE_RESOLVER_FEES); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INEXISTENT_DISPUTE_RESOLVER_FEES); }); it("DisputeResolverFee in array does not exist for Dispute Resolver", async function () { @@ -1743,7 +1757,7 @@ describe("DisputeResolverHandler", function () { // Attempt to remove fees from the dispute resolver, expecting revert await expect( accountHandler.connect(admin).removeFeesFromDisputeResolver(disputeResolver.id, feeTokenAddressesToRemove) - ).to.revertedWith(RevertReasons.DISPUTE_RESOLVER_FEE_NOT_FOUND); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_RESOLVER_FEE_NOT_FOUND); }); }); }); @@ -1831,7 +1845,7 @@ describe("DisputeResolverHandler", function () { // Attempt to add sellers to a dispute resolver allow list, expecting revert await expect( accountHandler.connect(admin).addSellersToAllowList(disputeResolver.id, allowedSellersToAdd) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Dispute resolver does not exist", async function () { @@ -1841,7 +1855,7 @@ describe("DisputeResolverHandler", function () { // Attempt to add sellers to the allow list, expecting revert await expect( accountHandler.connect(admin).addSellersToAllowList(disputeResolver.id, allowedSellersToAdd) - ).to.revertedWith(RevertReasons.NO_SUCH_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_DISPUTE_RESOLVER); // Set invalid id disputeResolver.id = "0"; @@ -1849,14 +1863,14 @@ describe("DisputeResolverHandler", function () { // Attempt to add sellers to the allow list, expecting revert await expect( accountHandler.connect(admin).addSellersToAllowList(disputeResolver.id, allowedSellersToAdd) - ).to.revertedWith(RevertReasons.NO_SUCH_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_DISPUTE_RESOLVER); }); it("Caller is not dispute resolver admin address", async function () { // Attempt to add sellers to the allow list, expecting revert await expect( accountHandler.connect(rando).addSellersToAllowList(disputeResolver.id, allowedSellersToAdd) - ).to.revertedWith(RevertReasons.NOT_ADMIN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN); }); it("SellerAllowList empty", async function () { @@ -1865,7 +1879,7 @@ describe("DisputeResolverHandler", function () { // Attempt to add sellers to the allow list, expecting revert await expect( accountHandler.connect(admin).addSellersToAllowList(disputeResolver.id, allowedSellersToAdd) - ).to.revertedWith(RevertReasons.INEXISTENT_ALLOWED_SELLERS_LIST); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INEXISTENT_ALLOWED_SELLERS_LIST); }); it("Some seller does not exist", async function () { @@ -1875,7 +1889,7 @@ describe("DisputeResolverHandler", function () { // Attempt to add sellers to the allow list, expecting revert await expect( accountHandler.connect(admin).addSellersToAllowList(disputeResolver.id, allowedSellersToAdd) - ).to.revertedWith(RevertReasons.NO_SUCH_SELLER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_SELLER); }); it("Seller id is already approved", async function () { @@ -1885,7 +1899,7 @@ describe("DisputeResolverHandler", function () { // Attempt to add sellers to the allow listr, expecting revert await expect( accountHandler.connect(admin).addSellersToAllowList(disputeResolver.id, allowedSellersToAdd) - ).to.revertedWith(RevertReasons.SELLER_ALREADY_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_ALREADY_APPROVED); // Duplicate existing seller id allowedSellersToAdd = ["2", "1"]; @@ -1893,7 +1907,7 @@ describe("DisputeResolverHandler", function () { // Attempt to add sellers to the allow list, expecting revert await expect( accountHandler.connect(admin).addSellersToAllowList(disputeResolver.id, allowedSellersToAdd) - ).to.revertedWith(RevertReasons.SELLER_ALREADY_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_ALREADY_APPROVED); }); }); }); @@ -2036,7 +2050,7 @@ describe("DisputeResolverHandler", function () { // Attempt to remove sellers from a dispute resolver allow list, expecting revert await expect( accountHandler.connect(admin).removeSellersFromAllowList(disputeResolver.id, allowedSellersToRemove) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Dispute resolver does not exist", async function () { @@ -2046,7 +2060,7 @@ describe("DisputeResolverHandler", function () { // Attempt to remove sellers from the allowed list, expecting revert await expect( accountHandler.connect(admin).removeSellersFromAllowList(disputeResolver.id, allowedSellersToRemove) - ).to.revertedWith(RevertReasons.NO_SUCH_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_DISPUTE_RESOLVER); // Set invalid id disputeResolver.id = "0"; @@ -2054,14 +2068,14 @@ describe("DisputeResolverHandler", function () { // Attempt to remove sellers from the allowed list, expecting revert await expect( accountHandler.connect(admin).removeSellersFromAllowList(disputeResolver.id, allowedSellersToRemove) - ).to.revertedWith(RevertReasons.NO_SUCH_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_DISPUTE_RESOLVER); }); it("Caller is not dispute resolver admin address", async function () { // Attempt to remove sellers from the allowed list, expecting revert await expect( accountHandler.connect(rando).removeSellersFromAllowList(disputeResolver.id, allowedSellersToRemove) - ).to.revertedWith(RevertReasons.NOT_ADMIN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN); }); it("SellerAllowList empty", async function () { @@ -2070,7 +2084,7 @@ describe("DisputeResolverHandler", function () { // Attempt to remove sellers from the allowed list, expecting revert await expect( accountHandler.connect(admin).removeSellersFromAllowList(disputeResolver.id, allowedSellersToRemove) - ).to.revertedWith(RevertReasons.INEXISTENT_ALLOWED_SELLERS_LIST); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INEXISTENT_ALLOWED_SELLERS_LIST); }); it("Seller id is not approved", async function () { @@ -2089,7 +2103,7 @@ describe("DisputeResolverHandler", function () { // Attempt to remove sellers from the allowed list, expecting revert await expect( accountHandler.connect(admin).removeSellersFromAllowList(disputeResolver.id, allowedSellersToRemove) - ).to.revertedWith(RevertReasons.SELLER_NOT_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_NOT_APPROVED); // remove same id twice allowedSellersToRemove = ["2", "4", "2"]; @@ -2097,7 +2111,7 @@ describe("DisputeResolverHandler", function () { // Attempt to remove sellers from the allowed list, expecting revert await expect( accountHandler.connect(admin).removeSellersFromAllowList(disputeResolver.id, allowedSellersToRemove) - ).to.revertedWith(RevertReasons.SELLER_NOT_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_NOT_APPROVED); }); }); }); @@ -2202,7 +2216,7 @@ describe("DisputeResolverHandler", function () { accountHandler .connect(other1) .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Assistant]) - ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.UNAUTHORIZED_CALLER_UPDATE); disputeResolverPendingUpdate.assistant = ZeroAddress; disputeResolverPendingUpdate2Struct = disputeResolverPendingUpdate.toStruct(); @@ -2274,7 +2288,7 @@ describe("DisputeResolverHandler", function () { await expect( accountHandler.connect(other1).optInToDisputeResolverUpdate(disputeResolver.id, []) - ).to.revertedWith(RevertReasons.NO_PENDING_UPDATE_FOR_ACCOUNT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_PENDING_UPDATE_FOR_ACCOUNT); }); it("Caller is not the new admin", async function () { @@ -2287,7 +2301,7 @@ describe("DisputeResolverHandler", function () { accountHandler .connect(other2) .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Admin]) - ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.UNAUTHORIZED_CALLER_UPDATE); }); it("Caller is not the new assistant", async function () { @@ -2300,7 +2314,7 @@ describe("DisputeResolverHandler", function () { accountHandler .connect(other2) .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Assistant]) - ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.UNAUTHORIZED_CALLER_UPDATE); }); it("The DisputeResolvers region of protocol is paused", async function () { @@ -2313,7 +2327,7 @@ describe("DisputeResolverHandler", function () { await expect( accountHandler.connect(rando).optInToDisputeResolverUpdate(disputeResolver.id, []) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Admin is not unique to this disputeResolver", async function () { @@ -2339,7 +2353,7 @@ describe("DisputeResolverHandler", function () { accountHandler .connect(other1) .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Admin]) - ).to.revertedWith(RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE); }); it("Assistant is not unique to this disputeResolver", async function () { @@ -2365,7 +2379,7 @@ describe("DisputeResolverHandler", function () { accountHandler .connect(other1) .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Assistant]) - ).to.revertedWith(RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE); }); it("Dispute resolver tries to update the clerk", async function () { @@ -2378,7 +2392,7 @@ describe("DisputeResolverHandler", function () { accountHandler .connect(other2) .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Clerk]) - ).to.revertedWith(RevertReasons.CLERK_DEPRECATED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CLERK_DEPRECATED); }); }); }); diff --git a/test/protocol/ExchangeHandlerTest.js b/test/protocol/ExchangeHandlerTest.js index 1963a67ec..9c877da10 100644 --- a/test/protocol/ExchangeHandlerTest.js +++ b/test/protocol/ExchangeHandlerTest.js @@ -132,6 +132,7 @@ describe("IBosonExchangeHandler", function () { let protocolDiamondAddress; let snapshotId; let tokenId; + let bosonErrors; before(async function () { accountId.next(true); @@ -174,9 +175,7 @@ describe("IBosonExchangeHandler", function () { diamondAddress: protocolDiamondAddress, } = await setupTestEnvironment(contracts)); - // // Voucher contract - // const bosonVoucherProxyAddress = await calculateBosonProxyAddress(protocolDiamondAddress); - // bosonVoucher = await getContractAt("IBosonVoucher", bosonVoucherProxyAddress); + bosonErrors = await getContractAt("BosonErrors", protocolDiamondAddress); [deployer] = await getSigners(); @@ -189,7 +188,7 @@ describe("IBosonExchangeHandler", function () { [foreign20, foreign721, foreign1155] = await deployMockTokens(["Foreign20", "Foreign721", "Foreign1155"]); // Get the beacon proxy address - beaconProxyAddress = await calculateBosonProxyAddress(await configHandler.getAddress()); + beaconProxyAddress = await calculateBosonProxyAddress(protocolDiamondAddress); // Get snapshot id snapshotId = await getSnapshot(); @@ -789,7 +788,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to create an exchange, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The buyers region of protocol is paused", async function () { @@ -799,14 +798,14 @@ describe("IBosonExchangeHandler", function () { // Attempt to create a buyer, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("buyer.address is the zero address", async function () { // Attempt to commit, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(ZeroAddress, offerId, { value: price }) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("offer id is invalid", async function () { @@ -816,7 +815,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to commit, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }) - ).to.revertedWith(RevertReasons.NO_SUCH_OFFER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); }); it("offer is voided", async function () { @@ -826,7 +825,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to commit to the voided offer, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_HAS_BEEN_VOIDED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); }); it("offer is not yet available for commits", async function () { @@ -845,7 +844,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to commit to the not available offer, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), ++offerId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_NOT_AVAILABLE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_NOT_AVAILABLE); }); it("offer has expired", async function () { @@ -855,7 +854,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to commit to the expired offer, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_EXPIRED); }); it("offer sold", async function () { @@ -870,7 +869,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to commit to the sold out offer, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_SOLD_OUT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_SOLD_OUT); }); it("Offer belongs to a group with condition", async function () { @@ -889,7 +888,7 @@ describe("IBosonExchangeHandler", function () { await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }) - ).to.revertedWith(RevertReasons.GROUP_HAS_CONDITION); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.GROUP_HAS_CONDITION); }); }); }); @@ -1350,7 +1349,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The buyers region of protocol is paused", async function () { @@ -1362,7 +1361,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Caller is not the voucher contract, owned by the seller", async function () { @@ -1376,7 +1375,7 @@ describe("IBosonExchangeHandler", function () { await assistant.getAddress(), await assistant.getAddress() ) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("Exchange exists already", async function () { @@ -1402,7 +1401,7 @@ describe("IBosonExchangeHandler", function () { await assistant.getAddress(), await assistant.getAddress() ) - ).to.revertedWith(RevertReasons.EXCHANGE_ALREADY_EXISTS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.EXCHANGE_ALREADY_EXISTS); }); it("offer is voided", async function () { @@ -1414,7 +1413,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.OFFER_HAS_BEEN_VOIDED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); }); it("offer is not yet available for commits", async function () { @@ -1445,7 +1444,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.OFFER_NOT_AVAILABLE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_NOT_AVAILABLE); }); it("offer has expired", async function () { @@ -1457,7 +1456,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.OFFER_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_EXPIRED); }); it("should not be able to commit directly if whole offer preminted", async function () { @@ -1472,7 +1471,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to commit to the sold out offer, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_SOLD_OUT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_SOLD_OUT); }); it("buyer does not meet condition for commit", async function () { @@ -1501,7 +1500,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); it("Offer is part of a group with condition [ERC721, specificToken, gating per address] with length > 1", async function () { @@ -1532,7 +1531,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); it("Offer is part of a group with condition [ERC721, specificToken, gating per tokenId] with length > 1", async function () { @@ -1563,7 +1562,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); it("Offer is part of a group with condition [ERC1155, gating per address] with length > 1", async function () { @@ -1594,7 +1593,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); it("Offer is part of a group with condition [ERC1155, gating per tokenId] with length > 1", async function () { @@ -1625,7 +1624,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); }); }); @@ -1688,7 +1687,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, 0, { value: price }) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); it("buyer has exhausted allowable commits", async function () { @@ -1707,7 +1706,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, 0, { value: price }) - ).to.revertedWith(RevertReasons.MAX_COMMITS_REACHED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.MAX_COMMITS_REACHED); }); it("Group doesn't exist", async function () { @@ -1720,7 +1719,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), ++offerId, 0, { value: price }) - ).to.revertedWith(RevertReasons.NO_SUCH_GROUP); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_GROUP); }); it("Caller sends non-zero tokenId", async function () {}); @@ -1728,7 +1727,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, 1, { value: price }) - ).to.revertedWith(RevertReasons.INVALID_TOKEN_ID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_TOKEN_ID); }); }); @@ -1795,7 +1794,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, 0, { value: price }) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); it("buyer has exhausted allowable commits", async function () { @@ -1814,7 +1813,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, 0, { value: price }) - ).to.revertedWith(RevertReasons.MAX_COMMITS_REACHED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.MAX_COMMITS_REACHED); }); it("Caller sends non-zero tokenId", async function () { @@ -1822,7 +1821,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, 1, { value: price }) - ).to.revertedWith(RevertReasons.INVALID_TOKEN_ID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_TOKEN_ID); }); }); }); @@ -1923,7 +1922,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); it("max commits per token id reached", async function () { @@ -1939,7 +1938,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.MAX_COMMITS_REACHED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.MAX_COMMITS_REACHED); }); it("token id not in condition range", async function () { @@ -1949,7 +1948,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); }); }); }); @@ -2051,7 +2050,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); it("max commits per token id reached", async function () { @@ -2067,7 +2066,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.MAX_COMMITS_REACHED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.MAX_COMMITS_REACHED); }); it("token id not in condition range", async function () { @@ -2077,7 +2076,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); }); }); }); @@ -2154,7 +2153,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); it("buyer has exhausted allowable commits", async function () { @@ -2173,7 +2172,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.MAX_COMMITS_REACHED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.MAX_COMMITS_REACHED); }); }); }); @@ -2263,14 +2262,14 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); it("buyer does not meet condition for commit", async function () { // Attempt to commit, expecting revert await expect( exchangeHandler.connect(rando).commitToConditionalOffer(rando.address, offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.CANNOT_COMMIT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CANNOT_COMMIT); }); it("max commits per token id reached", async function () { @@ -2286,7 +2285,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.MAX_COMMITS_REACHED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.MAX_COMMITS_REACHED); }); it("token id not in condition range", async function () { @@ -2296,7 +2295,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); }); }); }); @@ -2340,7 +2339,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The buyers region of protocol is paused", async function () { @@ -2352,14 +2351,14 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("await buyer.getAddress() is the zero address", async function () { // Attempt to commit, expecting revert await expect( exchangeHandler.connect(buyer).commitToConditionalOffer(ZeroAddress, offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("offer id is invalid", async function () { @@ -2371,7 +2370,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.NO_SUCH_OFFER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); }); it("offer is voided", async function () { @@ -2383,7 +2382,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_HAS_BEEN_VOIDED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); }); it("offer is not yet available for commits", async function () { @@ -2408,7 +2407,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_NOT_AVAILABLE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_NOT_AVAILABLE); }); it("offer has expired", async function () { @@ -2420,7 +2419,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_EXPIRED); }); it("offer sold", async function () { @@ -2443,7 +2442,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_SOLD_OUT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_SOLD_OUT); }); it("Group without condition", async function () { @@ -2472,7 +2471,7 @@ describe("IBosonExchangeHandler", function () { exchangeHandler .connect(buyer) .commitToConditionalOffer(await buyer.getAddress(), offerId, tokenId, { value: price }) - ).to.revertedWith(RevertReasons.GROUP_HAS_NO_CONDITION); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.GROUP_HAS_NO_CONDITION); }); }); }); @@ -2585,7 +2584,8 @@ describe("IBosonExchangeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Exchanges]); // Attempt to complete an exchange, expecting revert - await expect(exchangeHandler.connect(assistant).completeExchange(exchangeId)).to.revertedWith( + await expect(exchangeHandler.connect(assistant).completeExchange(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -2595,7 +2595,8 @@ describe("IBosonExchangeHandler", function () { exchangeId = "666"; // Attempt to complete the exchange, expecting revert - await expect(exchangeHandler.connect(assistant).completeExchange(exchangeId)).to.revertedWith( + await expect(exchangeHandler.connect(assistant).completeExchange(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_EXCHANGE ); }); @@ -2608,7 +2609,8 @@ describe("IBosonExchangeHandler", function () { assert.equal(response, ExchangeState.Committed, "Exchange state is incorrect"); // Attempt to complete the exchange, expecting revert - await expect(exchangeHandler.connect(assistant).completeExchange(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(assistant).completeExchange(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); @@ -2618,7 +2620,8 @@ describe("IBosonExchangeHandler", function () { await exchangeHandler.connect(buyer).cancelVoucher(exchange.id); // Attempt to complete the exchange, expecting revert - await expect(exchangeHandler.connect(assistant).completeExchange(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(assistant).completeExchange(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); @@ -2631,7 +2634,8 @@ describe("IBosonExchangeHandler", function () { await exchangeHandler.connect(buyer).redeemVoucher(exchange.id); // Attempt to complete the exchange, expecting revert - await expect(exchangeHandler.connect(rando).completeExchange(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(rando).completeExchange(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.DISPUTE_PERIOD_NOT_ELAPSED ); }); @@ -2647,7 +2651,8 @@ describe("IBosonExchangeHandler", function () { await accountHandler.connect(rando).createBuyer(mockBuyer(await rando.getAddress())); // Attempt to complete the exchange, expecting revert - await expect(exchangeHandler.connect(rando).completeExchange(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(rando).completeExchange(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.DISPUTE_PERIOD_NOT_ELAPSED ); }); @@ -2660,7 +2665,8 @@ describe("IBosonExchangeHandler", function () { await exchangeHandler.connect(buyer).redeemVoucher(exchange.id); // Attempt to complete the exchange, expecting revert - await expect(exchangeHandler.connect(assistant).completeExchange(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(assistant).completeExchange(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.DISPUTE_PERIOD_NOT_ELAPSED ); }); @@ -2790,9 +2796,9 @@ describe("IBosonExchangeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Exchanges]); // Attempt to complete an exchange, expecting revert - await expect(exchangeHandler.connect(buyer).completeExchangeBatch(exchangesToComplete)).to.revertedWith( - RevertReasons.REGION_PAUSED - ); + await expect( + exchangeHandler.connect(buyer).completeExchangeBatch(exchangesToComplete) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("exchange id is invalid", async function () { @@ -2803,9 +2809,9 @@ describe("IBosonExchangeHandler", function () { exchangesToComplete = [exchangeId, ...exchangesToComplete]; // Attempt to complete the exchange, expecting revert - await expect(exchangeHandler.connect(assistant).completeExchangeBatch(exchangesToComplete)).to.revertedWith( - RevertReasons.NO_SUCH_EXCHANGE - ); + await expect( + exchangeHandler.connect(assistant).completeExchangeBatch(exchangesToComplete) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("exchange is not in redeemed state", async function () { @@ -2820,9 +2826,9 @@ describe("IBosonExchangeHandler", function () { exchangesToComplete = [exchangeId, ...exchangesToComplete]; // Attempt to complete the exchange, expecting revert - await expect(exchangeHandler.connect(assistant).completeExchangeBatch(exchangesToComplete)).to.revertedWith( - RevertReasons.INVALID_STATE - ); + await expect( + exchangeHandler.connect(assistant).completeExchangeBatch(exchangesToComplete) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("caller is not buyer and offer dispute period has not elapsed", async function () { @@ -2838,9 +2844,9 @@ describe("IBosonExchangeHandler", function () { exchangesToComplete = [exchangeId, ...exchangesToComplete]; // Attempt to complete the exchange, expecting revert - await expect(exchangeHandler.connect(rando).completeExchangeBatch(exchangesToComplete)).to.revertedWith( - RevertReasons.DISPUTE_PERIOD_NOT_ELAPSED - ); + await expect( + exchangeHandler.connect(rando).completeExchangeBatch(exchangesToComplete) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_PERIOD_NOT_ELAPSED); }); it("caller is seller's assistant and offer dispute period has not elapsed", async function () { @@ -2853,9 +2859,9 @@ describe("IBosonExchangeHandler", function () { await exchangeHandler.connect(buyer).redeemVoucher(exchangeId); // Attempt to complete the exchange, expecting revert - await expect(exchangeHandler.connect(assistant).completeExchangeBatch(exchangesToComplete)).to.revertedWith( - RevertReasons.DISPUTE_PERIOD_NOT_ELAPSED - ); + await expect( + exchangeHandler.connect(assistant).completeExchangeBatch(exchangesToComplete) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_PERIOD_NOT_ELAPSED); }); }); }); @@ -2924,7 +2930,8 @@ describe("IBosonExchangeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Exchanges]); // Attempt to complete an exchange, expecting revert - await expect(exchangeHandler.connect(assistant).revokeVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(assistant).revokeVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -2934,7 +2941,8 @@ describe("IBosonExchangeHandler", function () { exchangeId = "666"; // Attempt to revoke the voucher, expecting revert - await expect(exchangeHandler.connect(assistant).revokeVoucher(exchangeId)).to.revertedWith( + await expect(exchangeHandler.connect(assistant).revokeVoucher(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_EXCHANGE ); }); @@ -2944,14 +2952,16 @@ describe("IBosonExchangeHandler", function () { await exchangeHandler.connect(buyer).cancelVoucher(exchange.id); // Attempt to revoke the voucher, expecting revert - await expect(exchangeHandler.connect(assistant).revokeVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(assistant).revokeVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); it("caller is not seller's assistant", async function () { // Attempt to complete the exchange, expecting revert - await expect(exchangeHandler.connect(rando).revokeVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(rando).revokeVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ASSISTANT ); }); @@ -3039,7 +3049,8 @@ describe("IBosonExchangeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Exchanges]); // Attempt to complete an exchange, expecting revert - await expect(exchangeHandler.connect(buyer).cancelVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).cancelVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -3049,7 +3060,8 @@ describe("IBosonExchangeHandler", function () { exchangeId = "666"; // Attempt to cancel the voucher, expecting revert - await expect(exchangeHandler.connect(buyer).cancelVoucher(exchangeId)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).cancelVoucher(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_EXCHANGE ); }); @@ -3068,7 +3080,8 @@ describe("IBosonExchangeHandler", function () { assert.equal(response, ExchangeState.Redeemed, "Exchange state is incorrect"); // Attempt to cancel the voucher, expecting revert - await expect(exchangeHandler.connect(buyer).cancelVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).cancelVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); @@ -3078,14 +3091,16 @@ describe("IBosonExchangeHandler", function () { await exchangeHandler.connect(assistant).revokeVoucher(exchange.id); // Attempt to cancel the voucher, expecting revert - await expect(exchangeHandler.connect(buyer).cancelVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).cancelVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); it("caller does not own voucher", async function () { // Attempt to cancel the voucher, expecting revert - await expect(exchangeHandler.connect(rando).cancelVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(rando).cancelVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER ); }); @@ -3096,7 +3111,8 @@ describe("IBosonExchangeHandler", function () { await mockMetaTransactionsHandler.setAsMetaTransactionAndCurrentSenderAs(ZeroAddress); // Attempt to cancel the voucher, expecting revert - await expect(exchangeHandler.connect(rando).cancelVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(rando).cancelVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ADDRESS ); }); @@ -3157,7 +3173,8 @@ describe("IBosonExchangeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Exchanges]); // Attempt to complete an exchange, expecting revert - await expect(exchangeHandler.connect(buyer).expireVoucher(exchangeId)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).expireVoucher(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -3170,7 +3187,8 @@ describe("IBosonExchangeHandler", function () { exchangeId = "666"; // Attempt to cancel the voucher, expecting revert - await expect(exchangeHandler.connect(buyer).expireVoucher(exchangeId)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).expireVoucher(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_EXCHANGE ); }); @@ -3189,7 +3207,8 @@ describe("IBosonExchangeHandler", function () { assert.equal(response, ExchangeState.Redeemed, "Exchange state is incorrect"); // Attempt to expire the voucher, expecting revert - await expect(exchangeHandler.connect(buyer).expireVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).expireVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); @@ -3202,14 +3221,16 @@ describe("IBosonExchangeHandler", function () { await exchangeHandler.connect(assistant).revokeVoucher(exchange.id); // Attempt to expire the voucher, expecting revert - await expect(exchangeHandler.connect(buyer).expireVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).expireVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); it("Redemption period has not yet elapsed", async function () { // Attempt to cancel the voucher, expecting revert - await expect(exchangeHandler.connect(rando).expireVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(rando).expireVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.VOUCHER_STILL_VALID ); @@ -3217,7 +3238,8 @@ describe("IBosonExchangeHandler", function () { await setNextBlockTimestamp(Number(voucherRedeemableFrom) + Number(voucherValid)); // Attempt to cancel the voucher, expecting revert - await expect(exchangeHandler.connect(rando).expireVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(rando).expireVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.VOUCHER_STILL_VALID ); }); @@ -3308,7 +3330,8 @@ describe("IBosonExchangeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Exchanges]); // Attempt to complete an exchange, expecting revert - await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -3318,7 +3341,8 @@ describe("IBosonExchangeHandler", function () { exchangeId = "666"; // Attempt to redeem the voucher, expecting revert - await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_EXCHANGE ); }); @@ -3328,21 +3352,24 @@ describe("IBosonExchangeHandler", function () { await exchangeHandler.connect(assistant).revokeVoucher(exchange.id); // Attempt to redeem the voucher, expecting revert - await expect(exchangeHandler.connect(buyer).redeemVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).redeemVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_STATE ); }); it("caller does not own voucher", async function () { // Attempt to redeem the voucher, expecting revert - await expect(exchangeHandler.connect(rando).redeemVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(rando).redeemVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER ); }); it("current time is prior to offer's voucherRedeemableFrom", async function () { // Attempt to redeem the voucher, expecting revert - await expect(exchangeHandler.connect(buyer).redeemVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).redeemVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.VOUCHER_NOT_REDEEMABLE ); }); @@ -3352,7 +3379,8 @@ describe("IBosonExchangeHandler", function () { await setNextBlockTimestamp(Number(voucherRedeemableFrom) + Number(voucherValid) + 1); // Attempt to redeem the voucher, expecting revert - await expect(exchangeHandler.connect(buyer).redeemVoucher(exchange.id)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).redeemVoucher(exchange.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.VOUCHER_NOT_REDEEMABLE ); }); @@ -5726,9 +5754,9 @@ describe("IBosonExchangeHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Exchanges]); // Attempt to complete an exchange, expecting revert - await expect(exchangeHandler.connect(assistant).extendVoucher(exchange.id, validUntilDate)).to.revertedWith( - RevertReasons.REGION_PAUSED - ); + await expect( + exchangeHandler.connect(assistant).extendVoucher(exchange.id, validUntilDate) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("exchange id is invalid", async function () { @@ -5736,9 +5764,9 @@ describe("IBosonExchangeHandler", function () { exchangeId = "666"; // Attempt to extend voucher, expecting revert - await expect(exchangeHandler.connect(assistant).extendVoucher(exchangeId, validUntilDate)).to.revertedWith( - RevertReasons.NO_SUCH_EXCHANGE - ); + await expect( + exchangeHandler.connect(assistant).extendVoucher(exchangeId, validUntilDate) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("exchange is not in committed state", async function () { @@ -5746,16 +5774,16 @@ describe("IBosonExchangeHandler", function () { await exchangeHandler.connect(buyer).cancelVoucher(exchange.id); // Attempt to extend voucher, expecting revert - await expect(exchangeHandler.connect(assistant).extendVoucher(exchange.id, validUntilDate)).to.revertedWith( - RevertReasons.INVALID_STATE - ); + await expect( + exchangeHandler.connect(assistant).extendVoucher(exchange.id, validUntilDate) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("caller is not seller's assistant", async function () { // Attempt to extend voucher, expecting revert - await expect(exchangeHandler.connect(rando).extendVoucher(exchange.id, validUntilDate)).to.revertedWith( - RevertReasons.NOT_ASSISTANT - ); + await expect( + exchangeHandler.connect(rando).extendVoucher(exchange.id, validUntilDate) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("new date is not later than the current one", async function () { @@ -5763,9 +5791,9 @@ describe("IBosonExchangeHandler", function () { validUntilDate = BigInt(voucher.validUntilDate) - oneMonth; // Attempt to extend voucher, expecting revert - await expect(exchangeHandler.connect(assistant).extendVoucher(exchange.id, validUntilDate)).to.revertedWith( - RevertReasons.VOUCHER_EXTENSION_NOT_VALID - ); + await expect( + exchangeHandler.connect(assistant).extendVoucher(exchange.id, validUntilDate) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VOUCHER_EXTENSION_NOT_VALID); }); }); }); @@ -5937,14 +5965,14 @@ describe("IBosonExchangeHandler", function () { bosonVoucherClone .connect(buyer) .transferFrom(await buyer.getAddress(), await newOwner.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Caller is not a clone address", async function () { // Attempt to call onVoucherTransferred, expecting revert await expect( exchangeHandler.connect(rando).onVoucherTransferred(exchange.id, await newOwner.getAddress()) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("Caller is not a clone address associated with the seller", async function () { @@ -5978,7 +6006,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucherClone2 .connect(buyer) .transferFrom(await buyer.getAddress(), await newOwner.getAddress(), exchange.id) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("exchange id is invalid", async function () { @@ -5988,7 +6016,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to call onVoucherTransferred, expecting revert await expect( exchangeHandler.connect(fauxClient).onVoucherTransferred(exchangeId, await newOwner.getAddress()) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("exchange is not in committed state", async function () { @@ -5998,7 +6026,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to call onVoucherTransferred, expecting revert await expect( exchangeHandler.connect(fauxClient).onVoucherTransferred(exchangeId, await newOwner.getAddress()) - ).to.revertedWith(RevertReasons.INVALID_STATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("Voucher has expired", async function () { @@ -6008,7 +6036,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to call onVoucherTransferred, expecting revert await expect( exchangeHandler.connect(fauxClient).onVoucherTransferred(exchangeId, await newOwner.getAddress()) - ).to.revertedWith(RevertReasons.VOUCHER_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VOUCHER_HAS_EXPIRED); }); }); }); @@ -6177,14 +6205,14 @@ describe("IBosonExchangeHandler", function () { bosonVoucherClone .connect(buyer) .transferFrom(await buyer.getAddress(), await newOwner.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Caller is not a clone address", async function () { // Attempt to call onVoucherTransferred, expecting revert await expect( exchangeHandler.connect(rando).onVoucherTransferred(exchange.id, await newOwner.getAddress()) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("Caller is not a clone address associated with the seller", async function () { @@ -6218,7 +6246,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucherClone2 .connect(buyer) .transferFrom(await buyer.getAddress(), await newOwner.getAddress(), exchange.id) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("exchange id is invalid", async function () { @@ -6228,7 +6256,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to call onVoucherTransferred, expecting revert await expect( exchangeHandler.connect(fauxClient).onVoucherTransferred(exchangeId, await newOwner.getAddress()) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("exchange is not in committed state", async function () { @@ -6238,7 +6266,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to call onVoucherTransferred, expecting revert await expect( exchangeHandler.connect(fauxClient).onVoucherTransferred(exchangeId, await newOwner.getAddress()) - ).to.revertedWith(RevertReasons.INVALID_STATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("Voucher has expired", async function () { @@ -6248,7 +6276,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to call onVoucherTransferred, expecting revert await expect( exchangeHandler.connect(fauxClient).onVoucherTransferred(exchangeId, await newOwner.getAddress()) - ).to.revertedWith(RevertReasons.VOUCHER_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VOUCHER_HAS_EXPIRED); }); }); }); @@ -7334,7 +7362,8 @@ describe("IBosonExchangeHandler", function () { context("💔 Revert Reasons", async function () { it("Exchange is not in a final state", async function () { - await expect(exchangeHandler.connect(rando).getReceipt(exchange.id)).to.be.revertedWith( + await expect(exchangeHandler.connect(rando).getReceipt(exchange.id)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.EXCHANGE_IS_NOT_IN_A_FINAL_STATE ); }); @@ -7342,7 +7371,8 @@ describe("IBosonExchangeHandler", function () { it("Exchange id is invalid", async function () { const invalidExchangeId = "666"; - await expect(exchangeHandler.connect(rando).getReceipt(invalidExchangeId)).to.be.revertedWith( + await expect(exchangeHandler.connect(rando).getReceipt(invalidExchangeId)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_EXCHANGE ); }); @@ -7507,9 +7537,9 @@ describe("IBosonExchangeHandler", function () { context("💔 Revert Reasons", async function () { it("Caller sends non-zero tokenId", async function () {}); - await expect(exchangeHandler.connect(buyer).isEligibleToCommit(buyer.address, offerId, 1)).to.revertedWith( - RevertReasons.INVALID_TOKEN_ID - ); + await expect( + exchangeHandler.connect(buyer).isEligibleToCommit(buyer.address, offerId, 1) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_TOKEN_ID); }); }); @@ -7588,9 +7618,9 @@ describe("IBosonExchangeHandler", function () { context("💔 Revert Reasons", async function () { it("Caller sends non-zero tokenId", async function () { - await expect(exchangeHandler.connect(buyer).isEligibleToCommit(buyer.address, offerId, 1)).to.revertedWith( - RevertReasons.INVALID_TOKEN_ID - ); + await expect( + exchangeHandler.connect(buyer).isEligibleToCommit(buyer.address, offerId, 1) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_TOKEN_ID); }); }); }); @@ -7708,7 +7738,7 @@ describe("IBosonExchangeHandler", function () { tokenId = "666"; await expect( exchangeHandler.connect(buyer).isEligibleToCommit(buyer.address, offerId, tokenId) - ).to.revertedWith(RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); }); }); }); @@ -7827,7 +7857,7 @@ describe("IBosonExchangeHandler", function () { await expect( exchangeHandler.connect(buyer).isEligibleToCommit(buyer.address, offerId, tokenId) - ).to.revertedWith(RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); }); }); }); @@ -8017,7 +8047,7 @@ describe("IBosonExchangeHandler", function () { // Attempt to commit, expecting revert await expect( exchangeHandler.connect(buyer).isEligibleToCommit(buyer.address, offerId, tokenId) - ).to.revertedWith(RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_ID_NOT_IN_CONDITION_RANGE); }); }); }); @@ -8026,17 +8056,17 @@ describe("IBosonExchangeHandler", function () { it("offer does not exist", async function () { offerId = "999"; - await expect(exchangeHandler.connect(buyer).isEligibleToCommit(buyer.address, offerId, 0)).to.revertedWith( - RevertReasons.NO_SUCH_OFFER - ); + await expect( + exchangeHandler.connect(buyer).isEligibleToCommit(buyer.address, offerId, 0) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); }); it("offer is voided", async function () { await offerHandler.connect(assistant).voidOffer(offerId); - await expect(exchangeHandler.connect(buyer).isEligibleToCommit(buyer.address, offerId, 0)).to.revertedWith( - RevertReasons.OFFER_HAS_BEEN_VOIDED - ); + await expect( + exchangeHandler.connect(buyer).isEligibleToCommit(buyer.address, offerId, 0) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); }); }); }); diff --git a/test/protocol/FundsHandlerTest.js b/test/protocol/FundsHandlerTest.js index 600620a2d..a943f5290 100644 --- a/test/protocol/FundsHandlerTest.js +++ b/test/protocol/FundsHandlerTest.js @@ -104,6 +104,7 @@ describe("IBosonFundsHandler", function () { let snapshotId; let priceDiscoveryContract; let beaconProxyAddress; + let bosonErrors; before(async function () { accountId.next(true); @@ -155,6 +156,8 @@ describe("IBosonFundsHandler", function () { extraReturnValues: { accessController }, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", protocolDiamondAddress); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -171,7 +174,7 @@ describe("IBosonFundsHandler", function () { await priceDiscoveryContract.waitForDeployment(); // Get the beacon proxy address - beaconProxyAddress = await calculateBosonProxyAddress(await configHandler.getAddress()); + beaconProxyAddress = await calculateBosonProxyAddress(protocolDiamondAddress); // Get snapshot id snapshotId = await getSnapshot(); @@ -311,7 +314,7 @@ describe("IBosonFundsHandler", function () { // Attempt to deposit funds, expecting revert await expect( fundsHandler.connect(assistant).depositFunds(seller.id, await mockToken.getAddress(), depositAmount) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Amount to deposit is zero", async function () { @@ -320,7 +323,7 @@ describe("IBosonFundsHandler", function () { // Attempt to deposit funds, expecting revert await expect( fundsHandler.connect(assistant).depositFunds(seller.id, await mockToken.getAddress(), depositAmount) - ).to.revertedWith(RevertReasons.ZERO_DEPOSIT_NOT_ALLOWED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ZERO_DEPOSIT_NOT_ALLOWED); }); it("Seller id does not exist", async function () { @@ -328,7 +331,7 @@ describe("IBosonFundsHandler", function () { seller.id = "555"; await expect( fundsHandler.connect(rando).depositFunds(seller.id, await mockToken.getAddress(), depositAmount) - ).to.revertedWith(RevertReasons.NO_SUCH_SELLER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_SELLER); }); it("Native currency deposited, but the token address is not zero", async function () { @@ -337,7 +340,7 @@ describe("IBosonFundsHandler", function () { fundsHandler .connect(rando) .depositFunds(seller.id, await mockToken.getAddress(), depositAmount, { value: depositAmount }) - ).to.revertedWith(RevertReasons.NATIVE_WRONG_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NATIVE_WRONG_ADDRESS); }); it("Native currency deposited, but the amount does not match msg.value", async function () { @@ -346,7 +349,7 @@ describe("IBosonFundsHandler", function () { fundsHandler .connect(rando) .depositFunds(seller.id, ZeroAddress, depositAmount * 2n, { value: depositAmount }) - ).to.revertedWith(RevertReasons.NATIVE_WRONG_AMOUNT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NATIVE_WRONG_AMOUNT); }); it("Token address contract does not support transferFrom", async function () { @@ -361,9 +364,9 @@ describe("IBosonFundsHandler", function () { it("No native currency deposited and token address is zero", async function () { // Attempt to deposit the funds, expecting revert - await expect(fundsHandler.connect(rando).depositFunds(seller.id, ZeroAddress, depositAmount)).to.revertedWith( - RevertReasons.INVALID_ADDRESS - ); + await expect( + fundsHandler.connect(rando).depositFunds(seller.id, ZeroAddress, depositAmount) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("Token address is not a contract", async function () { @@ -400,7 +403,7 @@ describe("IBosonFundsHandler", function () { // Attempt to deposit funds, expecting revert await expect( fundsHandler.connect(assistant).depositFunds(seller.id, await Foreign20WithFee.getAddress(), depositAmount) - ).to.revertedWith(RevertReasons.INSUFFICIENT_VALUE_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_VALUE_RECEIVED); }); it("ERC20 transferFrom returns false", async function () { @@ -856,22 +859,25 @@ describe("IBosonFundsHandler", function () { // Attempt to withdraw funds, expecting revert await expect( fundsHandler.connect(buyer).withdrawFunds(buyerId, tokenListBuyer, tokenAmountsBuyer) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Caller is not authorized to withdraw", async function () { // Attempt to withdraw the buyer funds, expecting revert - await expect(fundsHandler.connect(rando).withdrawFunds(buyerId, [], [])).to.revertedWith( + await expect(fundsHandler.connect(rando).withdrawFunds(buyerId, [], [])).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_AUTHORIZED ); // Attempt to withdraw the seller funds, expecting revert - await expect(fundsHandler.connect(rando).withdrawFunds(seller.id, [], [])).to.revertedWith( + await expect(fundsHandler.connect(rando).withdrawFunds(seller.id, [], [])).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_AUTHORIZED ); // Attempt to withdraw the seller funds as treasury, expecting revert - await expect(fundsHandler.connect(treasury).withdrawFunds(seller.id, [], [])).to.revertedWith( + await expect(fundsHandler.connect(treasury).withdrawFunds(seller.id, [], [])).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_AUTHORIZED ); }); @@ -884,7 +890,7 @@ describe("IBosonFundsHandler", function () { // Attempt to withdraw the funds, expecting revert await expect( fundsHandler.connect(assistant).withdrawFunds(seller.id, tokenList, tokenAmounts) - ).to.revertedWith(RevertReasons.TOKEN_AMOUNT_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_AMOUNT_MISMATCH); }); it("Caller tries to withdraw more than they have in the available funds", async function () { @@ -895,7 +901,7 @@ describe("IBosonFundsHandler", function () { // Attempt to withdraw the funds, expecting revert await expect( fundsHandler.connect(assistant).withdrawFunds(seller.id, tokenList, tokenAmounts) - ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); }); it("Caller tries to withdraw the same token twice", async function () { @@ -906,7 +912,7 @@ describe("IBosonFundsHandler", function () { // Attempt to withdraw the funds, expecting revert await expect( fundsHandler.connect(assistant).withdrawFunds(seller.id, tokenList, tokenAmounts) - ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); }); it("Nothing to withdraw", async function () { @@ -916,13 +922,14 @@ describe("IBosonFundsHandler", function () { await expect( fundsHandler.connect(assistant).withdrawFunds(seller.id, tokenList, tokenAmounts) - ).to.revertedWith(RevertReasons.NOTHING_TO_WITHDRAW); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOTHING_TO_WITHDRAW); // first withdraw everything await fundsHandler.connect(assistant).withdrawFunds(seller.id, [], []); // Attempt to withdraw the funds, expecting revert - await expect(fundsHandler.connect(assistant).withdrawFunds(seller.id, [], [])).to.revertedWith( + await expect(fundsHandler.connect(assistant).withdrawFunds(seller.id, [], [])).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOTHING_TO_WITHDRAW ); }); @@ -951,7 +958,7 @@ describe("IBosonFundsHandler", function () { [ZeroAddress], [offerNative.price] ) - ).to.revertedWith(RevertReasons.TOKEN_TRANSFER_FAILED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_TRANSFER_FAILED); }); it("Transfer of funds failed - no payable fallback or receive", async function () { @@ -978,7 +985,7 @@ describe("IBosonFundsHandler", function () { [ZeroAddress], [offerNative.price] ) - ).to.revertedWith(RevertReasons.TOKEN_TRANSFER_FAILED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_TRANSFER_FAILED); }); it("Transfer of funds failed - ERC20 token does not exist anymore", async function () { @@ -1222,12 +1229,13 @@ describe("IBosonFundsHandler", function () { // Attempt to withdraw funds, expecting revert await expect( fundsHandler.connect(feeCollector).withdrawProtocolFees(tokenList, tokenAmounts) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Caller is not authorized to withdraw", async function () { // Attempt to withdraw the protocol fees, expecting revert - await expect(fundsHandler.connect(rando).withdrawProtocolFees([], [])).to.revertedWith( + await expect(fundsHandler.connect(rando).withdrawProtocolFees([], [])).to.revertedWithCustomError( + bosonErrors, RevertReasons.ACCESS_DENIED ); }); @@ -1240,7 +1248,7 @@ describe("IBosonFundsHandler", function () { // Attempt to withdraw the funds, expecting revert await expect( fundsHandler.connect(feeCollector).withdrawProtocolFees(tokenList, tokenAmounts) - ).to.revertedWith(RevertReasons.TOKEN_AMOUNT_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_AMOUNT_MISMATCH); }); it("Caller tries to withdraw more than they have in the available funds", async function () { @@ -1251,7 +1259,7 @@ describe("IBosonFundsHandler", function () { // Attempt to withdraw the funds, expecting revert await expect( fundsHandler.connect(feeCollector).withdrawProtocolFees(tokenList, tokenAmounts) - ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); }); it("Caller tries to withdraw the same token twice", async function () { @@ -1262,7 +1270,7 @@ describe("IBosonFundsHandler", function () { // Attempt to withdraw the funds, expecting revert await expect( fundsHandler.connect(feeCollector).withdrawProtocolFees(tokenList, tokenAmounts) - ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); }); it("Nothing to withdraw", async function () { @@ -1272,13 +1280,14 @@ describe("IBosonFundsHandler", function () { await expect( fundsHandler.connect(feeCollector).withdrawProtocolFees(tokenList, tokenAmounts) - ).to.revertedWith(RevertReasons.NOTHING_TO_WITHDRAW); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOTHING_TO_WITHDRAW); // first withdraw everything await fundsHandler.connect(feeCollector).withdrawProtocolFees([], []); // Attempt to withdraw the funds, expecting revert - await expect(fundsHandler.connect(feeCollector).withdrawProtocolFees([], [])).to.revertedWith( + await expect(fundsHandler.connect(feeCollector).withdrawProtocolFees([], [])).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOTHING_TO_WITHDRAW ); }); @@ -1296,7 +1305,7 @@ describe("IBosonFundsHandler", function () { // attempt to withdraw the funds, expecting revert await expect( fundsHandler.connect(feeCollector).withdrawProtocolFees([ZeroAddress], [offerNativeProtocolFee]) - ).to.revertedWith(RevertReasons.TOKEN_TRANSFER_FAILED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_TRANSFER_FAILED); }); it("Transfer of funds failed - no payable fallback or receive", async function () { @@ -1312,7 +1321,7 @@ describe("IBosonFundsHandler", function () { // attempt to withdraw the funds, expecting revert await expect( fundsHandler.connect(feeCollector).withdrawProtocolFees([ZeroAddress], [offerNativeProtocolFee]) - ).to.revertedWith(RevertReasons.TOKEN_TRANSFER_FAILED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_TRANSFER_FAILED); }); it("Transfer of funds failed - ERC20 token does not exist anymore", async function () { @@ -1977,14 +1986,14 @@ describe("IBosonFundsHandler", function () { exchangeHandler .connect(buyer) .commitToOffer(await buyer.getAddress(), offerNative.id, { value: BigInt(price) - 1n }) - ).to.revertedWith(RevertReasons.INSUFFICIENT_VALUE_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_VALUE_RECEIVED); }); it("Native currency sent together with ERC20 token transfer", async function () { // Attempt to commit to an offer, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerToken.id, { value: price }) - ).to.revertedWith(RevertReasons.NATIVE_NOT_ALLOWED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NATIVE_NOT_ALLOWED); }); it("Token address contract does not support transferFrom", async function () { @@ -2061,7 +2070,7 @@ describe("IBosonFundsHandler", function () { // Attempt to commit to an offer, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerToken.id) - ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); // create an offer with native currency with higher seller deposit offerNative.sellerDeposit = BigInt(offerNative.sellerDeposit) * 4n; @@ -2073,7 +2082,7 @@ describe("IBosonFundsHandler", function () { // Attempt to commit to an offer, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerNative.id, { value: price }) - ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); }); it("Seller'a availableFunds is less than the required sellerDeposit + price for preminted offer", async function () { @@ -2098,7 +2107,7 @@ describe("IBosonFundsHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); // reserve a range and premint vouchers for offer in native currency exchangeId = await exchangeHandler.getNextExchangeId(); @@ -2113,7 +2122,7 @@ describe("IBosonFundsHandler", function () { bosonVoucher .connect(assistant) .transferFrom(await assistant.getAddress(), await buyer.getAddress(), tokenId) - ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); }); it("Received ERC20 token amount differs from the expected value", async function () { @@ -2146,7 +2155,7 @@ describe("IBosonFundsHandler", function () { // Attempt to commit to offer, expecting revert await expect( exchangeHandler.connect(buyer).commitToOffer(await buyer.getAddress(), offerToken.id) - ).to.revertedWith(RevertReasons.INSUFFICIENT_VALUE_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_VALUE_RECEIVED); }); }); }); diff --git a/test/protocol/GroupHandlerTest.js b/test/protocol/GroupHandlerTest.js index 0a0618765..baa4d3da3 100644 --- a/test/protocol/GroupHandlerTest.js +++ b/test/protocol/GroupHandlerTest.js @@ -1,5 +1,5 @@ const { ethers } = require("hardhat"); -const { ZeroAddress, getSigners, parseUnits, getContractFactory } = ethers; +const { ZeroAddress, getSigners, parseUnits, getContractFactory, getContractAt } = ethers; const { assert, expect } = require("chai"); const Group = require("../../scripts/domain/Group"); @@ -46,6 +46,7 @@ describe("IBosonGroupHandler", function () { let emptyAuthToken; let agentId; let snapshotId; + let bosonErrors; before(async function () { accountId.next(true); @@ -67,6 +68,8 @@ describe("IBosonGroupHandler", function () { contractInstances: { erc165, accountHandler, offerHandler, groupHandler, pauseHandler }, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", await accountHandler.getAddress()); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -297,14 +300,16 @@ describe("IBosonGroupHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Groups]); // Attempt to create a group expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); it("Caller not assistant of any seller", async function () { // Attempt to Create a group, expecting revert - await expect(groupHandler.connect(rando).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(rando).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ASSISTANT ); }); @@ -325,7 +330,8 @@ describe("IBosonGroupHandler", function () { group.offerIds = ["2", "6"]; // Attempt to create a group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ASSISTANT ); }); @@ -335,7 +341,8 @@ describe("IBosonGroupHandler", function () { group.offerIds = ["1", "999"]; // Attempt to create a group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_OFFER ); @@ -343,7 +350,8 @@ describe("IBosonGroupHandler", function () { group.offerIds = ["0", "4"]; // Attempt to create a group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_OFFER ); }); @@ -356,7 +364,8 @@ describe("IBosonGroupHandler", function () { group.offerIds = ["1", "2", "4"]; // Attempt to create a group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.OFFER_MUST_BE_UNIQUE ); }); @@ -366,7 +375,8 @@ describe("IBosonGroupHandler", function () { group.offerIds = ["1", "1", "4"]; // Attempt to create a group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.OFFER_MUST_BE_UNIQUE ); }); @@ -380,7 +390,8 @@ describe("IBosonGroupHandler", function () { condition.tokenAddress = await rando.getAddress(); // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -389,7 +400,8 @@ describe("IBosonGroupHandler", function () { condition.minTokenId = "20"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -398,7 +410,8 @@ describe("IBosonGroupHandler", function () { condition.threshold = "100"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -407,7 +420,8 @@ describe("IBosonGroupHandler", function () { condition.maxCommits = "5"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -416,7 +430,8 @@ describe("IBosonGroupHandler", function () { condition.maxTokenId = "5"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -425,7 +440,8 @@ describe("IBosonGroupHandler", function () { condition.tokenType = TokenType.NonFungibleToken; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -434,7 +450,8 @@ describe("IBosonGroupHandler", function () { condition.gating = GatingType.PerTokenId; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -457,7 +474,8 @@ describe("IBosonGroupHandler", function () { condition.tokenAddress = ZeroAddress; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -466,7 +484,8 @@ describe("IBosonGroupHandler", function () { condition.maxCommits = "0"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -475,7 +494,8 @@ describe("IBosonGroupHandler", function () { condition.threshold = "0"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -486,7 +506,8 @@ describe("IBosonGroupHandler", function () { condition.maxTokenId = "90"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -497,7 +518,8 @@ describe("IBosonGroupHandler", function () { condition.maxTokenId = "110"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -508,7 +530,8 @@ describe("IBosonGroupHandler", function () { condition.maxTokenId = "110"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -518,7 +541,8 @@ describe("IBosonGroupHandler", function () { condition.gating = GatingType.PerTokenId; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -528,7 +552,8 @@ describe("IBosonGroupHandler", function () { condition.gating = GatingType.PerTokenId; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -549,7 +574,8 @@ describe("IBosonGroupHandler", function () { condition.tokenAddress = ZeroAddress; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -558,7 +584,8 @@ describe("IBosonGroupHandler", function () { condition.threshold = "10"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -567,7 +594,8 @@ describe("IBosonGroupHandler", function () { condition.maxCommits = "0"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -576,7 +604,8 @@ describe("IBosonGroupHandler", function () { condition.tokenType = TokenType.MultiToken; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -585,7 +614,8 @@ describe("IBosonGroupHandler", function () { condition.tokenType = TokenType.FungibleToken; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -595,7 +625,8 @@ describe("IBosonGroupHandler", function () { condition.maxTokenId = "10"; // Attempt to create the group, expecting revert - await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWith( + await expect(groupHandler.connect(assistant).createGroup(group, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS ); }); @@ -654,9 +685,9 @@ describe("IBosonGroupHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Groups]); // Attempt to add offers to a group, expecting revert - await expect(groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd)).to.revertedWith( - RevertReasons.REGION_PAUSED - ); + await expect( + groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Group does not exist", async function () { @@ -664,24 +695,24 @@ describe("IBosonGroupHandler", function () { group.id = "444"; // Attempt to add offers to the group, expecting revert - await expect(groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd)).to.revertedWith( - RevertReasons.NO_SUCH_GROUP - ); + await expect( + groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_GROUP); // Set invalid id group.id = "0"; // Attempt to add offers to group, expecting revert - await expect(groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd)).to.revertedWith( - RevertReasons.NO_SUCH_GROUP - ); + await expect( + groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_GROUP); }); it("Caller is not the seller of the group", async function () { // Attempt to add offers to group, expecting revert - await expect(groupHandler.connect(rando).addOffersToGroup(group.id, offerIdsToAdd)).to.revertedWith( - RevertReasons.NOT_ASSISTANT - ); + await expect( + groupHandler.connect(rando).addOffersToGroup(group.id, offerIdsToAdd) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("Caller is not the seller of all offers", async function () { @@ -700,9 +731,9 @@ describe("IBosonGroupHandler", function () { offerIdsToAdd = ["1", "6"]; // Attempt to add offers to group, expecting revert - await expect(groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd)).to.revertedWith( - RevertReasons.NOT_ASSISTANT - ); + await expect( + groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("Offer is already part of another group", async function () { @@ -711,9 +742,9 @@ describe("IBosonGroupHandler", function () { await groupHandler.connect(assistant).createGroup(group, condition); // Attempt to add offers to a group, expecting revert - await expect(groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd)).to.revertedWith( - RevertReasons.OFFER_MUST_BE_UNIQUE - ); + await expect( + groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_MUST_BE_UNIQUE); }); it("Offer is duplicated", async function () { @@ -721,9 +752,9 @@ describe("IBosonGroupHandler", function () { offerIdsToAdd = ["1", "1", "4"]; // Attempt to add offers to a group, expecting revert - await expect(groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd)).to.revertedWith( - RevertReasons.OFFER_MUST_BE_UNIQUE - ); + await expect( + groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_MUST_BE_UNIQUE); }); it("Adding nothing", async function () { @@ -731,9 +762,9 @@ describe("IBosonGroupHandler", function () { offerIdsToAdd = []; // Attempt to add offers from the group, expecting revert - await expect(groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd)).to.revertedWith( - RevertReasons.NOTHING_UPDATED - ); + await expect( + groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOTHING_UPDATED); }); it("Offer does not exist", async function () { @@ -741,17 +772,17 @@ describe("IBosonGroupHandler", function () { offerIdsToAdd = ["1", "999"]; // Attempt to add offers to a group, expecting revert - await expect(groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd)).to.revertedWith( - RevertReasons.NO_SUCH_OFFER - ); + await expect( + groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); // Set invalid offer id offerIdsToAdd = ["0", "2"]; // Attempt to add offers to a group, expecting revert - await expect(groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd)).to.revertedWith( - RevertReasons.NO_SUCH_OFFER - ); + await expect( + groupHandler.connect(assistant).addOffersToGroup(group.id, offerIdsToAdd) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); }); }); }); @@ -850,7 +881,7 @@ describe("IBosonGroupHandler", function () { // Attempt to remove offers to a group, expecting revert await expect( groupHandler.connect(assistant).removeOffersFromGroup(group.id, offerIdsToRemove) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Group does not exist", async function () { @@ -860,7 +891,7 @@ describe("IBosonGroupHandler", function () { // Attempt to remove offers from the group, expecting revert await expect( groupHandler.connect(assistant).removeOffersFromGroup(group.id, offerIdsToRemove) - ).to.revertedWith(RevertReasons.NO_SUCH_GROUP); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_GROUP); // Set invalid id group.id = "0"; @@ -868,14 +899,14 @@ describe("IBosonGroupHandler", function () { // Attempt to remove offers from group, expecting revert await expect( groupHandler.connect(assistant).removeOffersFromGroup(group.id, offerIdsToRemove) - ).to.revertedWith(RevertReasons.NO_SUCH_GROUP); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_GROUP); }); it("Caller is not the seller of the group", async function () { // Attempt to remove offers from the group, expecting revert - await expect(groupHandler.connect(rando).removeOffersFromGroup(group.id, offerIdsToRemove)).to.revertedWith( - RevertReasons.NOT_ASSISTANT - ); + await expect( + groupHandler.connect(rando).removeOffersFromGroup(group.id, offerIdsToRemove) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("Offer is not a part of the group", async function () { @@ -885,7 +916,7 @@ describe("IBosonGroupHandler", function () { // Attempt to remove offers from the group, expecting revert await expect( groupHandler.connect(assistant).removeOffersFromGroup(group.id, offerIdsToRemove) - ).to.revertedWith(RevertReasons.OFFER_NOT_IN_GROUP); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_NOT_IN_GROUP); // create an offer and add it to another group await offerHandler @@ -897,7 +928,7 @@ describe("IBosonGroupHandler", function () { // Attempt to remove offers from a group, expecting revert await expect( groupHandler.connect(assistant).removeOffersFromGroup(group.id, offerIdsToRemove) - ).to.revertedWith(RevertReasons.OFFER_NOT_IN_GROUP); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_NOT_IN_GROUP); }); it("Removing nothing", async function () { @@ -907,7 +938,7 @@ describe("IBosonGroupHandler", function () { // Attempt to remove offers from the group, expecting revert await expect( groupHandler.connect(assistant).removeOffersFromGroup(group.id, offerIdsToRemove) - ).to.revertedWith(RevertReasons.NOTHING_UPDATED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOTHING_UPDATED); }); }); }); @@ -967,9 +998,9 @@ describe("IBosonGroupHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Groups]); // Attempt to set group condition, expecting revert - await expect(groupHandler.connect(assistant).setGroupCondition(group.id, condition)).to.revertedWith( - RevertReasons.REGION_PAUSED - ); + await expect( + groupHandler.connect(assistant).setGroupCondition(group.id, condition) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Group does not exist", async function () { @@ -977,22 +1008,23 @@ describe("IBosonGroupHandler", function () { group.id = "444"; // Attempt to update the group, expecting revert - await expect(groupHandler.connect(assistant).setGroupCondition(group.id, condition)).to.revertedWith( - RevertReasons.NO_SUCH_GROUP - ); + await expect( + groupHandler.connect(assistant).setGroupCondition(group.id, condition) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_GROUP); // Set invalid id group.id = "0"; // Attempt to update the group, expecting revert - await expect(groupHandler.connect(assistant).setGroupCondition(group.id, condition)).to.revertedWith( - RevertReasons.NO_SUCH_GROUP - ); + await expect( + groupHandler.connect(assistant).setGroupCondition(group.id, condition) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_GROUP); }); it("Caller is not the seller of the group", async function () { // Attempt to remove offers from the group, expecting revert - await expect(groupHandler.connect(rando).setGroupCondition(group.id, condition)).to.revertedWith( + await expect(groupHandler.connect(rando).setGroupCondition(group.id, condition)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ASSISTANT ); }); @@ -1001,9 +1033,9 @@ describe("IBosonGroupHandler", function () { condition.method = EvaluationMethod.None; // Attempt to update the group, expecting revert - await expect(groupHandler.connect(assistant).setGroupCondition(group.id, condition)).to.revertedWith( - RevertReasons.INVALID_CONDITION_PARAMETERS - ); + await expect( + groupHandler.connect(assistant).setGroupCondition(group.id, condition) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS); }); it("Condition 'Threshold' has zero token contract address", async function () { @@ -1011,9 +1043,9 @@ describe("IBosonGroupHandler", function () { condition.tokenAddress = ZeroAddress; // Attempt to update the group, expecting revert - await expect(groupHandler.connect(assistant).setGroupCondition(group.id, condition)).to.revertedWith( - RevertReasons.INVALID_CONDITION_PARAMETERS - ); + await expect( + groupHandler.connect(assistant).setGroupCondition(group.id, condition) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS); }); it("Condition 'Threshold' has zero max commits", async function () { @@ -1021,9 +1053,9 @@ describe("IBosonGroupHandler", function () { condition.maxCommits = "0"; // Attempt to update the group, expecting revert - await expect(groupHandler.connect(assistant).setGroupCondition(group.id, condition)).to.revertedWith( - RevertReasons.INVALID_CONDITION_PARAMETERS - ); + await expect( + groupHandler.connect(assistant).setGroupCondition(group.id, condition) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS); }); it("Condition 'SpecificToken' has zero token contract address", async function () { @@ -1031,9 +1063,9 @@ describe("IBosonGroupHandler", function () { condition.tokenAddress = ZeroAddress; // Attempt to update the group, expecting revert - await expect(groupHandler.connect(assistant).setGroupCondition(group.id, condition)).to.revertedWith( - RevertReasons.INVALID_CONDITION_PARAMETERS - ); + await expect( + groupHandler.connect(assistant).setGroupCondition(group.id, condition) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS); }); it("Condition 'SpecificToken' has zero max commits", async function () { @@ -1041,9 +1073,9 @@ describe("IBosonGroupHandler", function () { condition.maxCommits = "0"; // Attempt to update the group, expecting revert - await expect(groupHandler.connect(assistant).setGroupCondition(group.id, condition)).to.revertedWith( - RevertReasons.INVALID_CONDITION_PARAMETERS - ); + await expect( + groupHandler.connect(assistant).setGroupCondition(group.id, condition) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS); }); }); }); diff --git a/test/protocol/MetaTransactionsHandlerTest.js b/test/protocol/MetaTransactionsHandlerTest.js index d79a88bd7..6e0871aa3 100644 --- a/test/protocol/MetaTransactionsHandlerTest.js +++ b/test/protocol/MetaTransactionsHandlerTest.js @@ -109,6 +109,7 @@ describe("IBosonMetaTransactionsHandler", function () { let facetNames; let protocolDiamondAddress; let snapshotId; + let bosonErrors; before(async function () { accountId.next(true); @@ -163,6 +164,8 @@ describe("IBosonMetaTransactionsHandler", function () { diamondAddress: protocolDiamondAddress, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", protocolDiamondAddress); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -392,7 +395,7 @@ describe("IBosonMetaTransactionsHandler", function () { // Attempt to set new max offer per group, expecting revert await expect( metaTransactionsHandler.connect(rando).setAllowlistedFunctions(functionHashList, true) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); }); }); @@ -672,7 +675,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.MUST_BE_ACTIVE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.MUST_BE_ACTIVE); }); it("Should allow different signers to use same nonce", async () => { @@ -806,7 +809,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Should fail when function name is not allowlisted", async function () { @@ -846,7 +849,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.FUNCTION_NOT_ALLOWLISTED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FUNCTION_NOT_ALLOWLISTED); }); it("Should fail when function name is not allowlisted - incorrect name", async function () { @@ -883,7 +886,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.FUNCTION_NOT_ALLOWLISTED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FUNCTION_NOT_ALLOWLISTED); }); it("Should fail when function name is incorrect", async function () { @@ -920,7 +923,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.INVALID_FUNCTION_NAME); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_FUNCTION_NAME); }); it("Should fail when function name is incorrect, even if selector is correct [collision]", async function () { @@ -963,7 +966,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.FUNCTION_NOT_ALLOWLISTED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FUNCTION_NOT_ALLOWLISTED); }); it("Should fail when replaying a transaction", async function () { @@ -1007,7 +1010,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -1042,7 +1045,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); it("Should fail if signature is invalid", async function () { @@ -1076,7 +1079,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, "0" // invalid v signature component ) - ).to.revertedWith(RevertReasons.INVALID_SIGNATURE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_SIGNATURE); // Execute meta transaction, expecting revert. await expect( @@ -1089,7 +1092,7 @@ describe("IBosonMetaTransactionsHandler", function () { toHexString(MaxUint256), // invalid s signature component v ) - ).to.revertedWith(RevertReasons.INVALID_SIGNATURE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_SIGNATURE); // Execute meta transaction, expecting revert. await expect( @@ -1102,7 +1105,7 @@ describe("IBosonMetaTransactionsHandler", function () { zeroPadBytes("0x", 32), // invalid s signature component v ) - ).to.revertedWith(RevertReasons.INVALID_SIGNATURE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_SIGNATURE); // Execute meta transaction, expecting revert. await expect( @@ -1115,7 +1118,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.INVALID_SIGNATURE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_SIGNATURE); }); }); }); @@ -1244,7 +1247,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.FUNCTION_NOT_ALLOWLISTED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FUNCTION_NOT_ALLOWLISTED); }); it("Returns default revert reason if called function reverts without a reason", async function () { @@ -1456,7 +1459,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.REENTRANCY_GUARD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REENTRANCY_GUARD); [, buyerStruct] = await accountHandler.getBuyer(buyerId); const buyerAfter = Buyer.fromStruct(buyerStruct); @@ -1530,7 +1533,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.REENTRANCY_GUARD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REENTRANCY_GUARD); }); }); }); @@ -1761,7 +1764,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NO_SUCH_OFFER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); }); context("💔 Revert Reasons", async function () { @@ -1805,7 +1808,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -1832,7 +1835,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); }); }); @@ -1988,7 +1991,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NO_SUCH_OFFER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); }); it("does not modify revert reasons - invalid tokenId", async function () { @@ -2027,7 +2030,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.INVALID_TOKEN_ID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_TOKEN_ID); }); context("💔 Revert Reasons", async function () { @@ -2071,7 +2074,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -2098,7 +2101,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); }); }); @@ -2209,7 +2212,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); context("💔 Revert Reasons", async function () { @@ -2252,7 +2255,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -2279,7 +2282,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); }); }); @@ -2363,7 +2366,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); context("💔 Revert Reasons", async function () { @@ -2406,7 +2409,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -2433,7 +2436,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); }); }); @@ -2526,7 +2529,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); context("💔 Revert Reasons", async function () { @@ -2569,7 +2572,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -2596,7 +2599,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); }); }); @@ -2691,7 +2694,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); context("💔 Revert Reasons", async function () { @@ -2734,7 +2737,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -2761,7 +2764,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); }); }); @@ -2878,7 +2881,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); context("💔 Revert Reasons", async function () { @@ -2921,7 +2924,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -2948,7 +2951,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); }); }); @@ -3043,7 +3046,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); context("💔 Revert Reasons", async function () { @@ -3086,7 +3089,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -3113,7 +3116,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); }); }); @@ -3283,7 +3286,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.INVALID_BUYER_PERCENT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_BUYER_PERCENT); }); context("💔 Revert Reasons", async function () { @@ -3330,7 +3333,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -3357,7 +3360,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); }); }); @@ -3539,7 +3542,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.OFFER_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); context("💔 Revert Reasons", async function () { @@ -3575,7 +3578,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -3602,7 +3605,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); }); }); @@ -3939,7 +3942,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); }); }); @@ -3985,7 +3988,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.NONCE_USED_ALREADY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NONCE_USED_ALREADY); }); it("Should fail when Signer and Signature do not match", async function () { @@ -4012,7 +4015,7 @@ describe("IBosonMetaTransactionsHandler", function () { s, v ) - ).to.revertedWith(RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SIGNER_AND_SIGNATURE_DO_NOT_MATCH); }); }); }); diff --git a/test/protocol/OfferHandlerTest.js b/test/protocol/OfferHandlerTest.js index 2e67cbe9c..7ec88d0cd 100644 --- a/test/protocol/OfferHandlerTest.js +++ b/test/protocol/OfferHandlerTest.js @@ -90,6 +90,7 @@ describe("IBosonOfferHandler", function () { let returnedAgentId; let snapshotId; let beaconProxyAddress; + let bosonErrors; before(async function () { // get interface Ids @@ -130,6 +131,8 @@ describe("IBosonOfferHandler", function () { ], } = await setupTestEnvironment(contracts, { bosonTokenAddress: await bosonToken.getAddress() })); + bosonErrors = await getContractAt("BosonErrors", await configHandler.getAddress()); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -529,7 +532,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.SELLER_NOT_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_NOT_APPROVED); // add seller to allow list allowedSellersToAdd = ["1"]; // existing seller is "1", DR is "2", new seller is "3" @@ -616,14 +619,14 @@ describe("IBosonOfferHandler", function () { // Attempt to create an offer expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Caller not assistant of any seller", async function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(rando).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("Valid from date is greater than valid until date", async function () { @@ -634,7 +637,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.OFFER_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); it("Valid until date is not in the future", async function () { @@ -651,7 +654,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.OFFER_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); it("Buyer cancel penalty is greater than price", async function () { @@ -661,7 +664,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.OFFER_PENALTY_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PENALTY_INVALID); }); it("Offer cannot be voided at the time of the creation", async function () { @@ -671,7 +674,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.OFFER_MUST_BE_ACTIVE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_MUST_BE_ACTIVE); }); it("Both voucher expiration date and voucher expiration period are defined", async function () { @@ -682,7 +685,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); }); it("Neither of voucher expiration date and voucher expiration period are defined", async function () { @@ -693,7 +696,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); }); it("Voucher redeemable period is fixed, but it ends before it starts", async function () { @@ -704,7 +707,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.REDEMPTION_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REDEMPTION_PERIOD_INVALID); }); it("Voucher redeemable period is fixed, but it ends before offer expires", async function () { @@ -716,7 +719,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.REDEMPTION_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REDEMPTION_PERIOD_INVALID); }); it("Dispute period is less than minimum dispute period", async function () { @@ -726,7 +729,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_PERIOD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_PERIOD); }); it("Resolution period is less than minimum resolution period", async function () { @@ -736,7 +739,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.INVALID_RESOLUTION_PERIOD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RESOLUTION_PERIOD); }); it("Resolution period is greater than protocol max resolution period", async function () { @@ -747,7 +750,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.INVALID_RESOLUTION_PERIOD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RESOLUTION_PERIOD); }); it("Available quantity is set to zero", async function () { @@ -757,7 +760,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.INVALID_QUANTITY_AVAILABLE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_QUANTITY_AVAILABLE); }); it("Dispute resolver wallet is not registered", async function () { @@ -767,7 +770,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); }); it("Dispute resolver wallet is not registered", async function () { @@ -778,7 +781,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); }); // TODO - revisit when account deactivations are supported @@ -798,7 +801,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); // after activation it should be possible to create the offer await accountHandler.connect(deployer).activateDisputeResolver(disputeResolver.id); @@ -817,7 +820,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); }); // TODO - revisit when account deactivations are supported @@ -840,7 +843,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); // after activation it should be possible to create the offer await accountHandler.connect(deployer).activateDisputeResolver(disputeResolver.id); @@ -868,7 +871,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.SELLER_NOT_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_NOT_APPROVED); }); it("Dispute resolver does not accept fees in the exchange token", async function () { @@ -878,7 +881,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.DR_UNSUPPORTED_FEE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DR_UNSUPPORTED_FEE); }); it("Collection does not exist", async function () { @@ -888,7 +891,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.NO_SUCH_COLLECTION); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_COLLECTION); // Create a new collection const externalId = "Brand1"; @@ -901,7 +904,7 @@ describe("IBosonOfferHandler", function () { // Attempt to Create an offer, expecting revert await expect( offerHandler.connect(assistant).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.NO_SUCH_COLLECTION); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_COLLECTION); }); }); @@ -1026,7 +1029,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId) - ).to.revertedWith(RevertReasons.NO_SUCH_AGENT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_AGENT); }); it("Sum of agent fee amount and protocol fee amount should be <= than the offer fee limit", async function () { @@ -1047,7 +1050,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOffer(offer, offerDates, offerDurations, disputeResolver.id, agent.id) - ).to.revertedWith(RevertReasons.AGENT_FEE_AMOUNT_TOO_HIGH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AGENT_FEE_AMOUNT_TOO_HIGH); }); }); }); @@ -1101,7 +1104,10 @@ describe("IBosonOfferHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Offers]); // Attempt to void an offer expecting revert - await expect(offerHandler.connect(assistant).voidOffer(id)).to.revertedWith(RevertReasons.REGION_PAUSED); + await expect(offerHandler.connect(assistant).voidOffer(id)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.REGION_PAUSED + ); }); it("Offer does not exist", async function () { @@ -1109,19 +1115,28 @@ describe("IBosonOfferHandler", function () { id = "444"; // Attempt to void the offer, expecting revert - await expect(offerHandler.connect(assistant).voidOffer(id)).to.revertedWith(RevertReasons.NO_SUCH_OFFER); + await expect(offerHandler.connect(assistant).voidOffer(id)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NO_SUCH_OFFER + ); // Set invalid id id = "0"; // Attempt to void the offer, expecting revert - await expect(offerHandler.connect(assistant).voidOffer(id)).to.revertedWith(RevertReasons.NO_SUCH_OFFER); + await expect(offerHandler.connect(assistant).voidOffer(id)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NO_SUCH_OFFER + ); }); it("Caller is not seller", async function () { // caller is not the assistant of any seller // Attempt to update the offer, expecting revert - await expect(offerHandler.connect(rando).voidOffer(id)).to.revertedWith(RevertReasons.NOT_ASSISTANT); + await expect(offerHandler.connect(rando).voidOffer(id)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NOT_ASSISTANT + ); // caller is an assistant of another seller // Create a valid seller, then set fields in tests directly @@ -1138,7 +1153,10 @@ describe("IBosonOfferHandler", function () { await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); // Attempt to update the offer, expecting revert - await expect(offerHandler.connect(rando).voidOffer(id)).to.revertedWith(RevertReasons.NOT_ASSISTANT); + await expect(offerHandler.connect(rando).voidOffer(id)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NOT_ASSISTANT + ); }); it("Offer already voided", async function () { @@ -1146,7 +1164,8 @@ describe("IBosonOfferHandler", function () { await offerHandler.connect(assistant).voidOffer(id); // Attempt to void the offer again, expecting revert - await expect(offerHandler.connect(assistant).voidOffer(id)).to.revertedWith( + await expect(offerHandler.connect(assistant).voidOffer(id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED ); }); @@ -1198,9 +1217,9 @@ describe("IBosonOfferHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Offers]); // Attempt to extend an offer expecting revert - await expect(offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil)).to.revertedWith( - RevertReasons.REGION_PAUSED - ); + await expect( + offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Offer does not exist", async function () { @@ -1208,23 +1227,24 @@ describe("IBosonOfferHandler", function () { id = "444"; // Attempt to void the offer, expecting revert - await expect(offerHandler.connect(assistant).extendOffer(id, offerDates.validUntil)).to.revertedWith( - RevertReasons.NO_SUCH_OFFER - ); + await expect( + offerHandler.connect(assistant).extendOffer(id, offerDates.validUntil) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); // Set invalid id id = "0"; // Attempt to void the offer, expecting revert - await expect(offerHandler.connect(assistant).extendOffer(id, offerDates.validUntil)).to.revertedWith( - RevertReasons.NO_SUCH_OFFER - ); + await expect( + offerHandler.connect(assistant).extendOffer(id, offerDates.validUntil) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); }); it("Caller is not seller", async function () { // caller is not the assistant of any seller // Attempt to update the offer, expecting revert - await expect(offerHandler.connect(rando).extendOffer(id, offerDates.validUntil)).to.revertedWith( + await expect(offerHandler.connect(rando).extendOffer(id, offerDates.validUntil)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ASSISTANT ); @@ -1243,7 +1263,8 @@ describe("IBosonOfferHandler", function () { await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); // Attempt to update the offer, expecting revert - await expect(offerHandler.connect(rando).extendOffer(id, offerDates.validUntil)).to.revertedWith( + await expect(offerHandler.connect(rando).extendOffer(id, offerDates.validUntil)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ASSISTANT ); }); @@ -1253,26 +1274,26 @@ describe("IBosonOfferHandler", function () { await offerHandler.connect(assistant).voidOffer(id); // Attempt to update an offer, expecting revert - await expect(offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil)).to.revertedWith( - RevertReasons.OFFER_HAS_BEEN_VOIDED - ); + await expect( + offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); }); it("New valid until date is lower than the existing valid until date", async function () { // Make the valid until date the same as the existing offer offerDates.validUntil = (BigInt(offerDates.validUntil) - 10000n).toString(); - await expect(offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil)).to.revertedWith( - RevertReasons.OFFER_PERIOD_INVALID - ); + await expect( + offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); // Make new the valid until date less than existing one offerDates.validUntil = (BigInt(offerDates.validUntil) - 1n).toString(); // Attempt to update an offer, expecting revert - await expect(offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil)).to.revertedWith( - RevertReasons.OFFER_PERIOD_INVALID - ); + await expect( + offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); it("Valid until date is not in the future", async function () { @@ -1280,9 +1301,9 @@ describe("IBosonOfferHandler", function () { offerDates.validUntil = (BigInt(offerDates.validFrom) - oneMonth * 6n).toString(); // 6 months ago // Attempt to update an offer, expecting revert - await expect(offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil)).to.revertedWith( - RevertReasons.OFFER_PERIOD_INVALID - ); + await expect( + offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); }); }); @@ -1334,9 +1355,9 @@ describe("IBosonOfferHandler", function () { offerDates.validUntil = BigInt(offerDates.voucherRedeemableUntil) + oneWeek.toString(); // one week after voucherRedeemableUntil // Attempt to update an offer, expecting revert - await expect(offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil)).to.revertedWith( - RevertReasons.OFFER_PERIOD_INVALID - ); + await expect( + offerHandler.connect(assistant).extendOffer(offer.id, offerDates.validUntil) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); }); }); @@ -1527,7 +1548,7 @@ describe("IBosonOfferHandler", function () { // Attempt to reserve a range, expecting revert await expect( offerHandler.connect(assistant).reserveRange(id, length, await assistant.getAddress()) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The exchanges region of protocol is paused", async function () { @@ -1537,7 +1558,7 @@ describe("IBosonOfferHandler", function () { // Attempt to reserve a range, expecting revert await expect( offerHandler.connect(assistant).reserveRange(id, length, await assistant.getAddress()) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Offer does not exist", async function () { @@ -1547,7 +1568,7 @@ describe("IBosonOfferHandler", function () { // Attempt to reserve a range, expecting revert await expect( offerHandler.connect(assistant).reserveRange(id, length, await assistant.getAddress()) - ).to.revertedWith(RevertReasons.NO_SUCH_OFFER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); // Set invalid id id = "0"; @@ -1555,7 +1576,7 @@ describe("IBosonOfferHandler", function () { // Attempt to reserve a range, expecting revert await expect( offerHandler.connect(assistant).reserveRange(id, length, await assistant.getAddress()) - ).to.revertedWith(RevertReasons.NO_SUCH_OFFER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); }); it("Offer already voided", async function () { @@ -1565,7 +1586,7 @@ describe("IBosonOfferHandler", function () { // Attempt to reserve a range, expecting revert await expect( offerHandler.connect(assistant).reserveRange(id, length, await assistant.getAddress()) - ).to.revertedWith(RevertReasons.OFFER_HAS_BEEN_VOIDED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); }); it("Caller is not seller", async function () { @@ -1573,7 +1594,7 @@ describe("IBosonOfferHandler", function () { // Attempt to reserve a range, expecting revert await expect( offerHandler.connect(rando).reserveRange(id, length, await assistant.getAddress()) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); // caller is an assistant of another seller // Create a valid seller, then set fields in tests directly @@ -1592,7 +1613,7 @@ describe("IBosonOfferHandler", function () { // Attempt to reserve a range, expecting revert await expect( offerHandler.connect(rando).reserveRange(id, length, await assistant.getAddress()) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("Range length is zero", async function () { @@ -1602,7 +1623,7 @@ describe("IBosonOfferHandler", function () { // Attempt to reserve a range, expecting revert await expect( offerHandler.connect(assistant).reserveRange(id, length, await assistant.getAddress()) - ).to.revertedWith(RevertReasons.INVALID_RANGE_LENGTH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RANGE_LENGTH); }); it("Range length is greater than quantity available", async function () { @@ -1612,7 +1633,7 @@ describe("IBosonOfferHandler", function () { // Attempt to reserve a range, expecting revert await expect( offerHandler.connect(assistant).reserveRange(id, length, await assistant.getAddress()) - ).to.revertedWith(RevertReasons.INVALID_RANGE_LENGTH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RANGE_LENGTH); }); it("Range length is greater than maximum allowed range length", async function () { @@ -1628,7 +1649,7 @@ describe("IBosonOfferHandler", function () { // Attempt to reserve a range, expecting revert await expect( offerHandler.connect(assistant).reserveRange(nextOfferId, length, await assistant.getAddress()) - ).to.revertedWith(RevertReasons.INVALID_RANGE_LENGTH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RANGE_LENGTH); }); it("Call to BosonVoucher.reserveRange() reverts", async function () { @@ -1638,14 +1659,14 @@ describe("IBosonOfferHandler", function () { // Attempt to reserve the same range again, expecting revert await expect( offerHandler.connect(assistant).reserveRange(id, length, await assistant.getAddress()) - ).to.revertedWith(RevertReasons.OFFER_RANGE_ALREADY_RESERVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_RANGE_ALREADY_RESERVED); }); it("_to address isn't contract address or contract owner address", async function () { // Try to reserve range for rando address, it should fail await expect( offerHandler.connect(assistant).reserveRange(id, length, await rando.getAddress()) - ).to.be.revertedWith(RevertReasons.INVALID_TO_ADDRESS); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_TO_ADDRESS); }); }); }); @@ -2268,7 +2289,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.SELLER_NOT_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_NOT_APPROVED); // add seller to allow list allowedSellersToAdd = ["1"]; // existing seller is "1", DR is "2", new seller is "3" @@ -2292,7 +2313,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Caller not assistant of any seller", async function () { @@ -2301,7 +2322,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(rando) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("Valid from date is greater than valid until date in some offer", async function () { @@ -2314,7 +2335,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.OFFER_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); it("Valid until date is not in the future in some offer", async function () { @@ -2331,7 +2352,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.OFFER_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); it("Buyer cancel penalty is greater than price", async function () { @@ -2343,7 +2364,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.OFFER_PENALTY_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PENALTY_INVALID); }); it("No offer cannot be voided at the time of the creation", async function () { @@ -2355,7 +2376,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.OFFER_MUST_BE_ACTIVE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_MUST_BE_ACTIVE); }); it("Dispute valid duration is 0 for some offer", async function () { @@ -2367,7 +2388,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.INVALID_RESOLUTION_PERIOD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RESOLUTION_PERIOD); }); it("For some offer, both voucher expiration date and voucher expiration period are defined", async function () { @@ -2381,7 +2402,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); }); it("For some offer, neither of voucher expiration date and voucher expiration period are defined", async function () { @@ -2394,7 +2415,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); }); it("For some offer, voucher redeemable period is fixed, but it ends before it starts", async function () { @@ -2407,7 +2428,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.REDEMPTION_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REDEMPTION_PERIOD_INVALID); }); it("For some offer, voucher redeemable period is fixed, but it ends before offer expires", async function () { @@ -2421,7 +2442,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.REDEMPTION_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REDEMPTION_PERIOD_INVALID); }); it("For some offer, Dispute period is less than minimum dispute period", async function () { @@ -2433,7 +2454,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_PERIOD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_PERIOD); }); it("For some offer, resolution period is less than minimum dispute period", async function () { @@ -2445,7 +2466,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.INVALID_RESOLUTION_PERIOD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RESOLUTION_PERIOD); }); it("For some offer, available quantity is set to zero", async function () { @@ -2457,7 +2478,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.INVALID_QUANTITY_AVAILABLE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_QUANTITY_AVAILABLE); }); it("For some offer, dispute resolver wallet is not registered", async function () { @@ -2469,7 +2490,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); }); // TODO - revisit when account deactivations are supported @@ -2494,7 +2515,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); // after activation it should be possible to create the offer await accountHandler.connect(deployer).activateDisputeResolver(nextAccountId); @@ -2517,7 +2538,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); }); // TODO - revisit when account deactivations are supported @@ -2543,7 +2564,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); // after activation it should be possible to create the offer await accountHandler.connect(deployer).activateDisputeResolver(nextAccountId); @@ -2575,7 +2596,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.SELLER_NOT_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_NOT_APPROVED); }); it("For some offer, dispute resolver does not accept fees in the exchange token", async function () { @@ -2587,7 +2608,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.DR_UNSUPPORTED_FEE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DR_UNSUPPORTED_FEE); }); it("Number of dispute dates does not match the number of offers", async function () { @@ -2599,7 +2620,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.ARRAY_LENGTH_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ARRAY_LENGTH_MISMATCH); // Make dispute dates shorter offerDatesList = offerDatesList.slice(0, -2); @@ -2609,7 +2630,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.ARRAY_LENGTH_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ARRAY_LENGTH_MISMATCH); }); it("Number of dispute durations does not match the number of offers", async function () { @@ -2621,7 +2642,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.ARRAY_LENGTH_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ARRAY_LENGTH_MISMATCH); // Make dispute durations shorter offerDurationsList = offerDurationsList.slice(0, -2); @@ -2631,7 +2652,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.ARRAY_LENGTH_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ARRAY_LENGTH_MISMATCH); }); it("Number of dispute resolvers does not match the number of offers", async function () { @@ -2643,7 +2664,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.ARRAY_LENGTH_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ARRAY_LENGTH_MISMATCH); // Make dispute durations shorter disputeResolverIds = disputeResolverIds.slice(0, -2); @@ -2653,7 +2674,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.ARRAY_LENGTH_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ARRAY_LENGTH_MISMATCH); }); it("For some offer, collection does not exist", async function () { @@ -2665,7 +2686,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.NO_SUCH_COLLECTION); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_COLLECTION); // Create a new collection const externalId = "Brand1"; @@ -2680,7 +2701,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds) - ).to.revertedWith(RevertReasons.NO_SUCH_COLLECTION); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_COLLECTION); }); }); @@ -2818,7 +2839,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, nonZeroAgentIds) - ).to.revertedWith(RevertReasons.NO_SUCH_AGENT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_AGENT); }); it("Sum of agent fee amount and protocol fee amount should be <= than the offer fee limit", async function () { @@ -2844,7 +2865,7 @@ describe("IBosonOfferHandler", function () { offerHandler .connect(assistant) .createOfferBatch(offers, offerDatesList, offerDurationsList, disputeResolverIds, nonZeroAgentIds) - ).to.revertedWith(RevertReasons.AGENT_FEE_AMOUNT_TOO_HIGH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AGENT_FEE_AMOUNT_TOO_HIGH); }); }); }); @@ -2913,7 +2934,8 @@ describe("IBosonOfferHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Offers]); // Attempt to void offer batch, expecting revert - await expect(offerHandler.connect(assistant).voidOfferBatch(offersToVoid)).to.revertedWith( + await expect(offerHandler.connect(assistant).voidOfferBatch(offersToVoid)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -2923,7 +2945,8 @@ describe("IBosonOfferHandler", function () { offersToVoid = ["1", "432", "2"]; // Attempt to void the offer, expecting revert - await expect(offerHandler.connect(assistant).voidOfferBatch(offersToVoid)).to.revertedWith( + await expect(offerHandler.connect(assistant).voidOfferBatch(offersToVoid)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_OFFER ); @@ -2931,7 +2954,8 @@ describe("IBosonOfferHandler", function () { offersToVoid = ["1", "2", "0"]; // Attempt to void the offer, expecting revert - await expect(offerHandler.connect(assistant).voidOfferBatch(offersToVoid)).to.revertedWith( + await expect(offerHandler.connect(assistant).voidOfferBatch(offersToVoid)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_OFFER ); }); @@ -2939,7 +2963,8 @@ describe("IBosonOfferHandler", function () { it("Caller is not seller", async function () { // caller is not the assistant of any seller // Attempt to update the offer, expecting revert - await expect(offerHandler.connect(rando).voidOfferBatch(offersToVoid)).to.revertedWith( + await expect(offerHandler.connect(rando).voidOfferBatch(offersToVoid)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ASSISTANT ); @@ -2958,7 +2983,8 @@ describe("IBosonOfferHandler", function () { await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); // Attempt to update the offer, expecting revert - await expect(offerHandler.connect(rando).voidOfferBatch(offersToVoid)).to.revertedWith( + await expect(offerHandler.connect(rando).voidOfferBatch(offersToVoid)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ASSISTANT ); }); @@ -2968,7 +2994,8 @@ describe("IBosonOfferHandler", function () { await offerHandler.connect(assistant).voidOffer("1"); // Attempt to void the offer again, expecting revert - await expect(offerHandler.connect(assistant).voidOfferBatch(offersToVoid)).to.revertedWith( + await expect(offerHandler.connect(assistant).voidOfferBatch(offersToVoid)).to.revertedWithCustomError( + bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED ); @@ -2976,7 +3003,8 @@ describe("IBosonOfferHandler", function () { offersToVoid = ["1", "4", "1"]; // Attempt to void the offer again, expecting revert - await expect(offerHandler.connect(assistant).voidOfferBatch(offersToVoid)).to.revertedWith( + await expect(offerHandler.connect(assistant).voidOfferBatch(offersToVoid)).to.revertedWithCustomError( + bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED ); }); @@ -3041,7 +3069,7 @@ describe("IBosonOfferHandler", function () { // Attempt to void offer batch, expecting revert await expect( offerHandler.connect(assistant).extendOfferBatch(offersToExtend, newValidUntilDate) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Offer does not exist", async function () { @@ -3051,7 +3079,7 @@ describe("IBosonOfferHandler", function () { // Attempt to extend the offers, expecting revert await expect( offerHandler.connect(assistant).extendOfferBatch(offersToExtend, newValidUntilDate) - ).to.revertedWith(RevertReasons.NO_SUCH_OFFER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); // Set invalid id offersToExtend = ["1", "2", "0"]; @@ -3059,15 +3087,15 @@ describe("IBosonOfferHandler", function () { // Attempt to extend the offers, expecting revert await expect( offerHandler.connect(assistant).extendOfferBatch(offersToExtend, newValidUntilDate) - ).to.revertedWith(RevertReasons.NO_SUCH_OFFER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); }); it("Caller is not seller", async function () { // caller is not the assistant of any seller // Attempt to extend the offers, expecting revert - await expect(offerHandler.connect(rando).extendOfferBatch(offersToExtend, newValidUntilDate)).to.revertedWith( - RevertReasons.NOT_ASSISTANT - ); + await expect( + offerHandler.connect(rando).extendOfferBatch(offersToExtend, newValidUntilDate) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); // caller is an assistant of another seller seller = mockSeller( @@ -3083,9 +3111,9 @@ describe("IBosonOfferHandler", function () { await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); // Attempt to extend the offers, expecting revert - await expect(offerHandler.connect(rando).extendOfferBatch(offersToExtend, newValidUntilDate)).to.revertedWith( - RevertReasons.NOT_ASSISTANT - ); + await expect( + offerHandler.connect(rando).extendOfferBatch(offersToExtend, newValidUntilDate) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("Offers are not extendable, since one of them it's voided", async function () { @@ -3095,7 +3123,7 @@ describe("IBosonOfferHandler", function () { // Attempt to extend the offers, expecting revert await expect( offerHandler.connect(assistant).extendOfferBatch(offersToExtend, newValidUntilDate) - ).to.revertedWith(RevertReasons.OFFER_HAS_BEEN_VOIDED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); }); it("New valid until date is lower than the existing valid until date", async function () { @@ -3104,7 +3132,7 @@ describe("IBosonOfferHandler", function () { await expect( offerHandler.connect(assistant).extendOfferBatch(offersToExtend, newValidUntilDate) - ).to.revertedWith(RevertReasons.OFFER_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); // Make new the valid until date less than existing one newValidUntilDate = (BigInt(newValidUntilDate) - 1n).toString(); // less that validUntilDate of offer 5 @@ -3112,7 +3140,7 @@ describe("IBosonOfferHandler", function () { // Attempt to extend the offers, expecting revert await expect( offerHandler.connect(assistant).extendOfferBatch(offersToExtend, newValidUntilDate) - ).to.revertedWith(RevertReasons.OFFER_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); it("Valid until date is not in the future", async function () { @@ -3122,7 +3150,7 @@ describe("IBosonOfferHandler", function () { // Attempt to extend the offers, expecting revert await expect( offerHandler.connect(assistant).extendOfferBatch(offersToExtend, newValidUntilDate) - ).to.revertedWith(RevertReasons.OFFER_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); it("Offer has voucherRedeemableUntil set and new valid until date is greater than that", async function () { @@ -3141,7 +3169,7 @@ describe("IBosonOfferHandler", function () { // Attempt to extend the offers, expecting revert await expect( offerHandler.connect(assistant).extendOfferBatch(offersToExtend, newValidUntilDate) - ).to.revertedWith(RevertReasons.OFFER_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); }); }); diff --git a/test/protocol/OrchestrationHandlerTest.js b/test/protocol/OrchestrationHandlerTest.js index 0d2be6a07..b15b46ad1 100644 --- a/test/protocol/OrchestrationHandlerTest.js +++ b/test/protocol/OrchestrationHandlerTest.js @@ -114,6 +114,7 @@ describe("IBosonOrchestrationHandler", function () { let protocolDiamondAddress; let snapshotId; let beaconProxyAddress; + let bosonErrors; before(async function () { // Reset the accountId iterator @@ -165,6 +166,8 @@ describe("IBosonOrchestrationHandler", function () { diamondAddress: protocolDiamondAddress, } = await setupTestEnvironment(contracts, { bosonTokenAddress: await bosonToken.getAddress() })); + bosonErrors = await getContractAt("BosonErrors", protocolDiamondAddress); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -503,7 +506,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(buyer) .raiseAndEscalateDispute(exchangeId, { value: buyerEscalationDepositNative }) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The disputes region of protocol is paused", async function () { @@ -515,7 +518,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(buyer) .raiseAndEscalateDispute(exchangeId, { value: buyerEscalationDepositNative }) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Caller is not the buyer for the given exchange id", async function () { @@ -524,7 +527,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(rando) .raiseAndEscalateDispute(exchangeId, { value: buyerEscalationDepositNative }) - ).to.revertedWith(RevertReasons.NOT_VOUCHER_HOLDER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER); }); it("Exchange id does not exist", async function () { @@ -536,7 +539,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(buyer) .raiseAndEscalateDispute(exchangeId, { value: buyerEscalationDepositNative }) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("exchange is not in a redeemed state - completed", async function () { @@ -561,7 +564,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(buyer) .raiseAndEscalateDispute(exchangeId, { value: buyerEscalationDepositNative }) - ).to.revertedWith(RevertReasons.INVALID_STATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("exchange is not in a redeemed state - disputed already", async function () { @@ -573,7 +576,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(buyer) .raiseAndEscalateDispute(exchangeId, { value: buyerEscalationDepositNative }) - ).to.revertedWith(RevertReasons.INVALID_STATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_STATE); }); it("The dispute period has already elapsed", async function () { @@ -589,7 +592,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(buyer) .raiseAndEscalateDispute(exchangeId, { value: buyerEscalationDepositNative }) - ).to.revertedWith(RevertReasons.DISPUTE_PERIOD_HAS_ELAPSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DISPUTE_PERIOD_HAS_ELAPSED); }); }); }); @@ -1441,7 +1444,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The sellers region of protocol is paused", async function () { @@ -1462,7 +1465,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The offers region of protocol is paused", async function () { @@ -1483,7 +1486,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The exchanges region of protocol is paused [preminted offers]", async function () { @@ -1507,7 +1510,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("active is false", async function () { @@ -1527,7 +1530,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.MUST_BE_ACTIVE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.MUST_BE_ACTIVE); }); it("addresses are not unique to this seller Id", async function () { @@ -1549,7 +1552,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); }); it("Caller is not the supplied admin", async function () { @@ -1569,7 +1572,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.NOT_ADMIN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN); }); it("Caller does not own supplied auth token", async function () { @@ -1590,7 +1593,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.NOT_ADMIN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN); }); it("Caller is not the supplied assistant", async function () { @@ -1610,7 +1613,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("Clerk is not a zero address", async function () { @@ -1632,7 +1635,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.CLERK_DEPRECATED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CLERK_DEPRECATED); }); it("admin address is NOT zero address and AuthTokenType is NOT None", async function () { @@ -1650,7 +1653,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.ADMIN_OR_AUTH_TOKEN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ADMIN_OR_AUTH_TOKEN); }); it("admin address is zero address and AuthTokenType is None", async function () { @@ -1670,7 +1673,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.ADMIN_OR_AUTH_TOKEN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ADMIN_OR_AUTH_TOKEN); }); it("authToken is not unique to this seller", async function () { @@ -1694,7 +1697,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.AUTH_TOKEN_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AUTH_TOKEN_MUST_BE_UNIQUE); }); it("Valid from date is greater than valid until date", async function () { @@ -1716,7 +1719,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.OFFER_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); it("Valid until date is not in the future", async function () { @@ -1741,7 +1744,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.OFFER_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PERIOD_INVALID); }); it("Buyer cancel penalty is less than item price", async function () { @@ -1762,7 +1765,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.OFFER_PENALTY_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_PENALTY_INVALID); }); it("Offer cannot be voided at the time of the creation", async function () { @@ -1783,7 +1786,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.OFFER_MUST_BE_ACTIVE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_MUST_BE_ACTIVE); }); it("Both voucher expiration date and voucher expiration period are defined", async function () { @@ -1805,7 +1808,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); }); it("Neither of voucher expiration date and voucher expiration period are defined", async function () { @@ -1827,7 +1830,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AMBIGUOUS_VOUCHER_EXPIRY); }); it("Voucher redeemable period is fixed, but it ends before it starts", async function () { @@ -1849,7 +1852,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REDEMPTION_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REDEMPTION_PERIOD_INVALID); }); it("Voucher redeemable period is fixed, but it ends before offer expires", async function () { @@ -1872,7 +1875,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REDEMPTION_PERIOD_INVALID); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REDEMPTION_PERIOD_INVALID); }); it("Dispute period is less than minimum dispute period", async function () { @@ -1893,7 +1896,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_PERIOD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_PERIOD); }); it("Resolution period is less than minimum resolution period", async function () { @@ -1914,7 +1917,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.INVALID_RESOLUTION_PERIOD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RESOLUTION_PERIOD); }); it("Resolution period is set above the maximum resolution period", async function () { @@ -1935,7 +1938,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.INVALID_RESOLUTION_PERIOD); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RESOLUTION_PERIOD); }); it("Available quantity is set to zero", async function () { @@ -1956,7 +1959,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.INVALID_QUANTITY_AVAILABLE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_QUANTITY_AVAILABLE); }); it("Dispute resolver wallet is not registered", async function () { @@ -1977,7 +1980,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); }); // TODO - revisit when account deactivations are supported @@ -2010,7 +2013,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); }); it("For absolute zero offer, specified dispute resolver is not registered", async function () { @@ -2032,7 +2035,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); }); // TODO - revisit when account deactivations are supported @@ -2069,7 +2072,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.INVALID_DISPUTE_RESOLVER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_DISPUTE_RESOLVER); }); it("Seller is not on dispute resolver's seller allow list", async function () { @@ -2100,7 +2103,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.SELLER_NOT_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_NOT_APPROVED); }); it("Dispute resolver does not accept fees in the exchange token", async function () { @@ -2121,7 +2124,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.DR_UNSUPPORTED_FEE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.DR_UNSUPPORTED_FEE); }); it("Reserved range length is zero", async function () { @@ -2144,7 +2147,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.INVALID_RANGE_LENGTH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RANGE_LENGTH); }); it("Reserved range length is greater than quantity available", async function () { @@ -2167,7 +2170,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.INVALID_RANGE_LENGTH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RANGE_LENGTH); }); it("Reserved range length is greater than maximum allowed range length", async function () { @@ -2190,7 +2193,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.INVALID_RANGE_LENGTH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RANGE_LENGTH); }); it("Collection does not exist", async function () { @@ -2211,7 +2214,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.NO_SUCH_COLLECTION); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_COLLECTION); }); }); @@ -2300,7 +2303,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.NO_SUCH_AGENT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_AGENT); }); it("Sum of agent fee amount and protocol fee amount should be <= than the offer fee limit", async function () { @@ -2333,7 +2336,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agent.id ) - ).to.revertedWith(RevertReasons.AGENT_FEE_AMOUNT_TOO_HIGH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AGENT_FEE_AMOUNT_TOO_HIGH); }); }); }); @@ -2918,7 +2921,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The offers region of protocol is paused", async function () { @@ -2930,7 +2933,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferWithCondition(offer, offerDates, offerDurations, disputeResolver.id, condition, agentId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The exchanges region of protocol is paused [preminted offers]", async function () { @@ -2952,7 +2955,7 @@ describe("IBosonOrchestrationHandler", function () { condition, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The groups region of protocol is paused", async function () { @@ -2964,7 +2967,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferWithCondition(offer, offerDates, offerDurations, disputeResolver.id, condition, agentId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Caller not assistant of any seller", async function () { @@ -2973,7 +2976,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(rando) .createOfferWithCondition(offer, offerDates, offerDurations, disputeResolver.id, condition, agentId) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("Condition 'None' has some values in other fields", async function () { @@ -2984,7 +2987,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferWithCondition(offer, offerDates, offerDurations, disputeResolver.id, condition, agentId) - ).to.revertedWith(RevertReasons.INVALID_CONDITION_PARAMETERS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS); }); it("Condition 'Threshold' has zero token contract address", async function () { @@ -2996,7 +2999,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferWithCondition(offer, offerDates, offerDurations, disputeResolver.id, condition, agentId) - ).to.revertedWith(RevertReasons.INVALID_CONDITION_PARAMETERS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS); }); it("Condition 'SpecificToken' has has zero token contract address", async function () { @@ -3008,7 +3011,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferWithCondition(offer, offerDates, offerDurations, disputeResolver.id, condition, agentId) - ).to.revertedWith(RevertReasons.INVALID_CONDITION_PARAMETERS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_CONDITION_PARAMETERS); }); }); }); @@ -3612,7 +3615,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAddToGroup(offer, offerDates, offerDurations, disputeResolver.id, nextGroupId, agentId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The offers region of protocol is paused", async function () { @@ -3624,7 +3627,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAddToGroup(offer, offerDates, offerDurations, disputeResolver.id, nextGroupId, agentId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The exchanges region of protocol is paused [preminted offers]", async function () { @@ -3646,7 +3649,7 @@ describe("IBosonOrchestrationHandler", function () { nextGroupId, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The groups region of protocol is paused", async function () { @@ -3658,7 +3661,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAddToGroup(offer, offerDates, offerDurations, disputeResolver.id, nextGroupId, agentId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Group does not exist", async function () { @@ -3670,7 +3673,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAddToGroup(offer, offerDates, offerDurations, disputeResolver.id, invalidGroupId, agentId) - ).to.revertedWith(RevertReasons.NO_SUCH_GROUP); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_GROUP); // Set invalid id invalidGroupId = "0"; @@ -3680,7 +3683,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAddToGroup(offer, offerDates, offerDurations, disputeResolver.id, invalidGroupId, agentId) - ).to.revertedWith(RevertReasons.NO_SUCH_GROUP); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_GROUP); }); it("Caller is not the seller of the group", async function () { @@ -3689,7 +3692,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(rando) .createOfferAddToGroup(offer, offerDates, offerDurations, disputeResolver.id, nextGroupId, agentId) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); }); }); @@ -4324,7 +4327,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAndTwinWithBundle(offer, offerDates, offerDurations, disputeResolver.id, twin, agentId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The offers region of protocol is paused", async function () { @@ -4336,7 +4339,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAndTwinWithBundle(offer, offerDates, offerDurations, disputeResolver.id, twin, agentId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The bundles region of protocol is paused", async function () { @@ -4348,7 +4351,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAndTwinWithBundle(offer, offerDates, offerDurations, disputeResolver.id, twin, agentId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The twins region of protocol is paused", async function () { @@ -4360,7 +4363,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAndTwinWithBundle(offer, offerDates, offerDurations, disputeResolver.id, twin, agentId) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The exchanges region of protocol is paused [preminted offers]", async function () { @@ -4382,7 +4385,7 @@ describe("IBosonOrchestrationHandler", function () { twin, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("should revert if protocol is not approved to transfer the ERC20 token", async function () { @@ -4396,7 +4399,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAndTwinWithBundle(offer, offerDates, offerDurations, disputeResolver.id, twin, agentId) - ).to.revertedWith(RevertReasons.NO_TRANSFER_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_TRANSFER_APPROVED); }); it("should revert if protocol is not approved to transfer the ERC721 token", async function () { @@ -4407,7 +4410,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAndTwinWithBundle(offer, offerDates, offerDurations, disputeResolver.id, twin, agentId) - ).to.revertedWith(RevertReasons.NO_TRANSFER_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_TRANSFER_APPROVED); }); it("should revert if protocol is not approved to transfer the ERC1155 token", async function () { @@ -4418,7 +4421,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAndTwinWithBundle(offer, offerDates, offerDurations, disputeResolver.id, twin, agentId) - ).to.revertedWith(RevertReasons.NO_TRANSFER_APPROVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_TRANSFER_APPROVED); }); context("Token address is unsupported", async function () { @@ -4429,7 +4432,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAndTwinWithBundle(offer, offerDates, offerDurations, disputeResolver.id, twin, agentId) - ).to.be.revertedWith(RevertReasons.UNSUPPORTED_TOKEN); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.UNSUPPORTED_TOKEN); }); it("Token address is a contract address that does not support the isApprovedForAll", async function () { @@ -4439,7 +4442,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAndTwinWithBundle(offer, offerDates, offerDurations, disputeResolver.id, twin, agentId) - ).to.be.revertedWith(RevertReasons.UNSUPPORTED_TOKEN); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.UNSUPPORTED_TOKEN); }); it("Token address is a contract that reverts from a fallback method", async function () { @@ -4449,7 +4452,7 @@ describe("IBosonOrchestrationHandler", function () { orchestrationHandler .connect(assistant) .createOfferAndTwinWithBundle(offer, offerDates, offerDurations, disputeResolver.id, twin, agentId) - ).to.be.revertedWith(RevertReasons.UNSUPPORTED_TOKEN); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.UNSUPPORTED_TOKEN); }); }); }); @@ -5291,7 +5294,7 @@ describe("IBosonOrchestrationHandler", function () { twin, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The offers region of protocol is paused", async function () { @@ -5311,7 +5314,7 @@ describe("IBosonOrchestrationHandler", function () { twin, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The groups region of protocol is paused", async function () { @@ -5331,7 +5334,7 @@ describe("IBosonOrchestrationHandler", function () { twin, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The bundles region of protocol is paused", async function () { @@ -5351,7 +5354,7 @@ describe("IBosonOrchestrationHandler", function () { twin, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The twins region of protocol is paused", async function () { @@ -5371,7 +5374,7 @@ describe("IBosonOrchestrationHandler", function () { twin, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The exchanges region of protocol is paused [preminted offers]", async function () { @@ -5394,7 +5397,7 @@ describe("IBosonOrchestrationHandler", function () { twin, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); }); }); @@ -6112,7 +6115,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The sellers region of protocol is paused", async function () { @@ -6134,7 +6137,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The offers region of protocol is paused", async function () { @@ -6156,7 +6159,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The groups region of protocol is paused", async function () { @@ -6178,7 +6181,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The exchanges region of protocol is paused", async function () { @@ -6203,7 +6206,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); }); }); @@ -7026,7 +7029,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The sellers region of protocol is paused", async function () { @@ -7048,7 +7051,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The offers region of protocol is paused", async function () { @@ -7070,7 +7073,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The bundles region of protocol is paused", async function () { @@ -7092,7 +7095,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The twins region of protocol is paused", async function () { @@ -7114,7 +7117,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The exchanges region of protocol is paused [preminted offers]", async function () { @@ -7142,7 +7145,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); }); }); @@ -8066,7 +8069,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The sellers region of protocol is paused", async function () { @@ -8089,7 +8092,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The offers region of protocol is paused", async function () { @@ -8112,7 +8115,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The groups region of protocol is paused", async function () { @@ -8135,7 +8138,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The twins region of protocol is paused", async function () { @@ -8158,7 +8161,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The bundles region of protocol is paused", async function () { @@ -8181,7 +8184,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The exchanges region of protocol is paused [preminted offers]", async function () { @@ -8210,7 +8213,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); }); }); diff --git a/test/protocol/PauseHandlerTest.js b/test/protocol/PauseHandlerTest.js index 565cfedc7..92c4cd913 100644 --- a/test/protocol/PauseHandlerTest.js +++ b/test/protocol/PauseHandlerTest.js @@ -1,6 +1,6 @@ const { ethers } = require("hardhat"); const { expect } = require("chai"); -const { id } = ethers; +const { id, getContractAt } = ethers; const { getStorageAt } = require("@nomicfoundation/hardhat-network-helpers"); const PausableRegion = require("../../scripts/domain/PausableRegion.js"); const { getInterfaceIds } = require("../../scripts/config/supported-interfaces.js"); @@ -21,6 +21,8 @@ describe("IBosonPauseHandler", function () { let pauser, rando; let erc165, pauseHandler, support, regions; let snapshotId; + let bosonErrors; + // uint256 constant ALL_REGIONS_MASK = (1 << (uint256(type(BosonTypes.PausableRegion).max) + 1)) - 1; const ALL_REGIONS_MASK = (1 << PausableRegion.Regions.length) - 1; @@ -39,6 +41,8 @@ describe("IBosonPauseHandler", function () { contractInstances: { erc165, pauseHandler }, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", await pauseHandler.getAddress()); + // Get snapshot id snapshotId = await getSnapshot(); }); @@ -147,7 +151,10 @@ describe("IBosonPauseHandler", function () { context("💔 Revert Reasons", async function () { it("Caller does not have PAUSER role", async function () { // Attempt to pause without PAUSER role, expecting revert - await expect(pauseHandler.connect(rando).pause([])).to.revertedWith(RevertReasons.ACCESS_DENIED); + await expect(pauseHandler.connect(rando).pause([])).to.revertedWithCustomError( + bosonErrors, + RevertReasons.ACCESS_DENIED + ); }); }); }); @@ -203,12 +210,18 @@ describe("IBosonPauseHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Exchanges]); // Attempt to unpause without PAUSER role, expecting revert - await expect(pauseHandler.connect(rando).unpause([])).to.revertedWith(RevertReasons.ACCESS_DENIED); + await expect(pauseHandler.connect(rando).unpause([])).to.revertedWithCustomError( + bosonErrors, + RevertReasons.ACCESS_DENIED + ); }); it("Protocol is not currently paused", async function () { // Attempt to unpause while not paused, expecting revert - await expect(pauseHandler.connect(pauser).unpause([])).to.revertedWith(RevertReasons.NOT_PAUSED); + await expect(pauseHandler.connect(pauser).unpause([])).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NOT_PAUSED + ); }); }); }); diff --git a/test/protocol/PriceDiscoveryHandlerFacet.js b/test/protocol/PriceDiscoveryHandlerFacet.js index d2a44c867..b88d23e85 100644 --- a/test/protocol/PriceDiscoveryHandlerFacet.js +++ b/test/protocol/PriceDiscoveryHandlerFacet.js @@ -76,6 +76,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { let priceDiscoveryContract; let tokenId; let bosonVoucher; + let bosonErrors; before(async function () { accountId.next(true); @@ -116,6 +117,8 @@ describe("IPriceDiscoveryHandlerFacet", function () { diamondAddress: protocolDiamondAddress, } = await setupTestEnvironment(contracts, { wethAddress: await weth.getAddress() })); + bosonErrors = await getContractAt("BosonErrors", await configHandler.getAddress()); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -463,7 +466,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The buyers region of protocol is paused", async function () { @@ -475,7 +478,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("buyer address is the zero address", async function () { @@ -484,7 +487,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(ZeroAddress, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("token id is invalid", async function () { @@ -512,7 +515,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_HAS_BEEN_VOIDED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); }); it("offer is not yet available for commits", async function () { @@ -541,7 +544,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_NOT_AVAILABLE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_NOT_AVAILABLE); }); it("offer has expired", async function () { @@ -553,7 +556,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_EXPIRED); }); it.skip("offer sold", async function () { @@ -571,7 +574,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.FEE_AMOUNT_TOO_HIGH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FEE_AMOUNT_TOO_HIGH); }); it("insufficient values sent", async function () { @@ -581,7 +584,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.INSUFFICIENT_VALUE_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_VALUE_RECEIVED); }); it("price discovery does not send the voucher anywhere", async function () { @@ -609,7 +612,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.TOKEN_ID_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_ID_MISMATCH); }); it("price discovery does not send the voucher to the protocol", async function () { @@ -642,7 +645,43 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.VOUCHER_NOT_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VOUCHER_NOT_RECEIVED); + }); + + it("price discovery address is not set", async function () { + // An invalid price discovery address + priceDiscovery.priceDiscoveryContract = ZeroAddress; + + // Attempt to commit, expecting revert + await expect( + priceDiscoveryHandler + .connect(buyer) + .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_PRICE_DISCOVERY); + }); + + it("price discovery data is empty", async function () { + // An empty price discovery data + priceDiscovery.priceDiscoveryData = "0x"; + + // Attempt to commit, expecting revert + await expect( + priceDiscoveryHandler + .connect(buyer) + .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_PRICE_DISCOVERY); + }); + + it("conduit address is not set", async function () { + // An invalid conduit address + priceDiscovery.conduit = ZeroAddress; + + // Attempt to commit, expecting revert + await expect( + priceDiscoveryHandler + .connect(buyer) + .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_CONDUIT_ADDRESS); }); }); }); @@ -807,7 +846,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(assistant) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The buyers region of protocol is paused", async function () { @@ -819,14 +858,14 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(assistant) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("buyer address is the zero address", async function () { // Attempt to commit, expecting revert await expect( priceDiscoveryHandler.connect(assistant).commitToPriceDiscoveryOffer(ZeroAddress, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("offer id is invalid", async function () { @@ -839,7 +878,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(assistant) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.NO_SUCH_OFFER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_OFFER); }); it("token id is invalid", async function () { @@ -864,7 +903,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(assistant) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_HAS_BEEN_VOIDED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); }); it("offer is not yet available for commits", async function () { @@ -893,7 +932,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(assistant) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_NOT_AVAILABLE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_NOT_AVAILABLE); }); it("offer has expired", async function () { @@ -905,7 +944,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(assistant) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_EXPIRED); }); it.skip("offer sold", async function () { @@ -923,7 +962,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(assistant) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.FEE_AMOUNT_TOO_HIGH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FEE_AMOUNT_TOO_HIGH); }); it("voucher transfer not approved", async function () { @@ -947,14 +986,50 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(assistant) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.INSUFFICIENT_VALUE_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_VALUE_RECEIVED); }); it("Only seller can call, if side is bid", async function () { // Commit to offer, retrieving the event await expect( priceDiscoveryHandler.connect(rando).commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.NOT_VOUCHER_HOLDER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER); + }); + + it("price discovery address is not set", async function () { + // An invalid price discovery address + priceDiscovery.priceDiscoveryContract = ZeroAddress; + + // Attempt to commit, expecting revert + await expect( + priceDiscoveryHandler + .connect(assistant) + .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_PRICE_DISCOVERY); + }); + + it("price discovery data is empty", async function () { + // An empty price discovery data + priceDiscovery.priceDiscoveryData = "0x"; + + // Attempt to commit, expecting revert + await expect( + priceDiscoveryHandler + .connect(assistant) + .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_PRICE_DISCOVERY); + }); + + it("conduit address is not set", async function () { + // An invalid conduit address + priceDiscovery.conduit = ZeroAddress; + + // Attempt to commit, expecting revert + await expect( + priceDiscoveryHandler + .connect(assistant) + .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_CONDUIT_ADDRESS); }); }); }); @@ -995,7 +1070,8 @@ describe("IPriceDiscoveryHandlerFacet", function () { expect(await bosonVoucher.ownerOf(tokenId)).to.equal(await mockAuction.getAddress()); // safe transfer from will fail on onPremintedTransferredHook and transaction should fail - await expect(mockAuction.connect(rando).endAuction(auctionId)).to.be.revertedWith( + await expect(mockAuction.connect(rando).endAuction(auctionId)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.VOUCHER_TRANSFER_NOT_ALLOWED ); @@ -1180,7 +1256,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.TOKEN_ID_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_ID_MISMATCH); }); it("Correct token id, wrong caller", async function () { @@ -1222,7 +1298,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { priceDiscoveryHandler .connect(buyer) .commitToPriceDiscoveryOffer(buyer.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.UNEXPECTED_ERC721_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.UNEXPECTED_ERC721_RECEIVED); }); }); }); @@ -1249,7 +1325,8 @@ describe("IPriceDiscoveryHandlerFacet", function () { price: "0", }; - await expect(priceDiscoveryContract.fulfilBuyOrder(order)).to.be.revertedWith( + await expect(priceDiscoveryContract.fulfilBuyOrder(order)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.VOUCHER_TRANSFER_NOT_ALLOWED ); }); @@ -1260,7 +1337,7 @@ describe("IPriceDiscoveryHandlerFacet", function () { const tokenId = deriveTokenId(offer.id, exchangeId); await expect( bosonVoucher.connect(assistant).transferFrom(assistant.address, rando.address, tokenId) - ).to.be.revertedWith(RevertReasons.VOUCHER_TRANSFER_NOT_ALLOWED); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.VOUCHER_TRANSFER_NOT_ALLOWED); }); }); }); diff --git a/test/protocol/ProtocolDiamondTest.js b/test/protocol/ProtocolDiamondTest.js index f19d05806..14c269381 100644 --- a/test/protocol/ProtocolDiamondTest.js +++ b/test/protocol/ProtocolDiamondTest.js @@ -1054,7 +1054,7 @@ describe("ProtocolDiamond", async function () { // Attempt to deploy Protocol Diamond const ProtocolDiamond = await getContractFactory("ProtocolDiamond"); - await expect(ProtocolDiamond.deploy(...diamondArgs)).to.revertedWith(RevertReasons.INVALID_ADDRESS); + await expect(ProtocolDiamond.deploy(...diamondArgs)).to.revertedWith("Invalid address"); }); }); }); diff --git a/test/protocol/ProtocolInitializationHandlerTest.js b/test/protocol/ProtocolInitializationHandlerTest.js index 4a2c78562..9abcf0134 100644 --- a/test/protocol/ProtocolInitializationHandlerTest.js +++ b/test/protocol/ProtocolInitializationHandlerTest.js @@ -39,6 +39,7 @@ describe("ProtocolInitializationHandler", async function () { let version; let maxPremintedVouchers, initializationData; let abiCoder; + let bosonErrors; before(async function () { // get interface Ids @@ -70,6 +71,8 @@ describe("ProtocolInitializationHandler", async function () { await protocolDiamond.getAddress() ); + bosonErrors = await getContractAt("BosonErrors", await protocolDiamond.getAddress()); + version = "2.2.0"; abiCoder = AbiCoder.defaultAbiCoder(); @@ -124,8 +127,9 @@ describe("ProtocolInitializationHandler", async function () { await getFees(maxPriorityFeePerGas), ]; - await expect(diamondCutFacet.connect(deployer).diamondCut(...cutArgs)).to.revertedWith( - RevertReasons.ADDRESSES_AND_CALLDATA_MUST_BE_SAME_LENGTH + await expect(diamondCutFacet.connect(deployer).diamondCut(...cutArgs)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.ADDRESSES_AND_CALLDATA_LENGTH_MISMATCH ); }); @@ -149,7 +153,8 @@ describe("ProtocolInitializationHandler", async function () { await getFees(maxPriorityFeePerGas), ]; - await expect(diamondCutFacet.connect(deployer).diamondCut(...cutArgs)).to.revertedWith( + await expect(diamondCutFacet.connect(deployer).diamondCut(...cutArgs)).to.revertedWithCustomError( + bosonErrors, RevertReasons.VERSION_MUST_BE_SET ); }); @@ -197,7 +202,7 @@ describe("ProtocolInitializationHandler", async function () { await getFees(maxPriorityFeePerGas) ); - await expect(cutTransaction).to.be.revertedWith(RevertReasons.ALREADY_INITIALIZED); + await expect(cutTransaction).to.be.revertedWithCustomError(bosonErrors, RevertReasons.ALREADY_INITIALIZED); }); it("Initialize is not called via proxy", async function () { @@ -238,7 +243,7 @@ describe("ProtocolInitializationHandler", async function () { [], [] ) - ).to.be.revertedWith(RevertReasons.DIRECT_INITIALIZATION_NOT_ALLOWED); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.DIRECT_INITIALIZATION_NOT_ALLOWED); }); }); }); @@ -408,7 +413,7 @@ describe("ProtocolInitializationHandler", async function () { calldataProtocolInitialization, await getFees(maxPriorityFeePerGas) ) - ).to.be.revertedWith(RevertReasons.PROTOCOL_INITIALIZATION_FAILED); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.PROTOCOL_INITIALIZATION_FAILED); }); }); }); @@ -523,7 +528,7 @@ describe("ProtocolInitializationHandler", async function () { calldataProtocolInitialization, await getFees(maxPriorityFeePerGas) ) - ).to.be.revertedWith(RevertReasons.VALUE_ZERO_NOT_ALLOWED); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.VALUE_ZERO_NOT_ALLOWED); }); it("Current version is not 0", async () => { @@ -552,7 +557,7 @@ describe("ProtocolInitializationHandler", async function () { calldataProtocolInitialization, await getFees(maxPriorityFeePerGas) ) - ).to.be.revertedWith(RevertReasons.WRONG_CURRENT_VERSION); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.WRONG_CURRENT_VERSION); }); }); }); @@ -645,7 +650,7 @@ describe("ProtocolInitializationHandler", async function () { calldataProtocolInitialization, await getFees(maxPriorityFeePerGas) ) - ).to.be.revertedWith(RevertReasons.WRONG_CURRENT_VERSION); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.WRONG_CURRENT_VERSION); }); }); }); @@ -805,7 +810,7 @@ describe("ProtocolInitializationHandler", async function () { deployedProtocolInitializationHandlerFacetAddress, calldataProtocolInitialization ) - ).to.be.revertedWith(RevertReasons.TWINS_ALREADY_EXIST); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.TWINS_ALREADY_EXIST); }); it("Min resolution period is zero", async function () { @@ -825,15 +830,13 @@ describe("ProtocolInitializationHandler", async function () { deployedProtocolInitializationHandlerFacetAddress, calldataProtocolInitialization ) - ).to.be.revertedWith(RevertReasons.VALUE_ZERO_NOT_ALLOWED); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.VALUE_ZERO_NOT_ALLOWED); }); it("Min resolution period is greater than max resolution period", async function () { version = "2.3.0"; - console.log("oneMonth", oneMonth); await configHandler.connect(deployer).setMaxResolutionPeriod(oneMonth); minResolutionPeriod = oneMonth + 1n; - console.log("minResolutionPeriod", minResolutionPeriod); initializationData = abiCoder.encode(["uint256", "uint256[]", "address[]"], [minResolutionPeriod, [], []]); calldataProtocolInitialization = deployedProtocolInitializationHandlerFacet.interface.encodeFunctionData( "initialize", @@ -846,7 +849,7 @@ describe("ProtocolInitializationHandler", async function () { deployedProtocolInitializationHandlerFacetAddress, calldataProtocolInitialization ) - ).to.be.revertedWith(RevertReasons.INVALID_RESOLUTION_PERIOD); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RESOLUTION_PERIOD); }); it("Current version is not 2.2.1", async () => { @@ -892,7 +895,7 @@ describe("ProtocolInitializationHandler", async function () { await deployedProtocolInitializationHandlerFacet.getAddress(), calldataProtocolInitialization ) - ).to.be.revertedWith(RevertReasons.WRONG_CURRENT_VERSION); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.WRONG_CURRENT_VERSION); }); }); }); diff --git a/test/protocol/SellerHandlerTest.js b/test/protocol/SellerHandlerTest.js index 191576136..34bb74031 100644 --- a/test/protocol/SellerHandlerTest.js +++ b/test/protocol/SellerHandlerTest.js @@ -63,6 +63,7 @@ describe("SellerHandler", function () { let mockAuthERC721Contract, mockAuthERC721Contract2; let snapshotId; let beaconProxyAddress; + let bosonErrors; before(async function () { // Reset the accountId iterator @@ -81,6 +82,8 @@ describe("SellerHandler", function () { contractInstances: { accountHandler, exchangeHandler, pauseHandler, configHandler }, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", await accountHandler.getAddress()); + // make all account the same authTokenOwner = assistant = admin; clerk = { address: ZeroAddress }; @@ -671,7 +674,7 @@ describe("SellerHandler", function () { // Attempt to create a seller expecting revert await expect( accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("active is false", async function () { @@ -680,7 +683,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller, expecting revert await expect( accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.MUST_BE_ACTIVE); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.MUST_BE_ACTIVE); }); it("addresses are not unique to this seller Id when address used for same role", async function () { @@ -699,7 +702,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with non-unique assistant, expecting revert await expect( accountHandler.connect(other1).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); seller.admin = await admin.getAddress(); seller.assistant = await assistant.getAddress(); @@ -707,7 +710,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with non-unique admin, expecting revert await expect( accountHandler.connect(admin).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); }); it("addresses are not unique to this seller Id when address used for different role", async function () { @@ -726,7 +729,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with non-unique assistant, expecting revert await expect( accountHandler.connect(other1).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); // Update seller admin seller.admin = await other3.getAddress(); @@ -743,7 +746,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with non-unique admin, expecting revert await expect( accountHandler.connect(other3).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); }); it("addresses are not unique to this seller Id when address used for same role and the seller is created with auth token", async function () { @@ -770,14 +773,14 @@ describe("SellerHandler", function () { // Attempt to Create a seller with non-unique assistant, expecting revert await expect( accountHandler.connect(authTokenOwner).createSeller(seller2, authToken, voucherInitValues) - ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); }); it("admin address is NOT zero address and AuthTokenType is NOT None", async function () { // Attempt to Create a seller, expecting revert await expect( accountHandler.connect(authTokenOwner).createSeller(seller, authToken, voucherInitValues) - ).to.revertedWith(RevertReasons.ADMIN_OR_AUTH_TOKEN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ADMIN_OR_AUTH_TOKEN); }); it("admin address is zero address and AuthTokenType is None", async function () { @@ -786,7 +789,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller, expecting revert await expect( accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.ADMIN_OR_AUTH_TOKEN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.ADMIN_OR_AUTH_TOKEN); }); it("authToken is not unique to this seller", async function () { @@ -800,7 +803,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with non-unique authToken await expect( accountHandler.connect(authTokenOwner).createSeller(seller, authToken, voucherInitValues) - ).to.revertedWith(RevertReasons.AUTH_TOKEN_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AUTH_TOKEN_MUST_BE_UNIQUE); }); it("authTokenType is Custom", async function () { @@ -812,7 +815,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with AuthTokenType == Custom, expecting revert await expect( accountHandler.connect(authTokenOwner).createSeller(seller, authToken, voucherInitValues) - ).to.revertedWith(RevertReasons.INVALID_AUTH_TOKEN_TYPE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_AUTH_TOKEN_TYPE); }); it("Caller is not the supplied admin", async function () { @@ -821,7 +824,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with admin not the same to caller address await expect( accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.NOT_ADMIN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN); }); it("Caller does not own supplied auth token", async function () { @@ -832,7 +835,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller without owning the auth token await expect( accountHandler.connect(rando).createSeller(seller, authToken, voucherInitValues) - ).to.revertedWith(RevertReasons.NOT_ADMIN); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN); }); it("Caller is not the supplied assistant", async function () { @@ -841,7 +844,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with assistant not the same to caller address await expect( accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ASSISTANT); }); it("Clerk is not a zero address", async function () { @@ -852,7 +855,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with clerk not 0 await expect( accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.CLERK_DEPRECATED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CLERK_DEPRECATED); }); it("addresses are the zero address", async function () { @@ -862,7 +865,7 @@ describe("SellerHandler", function () { // Attempt to update a seller, expecting revert await expect( accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("Assistant address is zero address", async function () { @@ -871,7 +874,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with assistant == zero address await expect( accountHandler.connect(authTokenOwner).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("Treasury address is zero address", async function () { @@ -880,7 +883,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with treasury == zero address await expect( accountHandler.connect(authTokenOwner).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("seller salt is not unique [same as the original salt]", async function () { @@ -898,7 +901,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with non unique salt, expecting revert await expect( accountHandler.connect(admin).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.SELLER_SALT_NOT_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_SALT_NOT_UNIQUE); }); it("seller salt is not unique [same as the updated salt]", async function () { @@ -919,7 +922,7 @@ describe("SellerHandler", function () { voucherInitValues.collectionSalt = newSalt; await expect( accountHandler.connect(admin).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.SELLER_SALT_NOT_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_SALT_NOT_UNIQUE); }); it("same wallet cannot use the same salt twice", async function () { @@ -938,7 +941,7 @@ describe("SellerHandler", function () { // Attempt to Create a seller with non unique salt, expecting revert await expect( accountHandler.connect(admin).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.CLONE_CREATION_FAILED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CLONE_CREATION_FAILED); }); }); }); @@ -1939,7 +1942,8 @@ describe("SellerHandler", function () { ); // Attempt to update the seller with original admin address, expecting revert - await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWith( + await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ADMIN ); }); @@ -2002,7 +2006,8 @@ describe("SellerHandler", function () { ); // Attempt to update the seller with original admin address, expecting revertStruct - await expect(accountHandler.connect(admin).updateSeller(seller, authToken)).to.revertedWith( + await expect(accountHandler.connect(admin).updateSeller(seller, authToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ADMIN ); }); @@ -2154,7 +2159,8 @@ describe("SellerHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Sellers]); // Attempt to update a seller expecting revert - await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWith( + await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -2164,7 +2170,8 @@ describe("SellerHandler", function () { seller.id = "444"; // Attempt to update the seller, expecting revert - await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWith( + await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_SELLER ); @@ -2172,14 +2179,16 @@ describe("SellerHandler", function () { seller.id = "0"; // Attempt to update the seller, expecting revert - await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWith( + await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_SELLER ); }); it("Caller is not seller admin", async function () { // Attempt to update the seller, expecting revert - await expect(accountHandler.connect(rando).updateSeller(seller, emptyAuthToken)).to.revertedWith( + await expect(accountHandler.connect(rando).updateSeller(seller, emptyAuthToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_ADMIN ); }); @@ -2189,36 +2198,36 @@ describe("SellerHandler", function () { seller.treasury = ZeroAddress; // Attempt to update a seller, expecting revert - await expect(accountHandler.connect(authTokenOwner).updateSeller(seller, emptyAuthToken)).to.revertedWith( - RevertReasons.INVALID_ADDRESS - ); + await expect( + accountHandler.connect(authTokenOwner).updateSeller(seller, emptyAuthToken) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("Assistant is the zero address", async function () { seller.assistant = ZeroAddress; // Attempt to update a seller, expecting revert - await expect(accountHandler.connect(authTokenOwner).updateSeller(seller, emptyAuthToken)).to.revertedWith( - RevertReasons.INVALID_ADDRESS - ); + await expect( + accountHandler.connect(authTokenOwner).updateSeller(seller, emptyAuthToken) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("Clerk is not a zero address", async function () { seller.clerk = await rando.getAddress(); // Attempt to update a seller, expecting revert - await expect(accountHandler.connect(authTokenOwner).updateSeller(seller, emptyAuthToken)).to.revertedWith( - RevertReasons.CLERK_DEPRECATED - ); + await expect( + accountHandler.connect(authTokenOwner).updateSeller(seller, emptyAuthToken) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CLERK_DEPRECATED); }); it("Treasury is the zero address", async function () { seller.treasury = ZeroAddress; // Attempt to update a seller, expecting revert - await expect(accountHandler.connect(authTokenOwner).updateSeller(seller, emptyAuthToken)).to.revertedWith( - RevertReasons.INVALID_ADDRESS - ); + await expect( + accountHandler.connect(authTokenOwner).updateSeller(seller, emptyAuthToken) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("addresses are not unique to this seller Id when addresses used for same role", async function () { @@ -2243,7 +2252,8 @@ describe("SellerHandler", function () { seller.assistant = await assistant.getAddress(); //already being used by seller 1 // Attempt to update seller 2 with non-unique assistant, expecting revert - await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWith( + await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE ); @@ -2251,7 +2261,8 @@ describe("SellerHandler", function () { seller.assistant = await other1.getAddress(); // Attempt to update a seller with non-unique admin, expecting revert - await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWith( + await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE ); }); @@ -2278,7 +2289,8 @@ describe("SellerHandler", function () { seller.admin = await assistant.getAddress(); // Attempt to update seller 2 with non-unique assistant, expecting revert - await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWith( + await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE ); @@ -2287,14 +2299,16 @@ describe("SellerHandler", function () { seller.assistant = await admin.getAddress(); // Attempt to update a seller with non-unique admin, expecting revert - await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWith( + await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE ); }); it("admin address is NOT zero address and AuthTokenType is NOT None", async function () { // Attempt to update a seller, expecting revert - await expect(accountHandler.connect(admin).updateSeller(seller, authToken)).to.revertedWith( + await expect(accountHandler.connect(admin).updateSeller(seller, authToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.ADMIN_OR_AUTH_TOKEN ); }); @@ -2303,7 +2317,8 @@ describe("SellerHandler", function () { seller.admin = ZeroAddress; // Attempt to Create a seller, expecting revert - await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWith( + await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.ADMIN_OR_AUTH_TOKEN ); }); @@ -2332,7 +2347,8 @@ describe("SellerHandler", function () { seller2.admin = ZeroAddress; // Attempt to update seller2 with non-unique authToken used by seller 1 - await expect(accountHandler.connect(other1).updateSeller(seller2, authToken)).to.revertedWith( + await expect(accountHandler.connect(other1).updateSeller(seller2, authToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.AUTH_TOKEN_MUST_BE_UNIQUE ); }); @@ -2344,9 +2360,9 @@ describe("SellerHandler", function () { authToken.tokenType = AuthTokenType.Custom; // Attempt to Update a seller with AuthTokenType == Custom, expecting revert - await expect(accountHandler.connect(authTokenOwner).updateSeller(seller, authToken)).to.revertedWith( - RevertReasons.INVALID_AUTH_TOKEN_TYPE - ); + await expect( + accountHandler.connect(authTokenOwner).updateSeller(seller, authToken) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_AUTH_TOKEN_TYPE); }); it("seller is not owner of auth token currently stored for seller", async function () { @@ -2370,9 +2386,9 @@ describe("SellerHandler", function () { .transferFrom(await authTokenOwner.getAddress(), await other7.getAddress(), 0); // Attempt to update seller2 for token that seller doesn't own - await expect(accountHandler.connect(authTokenOwner).updateSeller(seller2, authToken2)).to.revertedWith( - RevertReasons.NOT_ADMIN - ); + await expect( + accountHandler.connect(authTokenOwner).updateSeller(seller2, authToken2) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN); }); it("auth token id does not exist", async function () { @@ -2393,7 +2409,8 @@ describe("SellerHandler", function () { }); it("No updates applied or set to pending", async function () { - await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWith( + await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_UPDATE_APPLIED ); }); @@ -2573,7 +2590,7 @@ describe("SellerHandler", function () { await expect( accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]) - ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.UNAUTHORIZED_CALLER_UPDATE); await expect(accountHandler.connect(other2).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant])) .to.emit(accountHandler, "SellerUpdateApplied") @@ -2608,7 +2625,7 @@ describe("SellerHandler", function () { await expect( accountHandler.connect(authTokenOwner).optInToSellerUpdate(seller.id, [SellerUpdateFields.AuthToken]) - ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.UNAUTHORIZED_CALLER_UPDATE); await expect(accountHandler.connect(rando).optInToSellerUpdate(seller.id, [SellerUpdateFields.AuthToken])) .to.emit(accountHandler, "SellerUpdateApplied") @@ -2747,7 +2764,8 @@ describe("SellerHandler", function () { await other1.getAddress() ); - await expect(accountHandler.connect(other1).optInToSellerUpdate(seller.id, [])).to.revertedWith( + await expect(accountHandler.connect(other1).optInToSellerUpdate(seller.id, [])).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_PENDING_UPDATE_FOR_ACCOUNT ); }); @@ -2778,7 +2796,7 @@ describe("SellerHandler", function () { // Attempt to update seller1 with non-unique authToken used by seller 2 await expect( accountHandler.connect(newAuthTokenOwner).optInToSellerUpdate(seller.id, [SellerUpdateFields.AuthToken]) - ).to.revertedWith(RevertReasons.AUTH_TOKEN_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.AUTH_TOKEN_MUST_BE_UNIQUE); }); it("Caller is not the new admin", async function () { @@ -2788,7 +2806,7 @@ describe("SellerHandler", function () { await expect( accountHandler.connect(other2).optInToSellerUpdate(seller.id, [SellerUpdateFields.Admin]) - ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.UNAUTHORIZED_CALLER_UPDATE); }); it("Caller is not the new assistant", async function () { @@ -2798,7 +2816,7 @@ describe("SellerHandler", function () { await expect( accountHandler.connect(other2).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]) - ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.UNAUTHORIZED_CALLER_UPDATE); }); it("Should revert if the caller is not the new auth token owner", async function () { @@ -2808,7 +2826,7 @@ describe("SellerHandler", function () { await expect( accountHandler.connect(other2).optInToSellerUpdate(seller.id, [SellerUpdateFields.AuthToken]) - ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.UNAUTHORIZED_CALLER_UPDATE); }); it("The sellers region of protocol is paused", async function () { @@ -2819,7 +2837,8 @@ describe("SellerHandler", function () { // Pause the sellers region of the protocol await pauseHandler.connect(pauser).pause([PausableRegion.Sellers]); - await expect(accountHandler.connect(rando).optInToSellerUpdate(seller.id, [])).to.revertedWith( + await expect(accountHandler.connect(rando).optInToSellerUpdate(seller.id, [])).to.revertedWithCustomError( + bosonErrors, RevertReasons.REGION_PAUSED ); }); @@ -2843,7 +2862,7 @@ describe("SellerHandler", function () { // Attempt to approve the update with non-unique admin, expecting revert await expect( accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Admin]) - ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); }); it("Assistant is not unique to this seller", async function () { @@ -2865,7 +2884,7 @@ describe("SellerHandler", function () { // Attempt to approve the update with non-unique assistant, expecting revert await expect( accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]) - ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); }); it("Seller tries to update the clerk", async function () { @@ -2875,7 +2894,7 @@ describe("SellerHandler", function () { await expect( accountHandler.connect(other2).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk]) - ).to.revertedWith(RevertReasons.CLERK_DEPRECATED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CLERK_DEPRECATED); }); }); }); @@ -3115,14 +3134,14 @@ describe("SellerHandler", function () { // Attempt to create a new collection expecting revert await expect( accountHandler.connect(assistant).createNewCollection(externalId, voucherInitValues) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Caller is not anyone's assistant", async function () { // Attempt to create a new collection await expect( accountHandler.connect(rando).createNewCollection(externalId, voucherInitValues) - ).to.revertedWith(RevertReasons.NO_SUCH_SELLER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_SELLER); }); it("Collection creation fails", async function () { @@ -3131,7 +3150,7 @@ describe("SellerHandler", function () { // Try to create a collection with already used salt await expect( accountHandler.connect(assistant).createNewCollection(externalId, voucherInitValues) - ).to.revertedWith(RevertReasons.CLONE_CREATION_FAILED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.CLONE_CREATION_FAILED); }); it("seller salt does not exist yet, and new salt is not unique", async function () { @@ -3188,7 +3207,7 @@ describe("SellerHandler", function () { // Try to create a collection with already used salt await expect( accountHandler.connect(assistant).createNewCollection(externalId, voucherInitValues) - ).to.revertedWith(RevertReasons.SELLER_SALT_NOT_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_SALT_NOT_UNIQUE); }); }); }); @@ -3330,31 +3349,31 @@ describe("SellerHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Sellers]); // Attempt to update the salt, expecting revert - await expect(accountHandler.connect(admin).updateSellerSalt(seller.id, newSellerSalt)).to.revertedWith( - RevertReasons.REGION_PAUSED - ); + await expect( + accountHandler.connect(admin).updateSellerSalt(seller.id, newSellerSalt) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("Caller is not anyone's admin", async function () { // Attempt to update the salt, expecting revert - await expect(accountHandler.connect(rando).updateSellerSalt(seller.id, newSellerSalt)).to.revertedWith( - RevertReasons.NOT_ADMIN - ); + await expect( + accountHandler.connect(rando).updateSellerSalt(seller.id, newSellerSalt) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_ADMIN); }); it("Caller is not anyone's admin", async function () { const sellerId = "444"; // Attempt to update the salt, expecting revert - await expect(accountHandler.connect(admin).updateSellerSalt(sellerId, newSellerSalt)).to.revertedWith( - RevertReasons.NO_SUCH_SELLER - ); + await expect( + accountHandler.connect(admin).updateSellerSalt(sellerId, newSellerSalt) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_SELLER); }); it("seller salt is not unique [same seller id]", async function () { // Attempt to update the salt, expecting revert await expect( accountHandler.connect(admin).updateSellerSalt(seller.id, voucherInitValues.collectionSalt) - ).to.revertedWith(RevertReasons.SELLER_SALT_NOT_UNIQUE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_SALT_NOT_UNIQUE); }); it("seller salt is not unique [different seller id]", async function () { @@ -3374,9 +3393,9 @@ describe("SellerHandler", function () { await accountHandler.connect(admin).createSeller(seller, emptyAuthToken, voucherInitValues); // Attempt to update the salt, expecting revert - await expect(accountHandler.connect(admin).updateSellerSalt(newSellerId, newSellerSalt)).to.revertedWith( - RevertReasons.SELLER_SALT_NOT_UNIQUE - ); + await expect( + accountHandler.connect(admin).updateSellerSalt(newSellerId, newSellerSalt) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.SELLER_SALT_NOT_UNIQUE); }); }); }); diff --git a/test/protocol/SequentialCommitHandlerTest.js b/test/protocol/SequentialCommitHandlerTest.js index e643c7280..e0ffdee35 100644 --- a/test/protocol/SequentialCommitHandlerTest.js +++ b/test/protocol/SequentialCommitHandlerTest.js @@ -73,6 +73,7 @@ describe("IBosonSequentialCommitHandler", function () { let snapshotId; let priceDiscoveryContract; let tokenId; + let bosonErrors; before(async function () { accountId.next(true); @@ -113,6 +114,8 @@ describe("IBosonSequentialCommitHandler", function () { diamondAddress: protocolDiamondAddress, } = await setupTestEnvironment(contracts, { wethAddress: await weth.getAddress() })); + bosonErrors = await getContractAt("BosonErrors", await configHandler.getAddress()); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -388,7 +391,8 @@ describe("IBosonSequentialCommitHandler", function () { .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price2 }); // Old buyer cannot redeem - await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.be.revertedWith( + await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER ); @@ -406,7 +410,8 @@ describe("IBosonSequentialCommitHandler", function () { .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price2 }); // Old buyer cannot redeem - await expect(exchangeHandler.connect(buyer).cancelVoucher(exchangeId)).to.be.revertedWith( + await expect(exchangeHandler.connect(buyer).cancelVoucher(exchangeId)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER ); @@ -470,7 +475,7 @@ describe("IBosonSequentialCommitHandler", function () { // Committing directly is not possible await expect( exchangeHandler.connect(buyer2).commitToOffer(buyer2.address, offerId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_HAS_BEEN_VOIDED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); // Sequential commit to offer, retrieving the event await expect( @@ -484,7 +489,8 @@ describe("IBosonSequentialCommitHandler", function () { it("It is possible to commit even if redemption period has not started yet", async function () { // Redemption not yet possible - await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.VOUCHER_NOT_REDEEMABLE ); @@ -505,7 +511,7 @@ describe("IBosonSequentialCommitHandler", function () { // Committing directly is not possible await expect( exchangeHandler.connect(buyer2).commitToOffer(buyer2.address, offerId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_EXPIRED); // Sequential commit to offer, retrieving the event await expect( @@ -526,7 +532,7 @@ describe("IBosonSequentialCommitHandler", function () { // Committing directly is not possible await expect( exchangeHandler.connect(buyer2).commitToOffer(buyer2.address, offerId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_SOLD_OUT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_SOLD_OUT); // Sequential commit to offer, retrieving the event await expect( @@ -548,7 +554,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(buyer2) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price2 }) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The buyers region of protocol is paused", async function () { @@ -560,7 +566,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(buyer2) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price2 }) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("buyer address is the zero address", async function () { @@ -569,7 +575,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(buyer2) .sequentialCommitToOffer(ZeroAddress, exchangeId, priceDiscovery, { value: price2 }) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("exchange id is invalid", async function () { @@ -582,7 +588,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(buyer2) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price2 }) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("voucher not valid anymore", async function () { @@ -594,7 +600,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(buyer2) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price2 }) - ).to.revertedWith(RevertReasons.VOUCHER_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VOUCHER_HAS_EXPIRED); }); it("protocol fees to high", async function () { @@ -608,7 +614,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(buyer2) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price2 }) - ).to.revertedWith(RevertReasons.FEE_AMOUNT_TOO_HIGH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FEE_AMOUNT_TOO_HIGH); }); it("insufficient values sent", async function () { @@ -617,7 +623,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(buyer2) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price }) - ).to.revertedWith(RevertReasons.INSUFFICIENT_VALUE_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_VALUE_RECEIVED); }); it("price discovery does not send the voucher anywhere", async function () { @@ -652,7 +658,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(buyer2) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price2 }) - ).to.revertedWith(RevertReasons.TOKEN_ID_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_ID_MISMATCH); }); it("price discovery does not send the voucher to the protocol", async function () { @@ -691,7 +697,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(buyer2) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price2 }) - ).to.revertedWith(RevertReasons.VOUCHER_NOT_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VOUCHER_NOT_RECEIVED); }); }); }); @@ -986,7 +992,8 @@ describe("IBosonSequentialCommitHandler", function () { .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery); // Old buyer cannot redeem - await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.be.revertedWith( + await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER ); @@ -1004,7 +1011,8 @@ describe("IBosonSequentialCommitHandler", function () { .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery); // Old buyer cannot redeem - await expect(exchangeHandler.connect(buyer).cancelVoucher(exchangeId)).to.be.revertedWith( + await expect(exchangeHandler.connect(buyer).cancelVoucher(exchangeId)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER ); @@ -1052,9 +1060,9 @@ describe("IBosonSequentialCommitHandler", function () { await offerHandler.connect(assistant).voidOffer(offerId); // Committing directly is not possible - await expect(exchangeHandler.connect(buyer2).commitToOffer(buyer2.address, offerId)).to.revertedWith( - RevertReasons.OFFER_HAS_BEEN_VOIDED - ); + await expect( + exchangeHandler.connect(buyer2).commitToOffer(buyer2.address, offerId) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); // Sequential commit to offer, retrieving the event await expect( @@ -1066,7 +1074,8 @@ describe("IBosonSequentialCommitHandler", function () { it("It is possible to commit even if redemption period has not started yet", async function () { // Redemption not yet possible - await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.revertedWith( + await expect(exchangeHandler.connect(buyer).redeemVoucher(exchangeId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.VOUCHER_NOT_REDEEMABLE ); @@ -1083,9 +1092,9 @@ describe("IBosonSequentialCommitHandler", function () { await setNextBlockTimestamp(Number(offerDates.validUntil) + 1); // Committing directly is not possible - await expect(exchangeHandler.connect(buyer2).commitToOffer(buyer2.address, offerId)).to.revertedWith( - RevertReasons.OFFER_HAS_EXPIRED - ); + await expect( + exchangeHandler.connect(buyer2).commitToOffer(buyer2.address, offerId) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_EXPIRED); // Sequential commit to offer, retrieving the event await expect( @@ -1104,7 +1113,7 @@ describe("IBosonSequentialCommitHandler", function () { // Committing directly is not possible await expect( exchangeHandler.connect(buyer2).commitToOffer(buyer2.address, offerId, { value: price }) - ).to.revertedWith(RevertReasons.OFFER_SOLD_OUT); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_SOLD_OUT); // Sequential commit to offer, retrieving the event await expect( @@ -1124,7 +1133,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(reseller) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("The buyers region of protocol is paused", async function () { @@ -1136,7 +1145,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(reseller) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.REGION_PAUSED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED); }); it("buyer address is the zero address", async function () { @@ -1145,7 +1154,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(reseller) .sequentialCommitToOffer(ZeroAddress, exchangeId, priceDiscovery) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("exchange id is invalid", async function () { @@ -1158,7 +1167,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(reseller) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.NO_SUCH_EXCHANGE); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NO_SUCH_EXCHANGE); }); it("voucher not valid anymore", async function () { @@ -1170,7 +1179,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(reseller) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.VOUCHER_HAS_EXPIRED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.VOUCHER_HAS_EXPIRED); }); it("protocol fees to high", async function () { @@ -1184,7 +1193,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(reseller) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.FEE_AMOUNT_TOO_HIGH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.FEE_AMOUNT_TOO_HIGH); }); it("voucher transfer not approved", async function () { @@ -1208,14 +1217,14 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(reseller) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.INSUFFICIENT_VALUE_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INSUFFICIENT_VALUE_RECEIVED); }); it("Only seller can call, if side is bid", async function () { // Sequential commit to offer, retrieving the event await expect( sequentialCommitHandler.connect(rando).sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery) - ).to.revertedWith(RevertReasons.NOT_VOUCHER_HOLDER); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.NOT_VOUCHER_HOLDER); }); }); }); @@ -1525,7 +1534,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(buyer2) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price2 }) - ).to.revertedWith(RevertReasons.TOKEN_ID_MISMATCH); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.TOKEN_ID_MISMATCH); }); it("Correct token id, wrong caller", async function () { @@ -1567,7 +1576,7 @@ describe("IBosonSequentialCommitHandler", function () { sequentialCommitHandler .connect(buyer2) .sequentialCommitToOffer(buyer2.address, tokenId, priceDiscovery, { value: price2 }) - ).to.revertedWith(RevertReasons.UNEXPECTED_ERC721_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.UNEXPECTED_ERC721_RECEIVED); }); it("Random erc721 transfer", async function () { @@ -1580,7 +1589,7 @@ describe("IBosonSequentialCommitHandler", function () { // Attempt to sequentially commit, expecting revert await expect( foreign721["safeTransferFrom(address,address,uint256)"](deployer.address, protocolDiamondAddress, tokenId) - ).to.revertedWith(RevertReasons.UNEXPECTED_ERC721_RECEIVED); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.UNEXPECTED_ERC721_RECEIVED); }); }); }); diff --git a/test/protocol/TwinHandlerTest.js b/test/protocol/TwinHandlerTest.js index 8ae5c61c0..853fe8bd7 100644 --- a/test/protocol/TwinHandlerTest.js +++ b/test/protocol/TwinHandlerTest.js @@ -1,5 +1,5 @@ const { ethers } = require("hardhat"); -const { ZeroAddress, MaxUint256, id: ethersId } = ethers; +const { ZeroAddress, MaxUint256, id: ethersId, getContractAt } = ethers; const { expect, assert } = require("chai"); const Twin = require("../../scripts/domain/Twin"); const Bundle = require("../../scripts/domain/Bundle"); @@ -50,6 +50,7 @@ describe("IBosonTwinHandler", function () { let voucherInitValues; let emptyAuthToken; let snapshotId; + let bosonErrors; before(async function () { // get interface Ids @@ -70,6 +71,8 @@ describe("IBosonTwinHandler", function () { contractInstances: { erc165, accountHandler, twinHandler, bundleHandler, offerHandler, pauseHandler }, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", await accountHandler.getAddress()); + // make all account the same assistant = admin; clerk = { address: ZeroAddress }; @@ -343,19 +346,26 @@ describe("IBosonTwinHandler", function () { await pauseHandler.connect(pauser).pause([PausableRegion.Twins]); // Attempt to Remove a twin, expecting revert - await expect(twinHandler.connect(assistant).createTwin(twin)).to.revertedWith(RevertReasons.REGION_PAUSED); + await expect(twinHandler.connect(assistant).createTwin(twin)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.REGION_PAUSED + ); }); it("Caller not assistant of any seller", async function () { // Attempt to Create a twin, expecting revert - await expect(twinHandler.connect(rando).createTwin(twin)).to.revertedWith(RevertReasons.NOT_ASSISTANT); + await expect(twinHandler.connect(rando).createTwin(twin)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NOT_ASSISTANT + ); }); it("protocol is not approved to transfer the ERC20 token", async function () { //ERC20 token address twin.tokenAddress = await bosonToken.getAddress(); - await expect(twinHandler.connect(assistant).createTwin(twin)).to.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_TRANSFER_APPROVED ); }); @@ -364,7 +374,8 @@ describe("IBosonTwinHandler", function () { //ERC721 token address twin.tokenAddress = await foreign721.getAddress(); - await expect(twinHandler.connect(assistant).createTwin(twin)).to.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_TRANSFER_APPROVED ); }); @@ -373,7 +384,8 @@ describe("IBosonTwinHandler", function () { //ERC1155 token address twin.tokenAddress = await foreign1155.getAddress(); - await expect(twinHandler.connect(assistant).createTwin(twin)).to.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_TRANSFER_APPROVED ); }); @@ -389,7 +401,8 @@ describe("IBosonTwinHandler", function () { twin.tokenAddress = await foreign721.getAddress(); twin.tokenType = TokenType.NonFungibleToken; - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_SUPPLY_AVAILABLE ); }); @@ -403,7 +416,8 @@ describe("IBosonTwinHandler", function () { twin.tokenAddress = await bosonToken.getAddress(); twin.tokenType = TokenType.FungibleToken; - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_AMOUNT ); }); @@ -418,7 +432,8 @@ describe("IBosonTwinHandler", function () { twin.tokenAddress = await foreign1155.getAddress(); twin.tokenType = TokenType.MultiToken; - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_AMOUNT ); }); @@ -431,7 +446,8 @@ describe("IBosonTwinHandler", function () { twin.tokenAddress = await bosonToken.getAddress(); twin.tokenType = TokenType.FungibleToken; - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_AMOUNT ); }); @@ -445,7 +461,8 @@ describe("IBosonTwinHandler", function () { twin.tokenAddress = await foreign1155.getAddress(); twin.tokenType = TokenType.MultiToken; - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_AMOUNT ); }); @@ -460,7 +477,8 @@ describe("IBosonTwinHandler", function () { await foreign721.connect(assistant).mint(twin.tokenId, "1"); await foreign721.connect(assistant).setApprovalForAll(await twinHandler.getAddress(), true); - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TWIN_PROPERTY ); }); @@ -480,28 +498,32 @@ describe("IBosonTwinHandler", function () { await twinHandler.connect(assistant).createTwin(twin); // Create another twin with exact same range - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TWIN_TOKEN_RANGE ); // Create an twin with ids range: ["0" ... "5"] twin.tokenId = "0"; twin.supplyAvailable = "6"; - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TWIN_TOKEN_RANGE ); // Create an twin with ids range: ["14" ... "18"] twin.tokenId = "14"; twin.supplyAvailable = "5"; - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TWIN_TOKEN_RANGE ); // Create an twin with ids range: ["6" ... "9"] twin.tokenId = "6"; twin.supplyAvailable = "4"; - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TWIN_TOKEN_RANGE ); }); @@ -519,7 +541,8 @@ describe("IBosonTwinHandler", function () { // Create new twin with same token address twin.supplyAvailable = "2"; - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TWIN_TOKEN_RANGE ); }); @@ -534,7 +557,8 @@ describe("IBosonTwinHandler", function () { await foreign721.connect(assistant).setApprovalForAll(await twinHandler.getAddress(), true); // Create new twin with same token address - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TWIN_TOKEN_RANGE ); }); @@ -549,7 +573,8 @@ describe("IBosonTwinHandler", function () { await foreign721.connect(assistant).setApprovalForAll(await twinHandler.getAddress(), true); // Create new twin with same token address - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TWIN_TOKEN_RANGE ); }); @@ -558,7 +583,8 @@ describe("IBosonTwinHandler", function () { it("Token address is a zero address", async function () { twin.tokenAddress = ZeroAddress; - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.UNSUPPORTED_TOKEN ); }); @@ -566,7 +592,8 @@ describe("IBosonTwinHandler", function () { it("Token address is a contract address that does not support the isApprovedForAll", async function () { twin.tokenAddress = await twinHandler.getAddress(); - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.UNSUPPORTED_TOKEN ); }); @@ -574,7 +601,8 @@ describe("IBosonTwinHandler", function () { it("Token address is a contract that reverts from a fallback method", async function () { twin.tokenAddress = await fallbackError.getAddress(); - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.UNSUPPORTED_TOKEN ); }); @@ -584,7 +612,8 @@ describe("IBosonTwinHandler", function () { twin.tokenType = TokenType.NonFungibleToken; twin.tokenAddress = await bosonToken.getAddress(); - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TOKEN_ADDRESS ); }); @@ -594,7 +623,8 @@ describe("IBosonTwinHandler", function () { twin.tokenType = TokenType.MultiToken; twin.tokenAddress = await bosonToken.getAddress(); - await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TOKEN_ADDRESS ); }); @@ -691,10 +721,12 @@ describe("IBosonTwinHandler", function () { // We don't have getters, so we implicitly test that correct change was done // Twin2 should still exists, therefore it should not be possible to create it again - await expect(twinHandler.connect(assistant).createTwin(twin1)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin1)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TWIN_TOKEN_RANGE ); - await expect(twinHandler.connect(assistant).createTwin(twin3)).to.be.revertedWith( + await expect(twinHandler.connect(assistant).createTwin(twin3)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_TWIN_TOKEN_RANGE ); // Twin2 was removed, therefore it should be possible to be added again @@ -719,21 +751,28 @@ describe("IBosonTwinHandler", function () { .pause([PausableRegion.Offers, PausableRegion.Twins, PausableRegion.Bundles]); // Attempt to Remove a twin, expecting revert - await expect(twinHandler.connect(assistant).removeTwin(twin.id)).to.revertedWith(RevertReasons.REGION_PAUSED); + await expect(twinHandler.connect(assistant).removeTwin(twin.id)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.REGION_PAUSED + ); }); it("Twin does not exist", async function () { let nonExistantTwinId = "999"; // Attempt to Remove a twin, expecting revert - await expect(twinHandler.connect(assistant).removeTwin(nonExistantTwinId)).to.revertedWith( + await expect(twinHandler.connect(assistant).removeTwin(nonExistantTwinId)).to.revertedWithCustomError( + bosonErrors, RevertReasons.NO_SUCH_TWIN ); }); it("Caller is not the seller", async function () { // Attempt to Remove a twin, expecting revert - await expect(twinHandler.connect(rando).removeTwin(twin.id)).to.revertedWith(RevertReasons.NOT_ASSISTANT); + await expect(twinHandler.connect(rando).removeTwin(twin.id)).to.revertedWithCustomError( + bosonErrors, + RevertReasons.NOT_ASSISTANT + ); }); it("Bundle for twin exists", async function () { @@ -765,7 +804,8 @@ describe("IBosonTwinHandler", function () { await bundleHandler.connect(assistant).createBundle(bundle); // Attempt to Remove a twin, expecting revert - await expect(twinHandler.connect(assistant).removeTwin(twin.id)).to.revertedWith( + await expect(twinHandler.connect(assistant).removeTwin(twin.id)).to.revertedWithCustomError( + bosonErrors, RevertReasons.BUNDLE_FOR_TWIN_EXISTS ); }); diff --git a/test/protocol/clients/BosonVoucherTest.js b/test/protocol/clients/BosonVoucherTest.js index adc0a5994..f7cbf86e3 100644 --- a/test/protocol/clients/BosonVoucherTest.js +++ b/test/protocol/clients/BosonVoucherTest.js @@ -59,6 +59,7 @@ describe("IBosonVoucher", function () { let forwarder; let snapshotId; let beaconProxyAddress; + let bosonErrors; before(async function () { accountId.next(true); @@ -89,6 +90,8 @@ describe("IBosonVoucher", function () { forwarderAddress: [await forwarder.getAddress()], })); + bosonErrors = await getContractAt("BosonErrors", await accountHandler.getAddress()); + // make all account the same assistant = admin; assistantDR = adminDR; @@ -266,7 +269,8 @@ describe("IBosonVoucher", function () { context("💔 Revert Reasons", async function () { it("should revert if caller does not have PROTOCOL role", async function () { // Expect revert if random user attempts to issue voucher - await expect(bosonVoucher.connect(rando).issueVoucher(0, buyerWallet)).to.be.revertedWith( + await expect(bosonVoucher.connect(rando).issueVoucher(0, buyerWallet)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.ACCESS_DENIED ); @@ -291,7 +295,8 @@ describe("IBosonVoucher", function () { await bosonVoucher.connect(protocol).reserveRange(offerId, start, length, await assistant.getAddress()); // Expect revert if random user attempts to issue voucher - await expect(bosonVoucher.connect(protocol).issueVoucher(tokenId, buyerWallet)).to.be.revertedWith( + await expect(bosonVoucher.connect(protocol).issueVoucher(tokenId, buyerWallet)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.EXCHANGE_ID_IN_RESERVED_RANGE ); }); @@ -363,7 +368,7 @@ describe("IBosonVoucher", function () { it("caller does not have PROTOCOL role", async function () { await expect( bosonVoucher.connect(rando).reserveRange(offerId, start, length, await assistant.getAddress()) - ).to.be.revertedWith(RevertReasons.ACCESS_DENIED); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("Start id is not greater than zero for the first range", async function () { @@ -373,7 +378,7 @@ describe("IBosonVoucher", function () { // Try to reserve range, it should fail await expect( bosonVoucher.connect(protocol).reserveRange(offerId, start, length, await assistant.getAddress()) - ).to.be.revertedWith(RevertReasons.INVALID_RANGE_START); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RANGE_START); }); it("Range length is zero", async function () { @@ -383,7 +388,7 @@ describe("IBosonVoucher", function () { // Try to reserve range, it should fail await expect( bosonVoucher.connect(protocol).reserveRange(offerId, start, length, await assistant.getAddress()) - ).to.be.revertedWith(RevertReasons.INVALID_RANGE_LENGTH); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RANGE_LENGTH); }); it("Range length is too large, i.e., would cause an overflow", async function () { @@ -394,7 +399,7 @@ describe("IBosonVoucher", function () { // Try to reserve range, it should fail await expect( bosonVoucher.connect(protocol).reserveRange(offerId, start, length, await assistant.getAddress()) - ).to.be.revertedWith(RevertReasons.INVALID_RANGE_LENGTH); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_RANGE_LENGTH); }); it("Offer id is already associated with a range", async function () { @@ -406,14 +411,14 @@ describe("IBosonVoucher", function () { // Try to reserve range for the same offer, it should fail await expect( bosonVoucher.connect(protocol).reserveRange(offerId, start, length, await assistant.getAddress()) - ).to.be.revertedWith(RevertReasons.OFFER_RANGE_ALREADY_RESERVED); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_RANGE_ALREADY_RESERVED); }); it("_to address isn't contract address or contract owner address", async function () { // Try to reserve range for rando address, it should fail await expect( bosonVoucher.connect(protocol).reserveRange(offerId, start, length, await rando.getAddress()) - ).to.be.revertedWith(RevertReasons.INVALID_TO_ADDRESS); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_TO_ADDRESS); }); }); }); @@ -593,7 +598,8 @@ describe("IBosonVoucher", function () { offerId = 15; // Try to premint, it should fail - await expect(bosonVoucher.connect(assistant).preMint(offerId, amount)).to.be.revertedWith( + await expect(bosonVoucher.connect(assistant).preMint(offerId, amount)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.NO_RESERVED_RANGE_FOR_OFFER ); }); @@ -606,7 +612,8 @@ describe("IBosonVoucher", function () { amount = "990"; // length is 1000, already minted 50 // Try to premint, it should fail - await expect(bosonVoucher.connect(assistant).preMint(offerId, amount)).to.be.revertedWith( + await expect(bosonVoucher.connect(assistant).preMint(offerId, amount)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_AMOUNT_TO_MINT ); }); @@ -616,7 +623,8 @@ describe("IBosonVoucher", function () { await setNextBlockTimestamp(Number(BigInt(offerDates.validUntil) + 1n)); // Try to premint, it should fail - await expect(bosonVoucher.connect(assistant).preMint(offerId, amount)).to.be.revertedWith( + await expect(bosonVoucher.connect(assistant).preMint(offerId, amount)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.OFFER_EXPIRED_OR_VOIDED ); }); @@ -625,7 +633,8 @@ describe("IBosonVoucher", function () { await offerHandler.connect(assistant).voidOffer(offerId); // Try to premint, it should fail - await expect(bosonVoucher.connect(assistant).preMint(offerId, amount)).to.be.revertedWith( + await expect(bosonVoucher.connect(assistant).preMint(offerId, amount)).to.be.revertedWithCustomError( + bosonErrors, RevertReasons.OFFER_EXPIRED_OR_VOIDED ); }); @@ -769,9 +778,9 @@ describe("IBosonVoucher", function () { assert.equal(returnedRange.toString(), range.toString(), "Range mismatch"); // Second call should revert since there's nothing to burn - await expect(bosonVoucher.connect(assistant).burnPremintedVouchers(offerId, amount)).to.be.revertedWith( - RevertReasons.AMOUNT_EXCEEDS_RANGE_OR_NOTHING_TO_BURN - ); + await expect( + bosonVoucher.connect(assistant).burnPremintedVouchers(offerId, amount) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.AMOUNT_EXCEEDS_RANGE_OR_NOTHING_TO_BURN); }); context("Test that require non-voided offer", function () { @@ -866,9 +875,9 @@ describe("IBosonVoucher", function () { offerId = 15; // Try to burn, it should fail - await expect(bosonVoucher.connect(assistant).burnPremintedVouchers(offerId, amount)).to.be.revertedWith( - RevertReasons.NO_RESERVED_RANGE_FOR_OFFER - ); + await expect( + bosonVoucher.connect(assistant).burnPremintedVouchers(offerId, amount) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.NO_RESERVED_RANGE_FOR_OFFER); }); it("Offer is still valid", async function () { @@ -881,9 +890,9 @@ describe("IBosonVoucher", function () { await bosonVoucher.connect(assistant).preMint(offerId, 10); // Try to burn, it should fail - await expect(bosonVoucher.connect(assistant).burnPremintedVouchers(offerId, amount)).to.be.revertedWith( - RevertReasons.OFFER_STILL_VALID - ); + await expect( + bosonVoucher.connect(assistant).burnPremintedVouchers(offerId, amount) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_STILL_VALID); }); it("Nothing to burn", async function () { @@ -891,9 +900,9 @@ describe("IBosonVoucher", function () { await bosonVoucher.connect(assistant).burnPremintedVouchers(offerId, amount); // Try to burn, it should fail - await expect(bosonVoucher.connect(assistant).burnPremintedVouchers(offerId, amount)).to.be.revertedWith( - RevertReasons.AMOUNT_EXCEEDS_RANGE_OR_NOTHING_TO_BURN - ); + await expect( + bosonVoucher.connect(assistant).burnPremintedVouchers(offerId, amount) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.AMOUNT_EXCEEDS_RANGE_OR_NOTHING_TO_BURN); }); }); }); @@ -1553,7 +1562,7 @@ describe("IBosonVoucher", function () { bosonVoucher .connect(assistant) [selector](await assistant.getAddress(), await rando.getAddress(), tokenId, ...additionalArgs) - ).to.be.revertedWith(RevertReasons.OFFER_HAS_BEEN_VOIDED); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_BEEN_VOIDED); }); it("Transfer preminted voucher, where offer has expired", async function () { @@ -1565,7 +1574,7 @@ describe("IBosonVoucher", function () { bosonVoucher .connect(assistant) [selector](await assistant.getAddress(), await rando.getAddress(), tokenId, ...additionalArgs) - ).to.be.revertedWith(RevertReasons.OFFER_HAS_EXPIRED); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.OFFER_HAS_EXPIRED); }); it("Transfer preminted voucher, but from is not the voucher owner", async function () { @@ -1744,9 +1753,9 @@ describe("IBosonVoucher", function () { royaltyPercentage = "1500"; //15% // royalty percentage too high, expecting revert - await expect(bosonVoucher.connect(assistant).setRoyaltyPercentage(royaltyPercentage)).to.be.revertedWith( - RevertReasons.ROYALTY_FEE_INVALID - ); + await expect( + bosonVoucher.connect(assistant).setRoyaltyPercentage(royaltyPercentage) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.ROYALTY_FEE_INVALID); }); }); }); @@ -1847,7 +1856,7 @@ describe("IBosonVoucher", function () { // royalty percentage too high, expecting revert await expect( accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.be.revertedWith(RevertReasons.ROYALTY_FEE_INVALID); + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.ROYALTY_FEE_INVALID); }); }); }); @@ -2011,7 +2020,10 @@ describe("IBosonVoucher", function () { it("should revert if caller does not have PROTOCOL role", async function () { // Expect revert if random user attempts to burn voucher - await expect(bosonVoucher.connect(rando).burnVoucher(0)).to.be.revertedWith(RevertReasons.ACCESS_DENIED); + await expect(bosonVoucher.connect(rando).burnVoucher(0)).to.be.revertedWithCustomError( + bosonErrors, + RevertReasons.ACCESS_DENIED + ); // Grant PROTOCOL role to random user address await accessController.grantRole(Role.PROTOCOL, await rando.getAddress()); @@ -2049,9 +2061,9 @@ describe("IBosonVoucher", function () { context("💔 Revert Reasons", async function () { it("should revert if caller does not have PROTOCOL role", async function () { - await expect(bosonVoucher.connect(rando).transferOwnership(await assistant.getAddress())).to.be.revertedWith( - RevertReasons.ACCESS_DENIED - ); + await expect( + bosonVoucher.connect(rando).transferOwnership(await assistant.getAddress()) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("Even the current owner cannot transfer the ownership", async function () { @@ -2059,9 +2071,9 @@ describe("IBosonVoucher", function () { await bosonVoucher.connect(protocol).transferOwnership(await assistant.getAddress()); // owner tries to transfer, it should fail - await expect(bosonVoucher.connect(assistant).transferOwnership(await rando.getAddress())).to.be.revertedWith( - RevertReasons.ACCESS_DENIED - ); + await expect( + bosonVoucher.connect(assistant).transferOwnership(await rando.getAddress()) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.ACCESS_DENIED); }); it("Current owner cannot renounce the ownership", async function () { @@ -2071,7 +2083,10 @@ describe("IBosonVoucher", function () { const ownable = await getContractAt("OwnableUpgradeable", await bosonVoucher.getAddress()); // owner tries to renounce ownership, it should fail - await expect(ownable.connect(assistant).renounceOwnership()).to.be.revertedWith(RevertReasons.ACCESS_DENIED); + await expect(ownable.connect(assistant).renounceOwnership()).to.be.revertedWithCustomError( + bosonErrors, + RevertReasons.ACCESS_DENIED + ); }); it("Transferring ownership to 0 is not allowed", async function () { @@ -2154,9 +2169,9 @@ describe("IBosonVoucher", function () { context("💔 Revert Reasons", async function () { it("_to is the zero address", async function () { - await expect(bosonVoucher.connect(assistant).callExternalContract(ZeroAddress, calldata)).to.be.revertedWith( - RevertReasons.INVALID_ADDRESS - ); + await expect( + bosonVoucher.connect(assistant).callExternalContract(ZeroAddress, calldata) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("Caller is not the contract owner", async function () { @@ -2185,9 +2200,9 @@ describe("IBosonVoucher", function () { // transfer calldata = erc20.interface.encodeFunctionData("transfer", [await assistant.getAddress(), 20]); - await expect(bosonVoucher.connect(assistant).callExternalContract(erc20Address, calldata)).to.be.revertedWith( - RevertReasons.INTERACTION_NOT_ALLOWED - ); + await expect( + bosonVoucher.connect(assistant).callExternalContract(erc20Address, calldata) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INTERACTION_NOT_ALLOWED); // transferFrom calldata = erc20.interface.encodeFunctionData("transferFrom", [ @@ -2195,24 +2210,24 @@ describe("IBosonVoucher", function () { await assistant.getAddress(), 20, ]); - await expect(bosonVoucher.connect(assistant).callExternalContract(erc20Address, calldata)).to.be.revertedWith( - RevertReasons.INTERACTION_NOT_ALLOWED - ); + await expect( + bosonVoucher.connect(assistant).callExternalContract(erc20Address, calldata) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INTERACTION_NOT_ALLOWED); // approve calldata = erc20.interface.encodeFunctionData("approve", [await assistant.getAddress(), 20]); - await expect(bosonVoucher.connect(assistant).callExternalContract(erc20Address, calldata)).to.be.revertedWith( - RevertReasons.INTERACTION_NOT_ALLOWED - ); + await expect( + bosonVoucher.connect(assistant).callExternalContract(erc20Address, calldata) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INTERACTION_NOT_ALLOWED); // DAI const dai = await getContractAt("DAIAliases", ZeroAddress); // push calldata = dai.interface.encodeFunctionData("push", [await assistant.getAddress(), 20]); - await expect(bosonVoucher.connect(assistant).callExternalContract(erc20Address, calldata)).to.be.revertedWith( - RevertReasons.INTERACTION_NOT_ALLOWED - ); + await expect( + bosonVoucher.connect(assistant).callExternalContract(erc20Address, calldata) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INTERACTION_NOT_ALLOWED); // move calldata = dai.interface.encodeFunctionData("move", [ @@ -2220,9 +2235,9 @@ describe("IBosonVoucher", function () { await assistant.getAddress(), 20, ]); - await expect(bosonVoucher.connect(assistant).callExternalContract(erc20Address, calldata)).to.be.revertedWith( - RevertReasons.INTERACTION_NOT_ALLOWED - ); + await expect( + bosonVoucher.connect(assistant).callExternalContract(erc20Address, calldata) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INTERACTION_NOT_ALLOWED); // ERC721 const erc721Address = await erc721.getAddress(); @@ -2232,9 +2247,9 @@ describe("IBosonVoucher", function () { await assistant.getAddress(), 20, ]); - await expect(bosonVoucher.connect(assistant).callExternalContract(erc721Address, calldata)).to.be.revertedWith( - RevertReasons.INTERACTION_NOT_ALLOWED - ); + await expect( + bosonVoucher.connect(assistant).callExternalContract(erc721Address, calldata) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INTERACTION_NOT_ALLOWED); // transferFrom calldata = erc721.interface.encodeFunctionData("safeTransferFrom(address,address,uint256)", [ @@ -2242,21 +2257,21 @@ describe("IBosonVoucher", function () { await assistant.getAddress(), 20, ]); - await expect(bosonVoucher.connect(assistant).callExternalContract(erc721Address, calldata)).to.be.revertedWith( - RevertReasons.INTERACTION_NOT_ALLOWED - ); + await expect( + bosonVoucher.connect(assistant).callExternalContract(erc721Address, calldata) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INTERACTION_NOT_ALLOWED); // approve calldata = erc721.interface.encodeFunctionData("approve", [await assistant.getAddress(), 20]); - await expect(bosonVoucher.connect(assistant).callExternalContract(erc721Address, calldata)).to.be.revertedWith( - RevertReasons.INTERACTION_NOT_ALLOWED - ); + await expect( + bosonVoucher.connect(assistant).callExternalContract(erc721Address, calldata) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INTERACTION_NOT_ALLOWED); // setApprovalForAll calldata = erc721.interface.encodeFunctionData("setApprovalForAll", [await assistant.getAddress(), true]); - await expect(bosonVoucher.connect(assistant).callExternalContract(erc721Address, calldata)).to.be.revertedWith( - RevertReasons.INTERACTION_NOT_ALLOWED - ); + await expect( + bosonVoucher.connect(assistant).callExternalContract(erc721Address, calldata) + ).to.be.revertedWithCustomError(bosonErrors, RevertReasons.INTERACTION_NOT_ALLOWED); }); }); }); @@ -2278,9 +2293,9 @@ describe("IBosonVoucher", function () { it("should revert if operator is zero address", async function () { // Expect revert if random user attempts to set approval - await expect(bosonVoucher.connect(assistant).setApprovalForAllToContract(ZeroAddress, true)).to.revertedWith( - RevertReasons.INVALID_ADDRESS - ); + await expect( + bosonVoucher.connect(assistant).setApprovalForAllToContract(ZeroAddress, true) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); }); }); diff --git a/test/protocol/clients/ClientExternalAddressesTest.js b/test/protocol/clients/ClientExternalAddressesTest.js index 1ed60d0b1..5c33adb7d 100644 --- a/test/protocol/clients/ClientExternalAddressesTest.js +++ b/test/protocol/clients/ClientExternalAddressesTest.js @@ -1,5 +1,5 @@ const { ethers } = require("hardhat"); -const { getSigners, ZeroAddress, getContractFactory } = ethers; +const { getSigners, ZeroAddress, getContractFactory, getContractAt } = ethers; const { gasLimit } = require("../../../environments"); const { deployProtocolClientImpls } = require("../../../scripts/util/deploy-protocol-client-impls.js"); const { deployProtocolClientBeacons } = require("../../../scripts/util/deploy-protocol-client-beacons.js"); @@ -14,6 +14,7 @@ describe("IClientExternalAddresses", function () { let voucherImplementation, protocolAddress; let snapshotId; let protocolDiamondAddress; + let bosonErrors; before(async function () { // Specify contracts needed for this test @@ -25,6 +26,8 @@ describe("IClientExternalAddresses", function () { extraReturnValues: { beacon }, } = await setupTestEnvironment(contracts)); + bosonErrors = await getContractAt("BosonErrors", protocolDiamondAddress); + [deployer] = await getSigners(); // Get snapshot id @@ -62,14 +65,16 @@ describe("IClientExternalAddresses", function () { context("💔 Revert Reasons", async function () { it("caller is not the admin", async function () { // Attempt to set new implementation, expecting revert - await expect(beacon.connect(rando).setImplementation(voucherImplementation)).to.revertedWith( + await expect(beacon.connect(rando).setImplementation(voucherImplementation)).to.revertedWithCustomError( + bosonErrors, RevertReasons.ACCESS_DENIED ); }); it("implementation address is the zero address", async function () { // Attempt to set new implementation, expecting revert - await expect(beacon.connect(deployer).setImplementation(ZeroAddress)).to.revertedWith( + await expect(beacon.connect(deployer).setImplementation(ZeroAddress)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ADDRESS ); }); @@ -100,14 +105,16 @@ describe("IClientExternalAddresses", function () { context("💔 Revert Reasons", async function () { it("caller is not the admin", async function () { // Attempt to set new protocol address, expecting revert - await expect(beacon.connect(rando).setProtocolAddress(protocolAddress)).to.revertedWith( + await expect(beacon.connect(rando).setProtocolAddress(protocolAddress)).to.revertedWithCustomError( + bosonErrors, RevertReasons.ACCESS_DENIED ); }); it("protocol address is the zero address", async function () { // Attempt to set new protocol address, expecting revert - await expect(beacon.connect(deployer).setProtocolAddress(ZeroAddress)).to.revertedWith( + await expect(beacon.connect(deployer).setProtocolAddress(ZeroAddress)).to.revertedWithCustomError( + bosonErrors, RevertReasons.INVALID_ADDRESS ); }); @@ -124,7 +131,7 @@ describe("IClientExternalAddresses", function () { const protocolClientArgs = [ZeroAddress]; await expect( deployProtocolClientBeacons(protocolClientImpls, protocolClientArgs, maxPriorityFeePerGas) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); it("_impl address is the zero address", async function () { @@ -133,9 +140,9 @@ describe("IClientExternalAddresses", function () { // Deploy the ClientBeacon for BosonVoucher const ClientBeacon = await getContractFactory("BosonClientBeacon"); - await expect(ClientBeacon.deploy(...protocolClientArgs, ZeroAddress, { gasLimit })).to.revertedWith( - RevertReasons.INVALID_ADDRESS - ); + await expect( + ClientBeacon.deploy(...protocolClientArgs, ZeroAddress, { gasLimit }) + ).to.revertedWithCustomError(bosonErrors, RevertReasons.INVALID_ADDRESS); }); }); });