diff --git a/contracts/domain/BosonConstants.sol b/contracts/domain/BosonConstants.sol index 423fc6c88..083e75f3b 100644 --- a/contracts/domain/BosonConstants.sol +++ b/contracts/domain/BosonConstants.sol @@ -38,8 +38,8 @@ string constant DIRECT_INITIALIZATION_NOT_ALLOWED = "Direct initializtion is not 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 NOT_ASSISTANT_AND_CLERK = "Not assistant and clerk"; -string constant NOT_ADMIN_ASSISTANT_AND_CLERK = "Not admin, assistant and clerk"; +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"; diff --git a/contracts/domain/BosonTypes.sol b/contracts/domain/BosonTypes.sol index a5c79b26a..b24fb26ee 100644 --- a/contracts/domain/BosonTypes.sol +++ b/contracts/domain/BosonTypes.sol @@ -73,14 +73,14 @@ contract BosonTypes { enum SellerUpdateFields { Admin, Assistant, - Clerk, + Clerk, // Deprecated. AuthToken } enum DisputeResolverUpdateFields { Admin, Assistant, - Clerk + Clerk // Deprecated. } struct AuthToken { @@ -92,7 +92,7 @@ contract BosonTypes { uint256 id; address assistant; address admin; - address clerk; + address clerk; // Deprecated. Kept for backwards compatibility. address payable treasury; bool active; string metadataUri; @@ -109,7 +109,7 @@ contract BosonTypes { uint256 escalationResponsePeriod; address assistant; address admin; - address clerk; + address clerk; // Deprecated. Kept for backwards compatibility. address payable treasury; string metadataUri; bool active; diff --git a/contracts/interfaces/handlers/IBosonAccountHandler.sol b/contracts/interfaces/handlers/IBosonAccountHandler.sol index 3a81f3131..9adb7d019 100644 --- a/contracts/interfaces/handlers/IBosonAccountHandler.sol +++ b/contracts/interfaces/handlers/IBosonAccountHandler.sol @@ -19,7 +19,8 @@ interface IBosonAccountHandler is IBosonAccountEvents { * * Reverts if: * - Caller is not the supplied admin or does not own supplied auth token - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant + * - Supplied clerk is not a zero address * - The sellers region of protocol is paused * - Address values are zero address * - Addresses are not unique to this seller @@ -59,7 +60,8 @@ interface IBosonAccountHandler is IBosonAccountEvents { * Emits a DisputeResolverCreated event if successful. * * Reverts if: - * - Caller is not the supplied admin, assistant and clerk + * - Caller is not the supplied admin and assistant + * - Supplied clerk is not a zero address * - The dispute resolvers region of protocol is paused * - Any address is zero address * - Any address is not unique to this dispute resolver @@ -98,18 +100,19 @@ interface IBosonAccountHandler is IBosonAccountEvents { function createAgent(BosonTypes.Agent memory _agent) external; /** - * @notice Updates treasury address, if changed. Puts admin, assistant, clerk and AuthToken in pending queue, if changed. + * @notice Updates treasury address, if changed. Puts admin, assistant and AuthToken in pending queue, if changed. * Pending updates can be completed by calling the optInToSellerUpdate function. * @dev Active flag passed in by caller will be ignored. The value from storage will be used. * * Emits a SellerUpdateApplied event if the seller has changed the treasury. - * Emits a SellerUpdatePending event if the seller has requested an update for admin, clerk, assistant, or auth token. - * Holder of new auth token and/or owner(s) of new addresses for admin, clerk, assistant must opt-in to the update. + * Emits a SellerUpdatePending event if the seller has requested an update for admin, assistant, or auth token. + * Holder of new auth token and/or owner(s) of new addresses for admin, assistant must opt-in to the update. * * Reverts if: * - The sellers region of protocol is paused * - Address values are zero address * - Addresses are not unique to this seller + * - Supplied clerk is not a zero address * - Caller address is not the admin address of the stored seller with no AuthToken * - Caller is not the owner of the seller's stored AuthToken * - Seller does not exist @@ -135,6 +138,7 @@ interface IBosonAccountHandler is IBosonAccountEvents { * - Caller is not the owner of the pending AuthToken being updated * - No pending update exists for this seller * - AuthTokenType is not unique to this seller + * - Seller tries to update the clerk * * @param _sellerId - seller id * @param _fieldsToUpdate - fields to update, see SellerUpdateFields enum @@ -161,7 +165,7 @@ interface IBosonAccountHandler is IBosonAccountEvents { function updateBuyer(BosonTypes.Buyer memory _buyer) external; /** - * @notice Updates treasury address, escalationResponsePeriod or metadataUri if changed. Puts admin, assistant and clerk in pending queue, if changed. + * @notice Updates treasury address, escalationResponsePeriod or metadataUri if changed. Puts admin and assistant in pending queue, if changed. * Pending updates can be completed by calling the optInToDisputeResolverUpdate function. * * Update doesn't include DisputeResolverFees, allowed seller list or active flag. @@ -172,13 +176,14 @@ interface IBosonAccountHandler is IBosonAccountEvents { * @dev Active flag passed in by caller will be ignored. The value from storage will be used. * * Emits a DisputeResolverUpdated event if successful. - * Emits a DisputeResolverUpdatePending event if the dispute resolver has requested an update for admin, clerk or assistant. - * Owner(s) of new addresses for admin, clerk, assistant must opt-in to the update. + * Emits a DisputeResolverUpdatePending event if the dispute resolver has requested an update for admin or assistant. + * Owner(s) of new addresses for admin, assistant must opt-in to the update. * * Reverts if: * - The dispute resolvers region of protocol is paused * - Caller is not the admin address of the stored dispute resolver * - Any address is not unique to this dispute resolver + * - Supplied clerk is not a zero address * - Dispute resolver does not exist * - EscalationResponsePeriod is invalid * - No field has been updated or requested to be updated @@ -197,6 +202,7 @@ interface IBosonAccountHandler is IBosonAccountEvents { * - Addresses are not unique to this dispute resolver * - Caller address is not pending update for the field being updated * - No pending update exists for this dispute resolver + * - Dispute resolver tries to update the clerk * * @param _disputeResolverId - disputeResolver id * @param _fieldsToUpdate - fields to update, see DisputeResolverUpdateFields enum @@ -317,11 +323,11 @@ interface IBosonAccountHandler is IBosonAccountEvents { ) external view returns (bool exists, BosonTypes.Seller memory seller, BosonTypes.AuthToken memory authToken); /** - * @notice Gets the details about a seller by an address associated with that seller: assistant, admin, or clerk address. + * @notice Gets the details about a seller by an address associated with that seller: assistant, or admin address. * A seller will have either an admin address or an auth token. * If seller's admin uses NFT Auth the seller should call `getSellerByAuthToken` instead. * - * @param _associatedAddress - the address associated with the seller. Must be an assistant, admin, or clerk address. + * @param _associatedAddress - the address associated with the seller. Must be an assistant, or admin address. * @return exists - the seller was found * @return seller - the seller details. See {BosonTypes.Seller} * @return authToken - optional AuthToken struct that specifies an AuthToken type and tokenId that the seller can use to do admin functions @@ -378,9 +384,9 @@ interface IBosonAccountHandler is IBosonAccountEvents { ); /** - * @notice Gets the details about a dispute resolver by an address associated with that dispute resolver: assistant, admin, or clerk address. + * @notice Gets the details about a dispute resolver by an address associated with that dispute resolver: assistant, or admin address. * - * @param _associatedAddress - the address associated with the dispute resolver. Must be an assistant, admin, or clerk address. + * @param _associatedAddress - the address associated with the dispute resolver. Must be an assistant, or admin address. * @return exists - the dispute resolver was found * @return disputeResolver - the dispute resolver details. See {BosonTypes.DisputeResolver} * @return disputeResolverFees - list of fees dispute resolver charges per token type. Zero address is native currency. See {BosonTypes.DisputeResolverFee} diff --git a/contracts/interfaces/handlers/IBosonOrchestrationHandler.sol b/contracts/interfaces/handlers/IBosonOrchestrationHandler.sol index b5ad79e5b..8f429d69a 100644 --- a/contracts/interfaces/handlers/IBosonOrchestrationHandler.sol +++ b/contracts/interfaces/handlers/IBosonOrchestrationHandler.sol @@ -67,7 +67,8 @@ interface IBosonOrchestrationHandler is * - The offers region of protocol is paused * - The orchestration region of protocol is paused * - Caller is not the supplied admin or does not own supplied auth token - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - In seller struct: @@ -132,8 +133,9 @@ interface IBosonOrchestrationHandler is * - The offers region of protocol is paused * - The orchestration region of protocol is paused * - The exchanges region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - Reserved range length is zero @@ -678,7 +680,8 @@ interface IBosonOrchestrationHandler is * - The groups region of protocol is paused * - The orchestration region of protocol is paused * - Caller is not the supplied admin or does not own supplied auth token - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - In seller struct: @@ -749,8 +752,9 @@ interface IBosonOrchestrationHandler is * - The groups region of protocol is paused * - The exchanges region of protocol is paused * - The orchestration region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - Reserved range length is zero @@ -832,7 +836,8 @@ interface IBosonOrchestrationHandler is * - The bundles region of protocol is paused * - The orchestration region of protocol is paused * - Caller is not the supplied admin or does not own supplied auth token - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - In seller struct: @@ -911,8 +916,9 @@ interface IBosonOrchestrationHandler is * - The bundles region of protocol is paused * - The exchanges region of protocol is paused * - The orchestration region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - Reserved range length is zero @@ -1002,7 +1008,8 @@ interface IBosonOrchestrationHandler is * - The bundles region of protocol is paused * - The orchestration region of protocol is paused * - Caller is not the supplied admin or does not own supplied auth token - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - In seller struct: @@ -1086,8 +1093,9 @@ interface IBosonOrchestrationHandler is * - The bundles region of protocol is paused * - The exchanges region of protocol is paused * - The orchestration region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - Reserved range length is zero diff --git a/contracts/protocol/bases/OfferBase.sol b/contracts/protocol/bases/OfferBase.sol index add7d3327..6710bb562 100644 --- a/contracts/protocol/bases/OfferBase.sol +++ b/contracts/protocol/bases/OfferBase.sol @@ -322,9 +322,6 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { // _to must be the contract address or the contract owner require(_to == address(bosonVoucher) || _to == sender, INVALID_TO_ADDRESS); - // Call reserveRange on voucher - bosonVoucher.reserveRange(_offerId, _startId, _length, _to); - // increase exchangeIds pc.nextExchangeId = _startId + _length; @@ -333,6 +330,9 @@ contract OfferBase is ProtocolBase, IBosonOfferEvents { offer.quantityAvailable -= _length; } + // Call reserveRange on voucher + bosonVoucher.reserveRange(_offerId, _startId, _length, _to); + // Notify external observers emit RangeReserved(_offerId, offer.sellerId, _startId, _startId + _length - 1, _to, sender); } diff --git a/contracts/protocol/bases/ProtocolBase.sol b/contracts/protocol/bases/ProtocolBase.sol index 946a7f02e..1690d1a3a 100644 --- a/contracts/protocol/bases/ProtocolBase.sol +++ b/contracts/protocol/bases/ProtocolBase.sol @@ -142,21 +142,6 @@ abstract contract ProtocolBase is PausableBase, ReentrancyGuardBase { exists = (sellerId > 0); } - /** - * @notice Gets a seller id from storage by clerk address - * - * @param _clerk - the clerk address of the seller - * @return exists - whether the seller id exists - * @return sellerId - the seller id - */ - function getSellerIdByClerk(address _clerk) internal view returns (bool exists, uint256 sellerId) { - // Get the seller id - sellerId = protocolLookups().sellerIdByClerk[_clerk]; - - // Determine existence - exists = (sellerId > 0); - } - /** * @notice Gets a seller id from storage by auth token. A seller will have either an admin address or an auth token * @@ -238,23 +223,6 @@ abstract contract ProtocolBase is PausableBase, ReentrancyGuardBase { exists = (disputeResolverId > 0); } - /** - * @notice Gets a dispute resolver id from storage by clerk address - * - * @param _clerk - the clerk address of the dispute resolver - * @return exists - whether the dispute resolver id exists - * @return disputeResolverId - the dispute resolver id - */ - function getDisputeResolverIdByClerk( - address _clerk - ) internal view returns (bool exists, uint256 disputeResolverId) { - // Get the dispute resolver id - disputeResolverId = protocolLookups().disputeResolverIdByClerk[_clerk]; - - // Determine existence - exists = (disputeResolverId > 0); - } - /** * @notice Gets a group id from storage by offer id * diff --git a/contracts/protocol/bases/SellerBase.sol b/contracts/protocol/bases/SellerBase.sol index 72ca2e5d9..b182e7452 100644 --- a/contracts/protocol/bases/SellerBase.sol +++ b/contracts/protocol/bases/SellerBase.sol @@ -21,7 +21,8 @@ contract SellerBase is ProtocolBase, IBosonAccountEvents { * Emits a SellerCreated event if successful. * * Reverts if: - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant + * - Supplied clerk is not a zero address * - The sellers region of protocol is paused * - Address values are zero address * - Addresses are not unique to this seller @@ -45,10 +46,7 @@ contract SellerBase is ProtocolBase, IBosonAccountEvents { require(_seller.active, MUST_BE_ACTIVE); // Check for zero address - require( - _seller.assistant != address(0) && _seller.clerk != address(0) && _seller.treasury != address(0), - INVALID_ADDRESS - ); + require(_seller.assistant != address(0) && _seller.treasury != address(0), INVALID_ADDRESS); // Admin address or AuthToken data must be present. A seller can have one or the other require( @@ -63,8 +61,9 @@ contract SellerBase is ProtocolBase, IBosonAccountEvents { // Get message sender address sender = msgSender(); - // Check that caller is the supplied assistant and clerk - require(_seller.assistant == sender && _seller.clerk == sender, NOT_ASSISTANT_AND_CLERK); + // Check that caller is the supplied assistant + require(_seller.assistant == sender, NOT_ASSISTANT); + require(_seller.clerk == address(0), CLERK_DEPRECATED); // Do caller and uniqueness checks based on auth type if (_authToken.tokenType != AuthTokenType.None) { @@ -87,9 +86,7 @@ contract SellerBase is ProtocolBase, IBosonAccountEvents { // Check that the sender address is unique to one seller id, across all roles require( - lookups.sellerIdByAdmin[sender] == 0 && - lookups.sellerIdByAssistant[sender] == 0 && - lookups.sellerIdByClerk[sender] == 0, + lookups.sellerIdByAdmin[sender] == 0 && lookups.sellerIdByAssistant[sender] == 0, SELLER_ADDRESS_MUST_BE_UNIQUE ); @@ -125,7 +122,6 @@ contract SellerBase is ProtocolBase, IBosonAccountEvents { seller.id = _seller.id; seller.assistant = _seller.assistant; seller.admin = _seller.admin; - seller.clerk = _seller.clerk; seller.treasury = _seller.treasury; seller.active = _seller.active; seller.metadataUri = _seller.metadataUri; @@ -146,7 +142,6 @@ contract SellerBase is ProtocolBase, IBosonAccountEvents { // Map the seller's other addresses to the seller id. It's not necessary to map the treasury address, as it only receives funds _lookups.sellerIdByAssistant[_seller.assistant] = _seller.id; - _lookups.sellerIdByClerk[_seller.clerk] = _seller.id; } /** @@ -210,7 +205,6 @@ contract SellerBase is ProtocolBase, IBosonAccountEvents { exists = sellerPendingUpdate.admin != address(0) || sellerPendingUpdate.assistant != address(0) || - sellerPendingUpdate.clerk != address(0) || authTokenPendingUpdate.tokenType != AuthTokenType.None; } } diff --git a/contracts/protocol/facets/DisputeResolverHandlerFacet.sol b/contracts/protocol/facets/DisputeResolverHandlerFacet.sol index 662e1039f..d8ecb2c87 100644 --- a/contracts/protocol/facets/DisputeResolverHandlerFacet.sol +++ b/contracts/protocol/facets/DisputeResolverHandlerFacet.sol @@ -28,7 +28,8 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { * Emits a DisputeResolverCreated event if successful. * * Reverts if: - * - Caller is not the supplied admin, assistant and clerk + * - Caller is not the supplied admin and assistant + * - Supplied clerk is not a zero address * - The dispute resolvers region of protocol is paused * - Any address is zero address * - Any address is not unique to this dispute resolver @@ -56,7 +57,6 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { require( _disputeResolver.admin != address(0) && _disputeResolver.assistant != address(0) && - _disputeResolver.clerk != address(0) && _disputeResolver.treasury != address(0), INVALID_ADDRESS ); @@ -69,13 +69,9 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { // Get message sender address sender = msgSender(); - // Check that caller is the supplied assistant and clerk - require( - _disputeResolver.admin == sender && - _disputeResolver.assistant == sender && - _disputeResolver.clerk == sender, - NOT_ADMIN_ASSISTANT_AND_CLERK - ); + // 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); } // Get the next account id and increment the counter @@ -84,17 +80,11 @@ 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; - mapping(address => uint256) storage disputeResolverIdByClerk = lookups.disputeResolverIdByClerk; require( disputeResolverIdByAssistant[_disputeResolver.assistant] == 0 && disputeResolverIdByAssistant[_disputeResolver.admin] == 0 && - disputeResolverIdByAssistant[_disputeResolver.clerk] == 0 && disputeResolverIdByAdmin[_disputeResolver.admin] == 0 && - disputeResolverIdByAdmin[_disputeResolver.assistant] == 0 && - disputeResolverIdByAdmin[_disputeResolver.clerk] == 0 && - disputeResolverIdByClerk[_disputeResolver.clerk] == 0 && - disputeResolverIdByClerk[_disputeResolver.assistant] == 0 && - disputeResolverIdByClerk[_disputeResolver.admin] == 0, + disputeResolverIdByAdmin[_disputeResolver.assistant] == 0, DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE ); @@ -159,7 +149,7 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { } /** - * @notice Updates treasury address, escalationResponsePeriod or metadataUri if changed. Puts admin, assistant and clerk in pending queue, if changed. + * @notice Updates treasury address, escalationResponsePeriod or metadataUri if changed. Puts admin and assistant in pending queue, if changed. * Pending updates can be completed by calling the optInToDisputeResolverUpdate function. * * Update doesn't include DisputeResolverFees, allowed seller list or active flag. @@ -170,14 +160,15 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { * @dev Active flag passed in by caller will be ignored. The value from storage will be used. * * Emits a DisputeResolverUpdated event if successful. - * Emits a DisputeResolverUpdatePending event if the dispute resolver has requested an update for admin, clerk or assistant. - * Owner(s) of new addresses for admin, clerk, assistant must opt-in to the update. + * Emits a DisputeResolverUpdatePending event if the dispute resolver has requested an update for admin or assistant. + * Owner(s) of new addresses for admin, assistant must opt-in to the update. * * Reverts if: * - The dispute resolvers region of protocol is paused * - Caller is not the admin address of the stored dispute resolver * - Any address is zero address * - Any address is not unique to this dispute resolver + * - Supplied clerk is not a zero address * - Dispute resolver does not exist * - EscalationResponsePeriod is invalid * - No field has been updated or requested to be updated @@ -194,10 +185,10 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { require( _disputeResolver.admin != address(0) && _disputeResolver.assistant != address(0) && - _disputeResolver.clerk != address(0) && _disputeResolver.treasury != address(0), INVALID_ADDRESS ); + require(_disputeResolver.clerk == address(0), CLERK_DEPRECATED); bool exists; DisputeResolver storage disputeResolver; @@ -238,14 +229,6 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { needsApproval = true; } - if (_disputeResolver.clerk != disputeResolver.clerk) { - preUpdateDisputeResolverCheck(_disputeResolver.id, _disputeResolver.clerk, lookups); - - // If clerk address exists, clerk address owner must approve the update to prevent front-running - disputeResolverPendingUpdate.clerk = _disputeResolver.clerk; - needsApproval = true; - } - bool updateApplied; if (_disputeResolver.treasury != disputeResolver.treasury) { @@ -304,6 +287,7 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { * - Addresses are not unique to this dispute resolver * - Caller address is not pending update for the field being updated * - No pending update exists for this dispute resolver + * - Dispute resolver tries to update the clerk * * @param _disputeResolverId - disputeResolver id * @param _fieldsToUpdate - fields to update, see DisputeResolverUpdateFields enum @@ -371,25 +355,8 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { delete disputeResolverPendingUpdate.assistant; updateApplied = true; - } else if (role == DisputeResolverUpdateFields.Clerk && disputeResolverPendingUpdate.clerk != address(0)) { - // Aprove clerk update - require(disputeResolverPendingUpdate.clerk == sender, UNAUTHORIZED_CALLER_UPDATE); - - preUpdateDisputeResolverCheck(_disputeResolverId, sender, lookups); - - // Delete old disputeResolver id by clerk mapping - delete lookups.disputeResolverIdByClerk[disputeResolver.clerk]; - - // Update clerk - disputeResolver.clerk = sender; - - // Store new disputeResolver id by clerk mapping - lookups.disputeResolverIdByClerk[sender] = _disputeResolverId; - - // Delete pending update clerk - delete disputeResolverPendingUpdate.clerk; - - updateApplied = true; + } else if (role == DisputeResolverUpdateFields.Clerk) { + revert(CLERK_DEPRECATED); } } @@ -686,9 +653,9 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { } /** - * @notice Gets the details about a dispute resolver by an address associated with that dispute resolver: assistant, admin, or clerk address. + * @notice Gets the details about a dispute resolver by an address associated with that dispute resolver: assistant, or admin address. * - * @param _associatedAddress - the address associated with the dispute resolver. Must be an assistant, admin, or clerk address. + * @param _associatedAddress - the address associated with the dispute resolver. Must be an assistant or admin address. * @return exists - the dispute resolver was found * @return disputeResolver - the dispute resolver details. See {BosonTypes.DisputeResolver} * @return disputeResolverFees - list of fees dispute resolver charges per token type. Zero address is native currency. See {BosonTypes.DisputeResolverFee} @@ -719,11 +686,6 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { if (exists) { return getDisputeResolver(disputeResolverId); } - - (exists, disputeResolverId) = getDisputeResolverIdByClerk(_associatedAddress); - if (exists) { - return getDisputeResolver(disputeResolverId); - } } /** @@ -778,7 +740,6 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { disputeResolver.escalationResponsePeriod = _disputeResolver.escalationResponsePeriod; disputeResolver.assistant = _disputeResolver.assistant; disputeResolver.admin = _disputeResolver.admin; - disputeResolver.clerk = _disputeResolver.clerk; disputeResolver.treasury = _disputeResolver.treasury; disputeResolver.metadataUri = _disputeResolver.metadataUri; disputeResolver.active = _disputeResolver.active; @@ -786,7 +747,6 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { // Map the dispute resolver's addresses to the dispute resolver id. lookups.disputeResolverIdByAssistant[_disputeResolver.assistant] = _disputeResolver.id; lookups.disputeResolverIdByAdmin[_disputeResolver.admin] = _disputeResolver.id; - lookups.disputeResolverIdByClerk[_disputeResolver.clerk] = _disputeResolver.id; } /** @@ -827,7 +787,7 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { * @notice Pre update dispute resolver checks * * Reverts if: - * - Address has already been used by another dispute resolver as assistant, admin, or clerk + * - Address has already been used by another dispute resolver as assistant or admin * * @param _disputeResolverId - the id of the disputeResolver to check * @param _role - the address to check @@ -840,13 +800,10 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { ) internal view { // Check that the role is unique to one dispute resolver id across all roles -- not used or is used by this dispute resolver id. uint256 check1 = _lookups.disputeResolverIdByAssistant[_role]; - uint256 check2 = _lookups.disputeResolverIdByClerk[_role]; - uint256 check3 = _lookups.disputeResolverIdByAdmin[_role]; + uint256 check2 = _lookups.disputeResolverIdByAdmin[_role]; require( - (check1 == 0 || check1 == _disputeResolverId) && - (check2 == 0 || check2 == _disputeResolverId) && - (check3 == 0 || check3 == _disputeResolverId), + (check1 == 0 || check1 == _disputeResolverId) && (check2 == 0 || check2 == _disputeResolverId), DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE ); } @@ -870,7 +827,6 @@ contract DisputeResolverHandlerFacet is IBosonAccountEvents, ProtocolBase { // Determine existence exists = disputeResolverPendingUpdate.admin != address(0) || - disputeResolverPendingUpdate.assistant != address(0) || - disputeResolverPendingUpdate.clerk != address(0); + disputeResolverPendingUpdate.assistant != address(0); } } diff --git a/contracts/protocol/facets/FundsHandlerFacet.sol b/contracts/protocol/facets/FundsHandlerFacet.sol index 6bf84e23a..58f613321 100644 --- a/contracts/protocol/facets/FundsHandlerFacet.sol +++ b/contracts/protocol/facets/FundsHandlerFacet.sol @@ -103,10 +103,10 @@ contract FundsHandlerFacet is IBosonFundsHandler, ProtocolBase { // Caller is a buyer destinationAddress = sender; } else { - // Check if the caller is a clerk - (exists, callerId) = getSellerIdByClerk(sender); + // Check if the caller is an assistant + (exists, callerId) = getSellerIdByAssistant(sender); if (exists && callerId == _entityId) { - // Caller is a clerk. In this case funds are transferred to the treasury address + // Caller is an assistant. In this case funds are transferred to the treasury address (, Seller storage seller, ) = fetchSeller(callerId); destinationAddress = seller.treasury; } else { @@ -115,7 +115,7 @@ contract FundsHandlerFacet is IBosonFundsHandler, ProtocolBase { // Caller is an agent destinationAddress = sender; } else { - // In this branch, caller is neither buyer, clerk or agent or does not match the _entityId + // In this branch, caller is neither buyer, assistant or agent or does not match the _entityId revert(NOT_AUTHORIZED); } } diff --git a/contracts/protocol/facets/OrchestrationHandlerFacet1.sol b/contracts/protocol/facets/OrchestrationHandlerFacet1.sol index b6640fdea..3881a9be1 100644 --- a/contracts/protocol/facets/OrchestrationHandlerFacet1.sol +++ b/contracts/protocol/facets/OrchestrationHandlerFacet1.sol @@ -43,8 +43,9 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou * - The sellers region of protocol is paused * - The offers region of protocol is paused * - The orchestration region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - In seller struct: @@ -112,8 +113,9 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou * - The offers region of protocol is paused * - The exchanges region of protocol is paused * - The orchestration region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - Reserved range length is zero @@ -725,8 +727,9 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou * - The offers region of protocol is paused * - The groups region of protocol is paused * - The orchestration region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - In seller struct: @@ -802,8 +805,9 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou * - The groups region of protocol is paused * - The exchanges region of protocol is paused * - The orchestration region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - Reserved range length is zero @@ -897,8 +901,9 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou * - The twins region of protocol is paused * - The bundles region of protocol is paused * - The orchestration region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - In seller struct: @@ -982,8 +987,9 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou * - The bundles region of protocol is paused * - The exchanges region of protocol is paused * - The orchestration region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - Reserved range length is zero @@ -1085,8 +1091,9 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou * - The twins region of protocol is paused * - The bundles region of protocol is paused * - The orchestration region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - In seller struct: @@ -1183,8 +1190,9 @@ contract OrchestrationHandlerFacet1 is PausableBase, SellerBase, OfferBase, Grou * - The bundles region of protocol is paused * - The exchanges region of protocol is paused * - The orchestration region of protocol is paused - * - Caller is not the supplied assistant and clerk + * - Caller is not the supplied assistant * - Caller is not the supplied admin or does not own supplied auth token + * - Supplied clerk is not a zero address * - Admin address is zero address and AuthTokenType == None * - AuthTokenType is not unique to this seller * - Reserved range length is zero diff --git a/contracts/protocol/facets/SellerHandlerFacet.sol b/contracts/protocol/facets/SellerHandlerFacet.sol index 5b8616c61..bcc26a059 100644 --- a/contracts/protocol/facets/SellerHandlerFacet.sol +++ b/contracts/protocol/facets/SellerHandlerFacet.sol @@ -28,7 +28,8 @@ contract SellerHandlerFacet is SellerBase { * * Reverts if: * - Caller is not the supplied admin or does not own supplied auth token - * - Caller is not the supplied assistant and clerk revert reason + * - Caller is not the supplied assistant + * - Supplied clerk is not a zero address * - The sellers region of protocol is paused * - Address values are zero address * - Addresses are not unique to this seller @@ -51,18 +52,19 @@ contract SellerHandlerFacet is SellerBase { } /** - * @notice Updates treasury address, if changed. Puts admin, assistant, clerk and AuthToken in pending queue, if changed. + * @notice Updates treasury address, if changed. Puts admin, assistant and AuthToken in pending queue, if changed. * Pending updates can be completed by calling the optInToSellerUpdate function. * @dev Active flag passed in by caller will be ignored. The value from storage will be used. * * Emits a SellerUpdateApplied event if the seller has changed the treasury. - * Emits a SellerUpdatePending event if the seller has requested an update for admin, clerk, assistant, or auth token. - * Holder of new auth token and/or owner(s) of new addresses for admin, clerk, assistant must opt-in to the update. + * Emits a SellerUpdatePending event if the seller has requested an update for admin, assistant, or auth token. + * Holder of new auth token and/or owner(s) of new addresses for admin, assistant must opt-in to the update. * * Reverts if: * - The sellers region of protocol is paused * - Address values are zero address * - Addresses are not unique to this seller + * - Supplied clerk is not a zero address * - Caller address is not the admin address of the stored seller with no AuthToken * - Caller is not the owner of the seller's stored AuthToken * - Seller does not exist @@ -88,6 +90,7 @@ contract SellerHandlerFacet is SellerBase { (_seller.admin != address(0) && _authToken.tokenType == AuthTokenType.None), ADMIN_OR_AUTH_TOKEN ); + require(_seller.clerk == address(0), CLERK_DEPRECATED); require(_authToken.tokenType != AuthTokenType.Custom, INVALID_AUTH_TOKEN_TYPE); @@ -145,14 +148,6 @@ contract SellerHandlerFacet is SellerBase { needsApproval = true; } - if (_seller.clerk != seller.clerk) { - preUpdateSellerCheck(_seller.id, _seller.clerk, lookups); - require(_seller.clerk != address(0), INVALID_ADDRESS); - // Clerk address owner must approve the update to prevent front-running - sellerPendingUpdate.clerk = _seller.clerk; - needsApproval = true; - } - bool updateApplied; if (_seller.treasury != seller.treasury) { @@ -203,6 +198,7 @@ contract SellerHandlerFacet is SellerBase { * - Caller is not the owner of the pending AuthToken being updated * - No pending update exists for this seller * - AuthTokenType is not unique to this seller + * - Seller tries to update the clerk * * @param _sellerId - seller id * @param _fieldsToUpdate - fields to update, see SellerUpdateFields enum @@ -282,25 +278,6 @@ contract SellerHandlerFacet is SellerBase { // Delete pending update assistant delete sellerPendingUpdate.assistant; - updateApplied = true; - } else if (role == SellerUpdateFields.Clerk && sellerPendingUpdate.clerk != address(0)) { - // Aprove clerk update - require(sellerPendingUpdate.clerk == sender, UNAUTHORIZED_CALLER_UPDATE); - - preUpdateSellerCheck(_sellerId, sender, lookups); - - // Delete old seller id by clerk mapping - delete lookups.sellerIdByClerk[seller.clerk]; - - // Update clerk - seller.clerk = sender; - - // Store new seller id by clerk mapping - lookups.sellerIdByClerk[sender] = _sellerId; - - // Delete pending update clerk - delete sellerPendingUpdate.clerk; - updateApplied = true; } else if (role == SellerUpdateFields.AuthToken && authTokenPendingUpdate.tokenType != AuthTokenType.None) { // Approve auth token update @@ -335,6 +312,8 @@ contract SellerHandlerFacet is SellerBase { delete authTokenPendingUpdate.tokenId; updateApplied = true; + } else if (role == SellerUpdateFields.Clerk) { + revert(CLERK_DEPRECATED); } } @@ -363,15 +342,15 @@ contract SellerHandlerFacet is SellerBase { function getSeller( uint256 _sellerId ) external view returns (bool exists, Seller memory seller, AuthToken memory authToken) { - return fetchSeller(_sellerId); + return fetchSellerWithoutClerk(_sellerId); } /** - * @notice Gets the details about a seller by an address associated with that seller: assistant, admin, or clerk address. + * @notice Gets the details about a seller by an address associated with that seller: assistant or admin address. * A seller will have either an admin address or an auth token. * If seller's admin uses NFT Auth the seller should call `getSellerByAuthToken` instead. * - * @param _associatedAddress - the address associated with the seller. Must be an assistant, admin, or clerk address. + * @param _associatedAddress - the address associated with the seller. Must be an assistant or admin address. * @return exists - the seller was found * @return seller - the seller details. See {BosonTypes.Seller} * @return authToken - optional AuthToken struct that specifies an AuthToken type and tokenId that the seller can use to do admin functions @@ -384,17 +363,12 @@ contract SellerHandlerFacet is SellerBase { (exists, sellerId) = getSellerIdByAssistant(_associatedAddress); if (exists) { - return fetchSeller(sellerId); + return fetchSellerWithoutClerk(sellerId); } (exists, sellerId) = getSellerIdByAdmin(_associatedAddress); if (exists) { - return fetchSeller(sellerId); - } - - (exists, sellerId) = getSellerIdByClerk(_associatedAddress); - if (exists) { - return fetchSeller(sellerId); + return fetchSellerWithoutClerk(sellerId); } } @@ -425,7 +399,7 @@ contract SellerHandlerFacet is SellerBase { * @notice Pre update Seller checks * * Reverts if: - * - Address has already been used by another seller as assistant, admin, or clerk + * - Address has already been used by another seller as assistant or admin * * @param _sellerId - the id of the seller to check * @param _role - the address to check @@ -439,15 +413,27 @@ contract SellerHandlerFacet is SellerBase { // Check that the role is unique to one seller id across all roles -- not used or is used by this seller id. if (_role != address(0)) { uint256 check1 = _lookups.sellerIdByAssistant[_role]; - uint256 check2 = _lookups.sellerIdByClerk[_role]; - uint256 check3 = _lookups.sellerIdByAdmin[_role]; + uint256 check2 = _lookups.sellerIdByAdmin[_role]; require( - (check1 == 0 || check1 == _sellerId) && - (check2 == 0 || check2 == _sellerId) && - (check3 == 0 || check3 == _sellerId), + (check1 == 0 || check1 == _sellerId) && (check2 == 0 || check2 == _sellerId), SELLER_ADDRESS_MUST_BE_UNIQUE ); } } + + /** + * @notice Fetches a given seller from storage by id and overrides the clerk address with 0x0. + * + * @param _sellerId - the id of the seller + * @return exists - whether the seller exists + * @return seller - the seller details. See {BosonTypes.Seller} + * @return authToken - optional AuthToken struct that specifies an AuthToken type and tokenId that the user can use to do admin functions + */ + function fetchSellerWithoutClerk( + uint256 _sellerId + ) internal view returns (bool exists, Seller memory seller, AuthToken memory authToken) { + (exists, seller, authToken) = fetchSeller(_sellerId); + seller.clerk = address(0); + } } diff --git a/contracts/protocol/libs/ProtocolLib.sol b/contracts/protocol/libs/ProtocolLib.sol index d97985de7..47a0b60fc 100644 --- a/contracts/protocol/libs/ProtocolLib.sol +++ b/contracts/protocol/libs/ProtocolLib.sol @@ -133,6 +133,7 @@ library ProtocolLib { // seller admin address => sellerId mapping(address => uint256) sellerIdByAdmin; // seller clerk address => sellerId + // @deprecated sellerIdByClerk is no longer used. Keeping it for backwards compatibility. mapping(address => uint256) sellerIdByClerk; // buyer wallet address => buyerId mapping(address => uint256) buyerIdByWallet; @@ -141,6 +142,7 @@ library ProtocolLib { // dispute resolver admin address => disputeResolverId mapping(address => uint256) disputeResolverIdByAdmin; // dispute resolver clerk address => disputeResolverId + // @deprecated disputeResolverIdByClerk is no longer used. Keeping it for backwards compatibility. mapping(address => uint256) disputeResolverIdByClerk; // dispute resolver id to fee token address => index of the token address mapping(uint256 => mapping(address => uint256)) disputeResolverFeeTokenIndex; diff --git a/docs/images/Boson_Protocol_V2_-_Domain_Model.png b/docs/images/Boson_Protocol_V2_-_Domain_Model.png index 63221a2e5..47261ead5 100644 Binary files a/docs/images/Boson_Protocol_V2_-_Domain_Model.png and b/docs/images/Boson_Protocol_V2_-_Domain_Model.png differ diff --git a/docs/tasks.md b/docs/tasks.md index 266c5b837..543afe372 100644 --- a/docs/tasks.md +++ b/docs/tasks.md @@ -168,7 +168,7 @@ Script will create a dispute resolver "escalationResponsePeriod": string, "assistant": string, "admin": string, - "clerk": string, + "clerk": string, // ignored, zero address is used instead "treasury": string, "metadataUri": string, "active": boolean @@ -189,8 +189,8 @@ Script will create a dispute resolver Note about the field `privateKey` in JSON file: - `privateKey` represents the hex encoded private key that will create a dispute resolver. If it is not specified, the protocol admin account will be used (specified in `.env`). -- If all `assistant`, `admin` and `clerk` match the address, corresponding to `privateKey`, dispute resolver is simply created. -- If any of `assistant`, `admin` or `clerk` differs from the address, corresponding to `privateKey`, dispute resolver is created in two steps. Firstly, a dispute resolver with `assistant`, `admin` and `clerk` set to address, corresponding to `privateKey` is created and then in the second step dispute resolver is updated with addresses from JSON file. +- If both `assistant` and `admin` match the address, corresponding to `privateKey`, a dispute resolver is simply created. +- If any of `assistant` or `admin` differs from the address, corresponding to `privateKey`, a dispute resolver is created in two steps. Firstly, a dispute resolver with `assistant` and `admin` set to address, corresponding to `privateKey` is created and then in the second step dispute resolver is updated with addresses from JSON file. Example: diff --git a/package-lock.json b/package-lock.json index d745191d8..5ba9b5280 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "eslint-config-prettier": "^8.6.0", "eslint-plugin-no-only-tests": "^3.1.0", "ethereum-input-data-decoder": "^0.4.2", - "glob": "^10.2.6", + "glob": "^10.2.7", "hardhat": "^2.14.1", "hardhat-contract-sizer": "^2.7.0", "hardhat-preprocessor": "^0.1.5", @@ -37,7 +37,7 @@ "prettier-plugin-solidity": "^1.0.0-beta.19", "simple-statistics": "^7.8.2", "solhint": "^3.3.8", - "truffle": "^5.9.3", + "truffle": "^5.9.4", "web3": "^1.8.1" } }, @@ -2555,9 +2555,9 @@ } }, "node_modules/@truffle/abi-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-1.0.0.tgz", - "integrity": "sha512-h1wGFB28YfByAWm/uBeMCwqDlGsrcMYTumLC/sB/qYhHisi1LK6tV47FEF7zKyf6Al2CtsO28v02+wfLXbUVRg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-1.0.1.tgz", + "integrity": "sha512-ZQUY3XUxEPdqxNaoXsOqF0spTtb6f5RNlnN4MUrVsJ64sOh0FJsY7rxZiUI3khfePmNh4i2qcJrQlKT36YcWUA==", "dev": true, "dependencies": { "change-case": "3.0.2", @@ -2572,9 +2572,9 @@ "dev": true }, "node_modules/@truffle/code-utils": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@truffle/code-utils/-/code-utils-3.0.2.tgz", - "integrity": "sha512-Q4FyYIX9G4GyMa8RJDk19kvgiyGZ1CGEx2RmVcXoCDZqEyiHLzqjvCRp+/fuBz2fv7szO6d+60LO1gLCGS1drQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@truffle/code-utils/-/code-utils-3.0.3.tgz", + "integrity": "sha512-VMQMXvt/nXxWvHo5K1t697se1NU7VNh3zmiFw41qaSE1DjFZ2FMsZuW1ZoLhO4NKc14uB8k8pX3NN7XoF3uP4w==", "dev": true, "dependencies": { "cbor": "^5.2.0" @@ -2612,13 +2612,13 @@ } }, "node_modules/@truffle/codec": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.15.1.tgz", - "integrity": "sha512-OBANcmefxEXLApWl/uU1SOHQJixO8pDaRTybP0YMvxPhgyj7G7+wC+fUvnZdmrTJD2WJFLuoYvZbxILmycEvPg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.15.2.tgz", + "integrity": "sha512-rLLy1RmDq3stE1Bd6cnPO9kGpoB5QE4caY665ghmAURqlqD0ik1Bhbfi4MIRwM7YVx2sYw485qsxfPzlewnT4g==", "dev": true, "dependencies": { - "@truffle/abi-utils": "^1.0.0", - "@truffle/compile-common": "^0.9.5", + "@truffle/abi-utils": "^1.0.1", + "@truffle/compile-common": "^0.9.6", "big.js": "^6.0.3", "bn.js": "^5.1.3", "cbor": "^5.2.0", @@ -2694,25 +2694,25 @@ "dev": true }, "node_modules/@truffle/compile-common": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.9.5.tgz", - "integrity": "sha512-qOIT7nYzQsrnpjk8LurKE6EYYvvJIk3rCHfn+xed88aG6F1l4WYtkUKl+Dcwgxgv3LH0khcQOpjqkXK5kUIJ8A==", + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.9.6.tgz", + "integrity": "sha512-TCcmr1E0GqMZJ2tOaCRNEllxTBJ/g7TuD6jDJpw5Gt9Bw0YO3Cmp6yPQRynRSO4xMJbHUgiEsSfRgIhswut5UA==", "dev": true, "dependencies": { - "@truffle/error": "^0.2.0", + "@truffle/error": "^0.2.1", "colors": "1.4.0" } }, "node_modules/@truffle/config": { - "version": "1.3.56", - "resolved": "https://registry.npmjs.org/@truffle/config/-/config-1.3.56.tgz", - "integrity": "sha512-2wg6zfaUlP3iZP9jHugx3WsyJ2dbIB+nEBULPK5YVbSkqBfXrzW0b9RJYQvyuk/AyFrp/7ycD4r5LnFLq1IHZA==", + "version": "1.3.57", + "resolved": "https://registry.npmjs.org/@truffle/config/-/config-1.3.57.tgz", + "integrity": "sha512-Cfude7ZMT2pykvMoHZ/47MvlVoZDQLs+Y85ChRw/1RKWsHrzz1BOyjDmnPLnSTOc056OuNOcgID1IdUMorVOIQ==", "dev": true, "optional": true, "dependencies": { - "@truffle/error": "^0.2.0", - "@truffle/events": "^0.1.23", - "@truffle/provider": "^0.3.9", + "@truffle/error": "^0.2.1", + "@truffle/events": "^0.1.24", + "@truffle/provider": "^0.3.10", "conf": "^10.1.2", "debug": "^4.3.1", "find-up": "^2.1.0", @@ -2884,14 +2884,14 @@ "dev": true }, "node_modules/@truffle/dashboard-message-bus-client": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/@truffle/dashboard-message-bus-client/-/dashboard-message-bus-client-0.1.10.tgz", - "integrity": "sha512-r9GpdR96T8xzk2Z3Qq5lowixT6hQwDZ9F3D3oNjOv2AOwBrC7dGkt1Ra1FQRsABn4K7LUVvnjjn6rALlsatAdw==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@truffle/dashboard-message-bus-client/-/dashboard-message-bus-client-0.1.11.tgz", + "integrity": "sha512-ABoKtaogh5KjOw0UM5/6wYuhg4T5cMPVSSNF1rv4j3s2XGzExx3vUObvXqNO6I8gZ8xuvzClw4RmcEk8JkM8yA==", "dev": true, "optional": true, "dependencies": { - "@truffle/dashboard-message-bus-common": "^0.1.5", - "@truffle/promise-tracker": "^0.1.5", + "@truffle/dashboard-message-bus-common": "^0.1.6", + "@truffle/promise-tracker": "^0.1.6", "axios": "1.2.4", "debug": "^4.3.1", "delay": "^5.0.0", @@ -2902,24 +2902,24 @@ } }, "node_modules/@truffle/dashboard-message-bus-common": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@truffle/dashboard-message-bus-common/-/dashboard-message-bus-common-0.1.5.tgz", - "integrity": "sha512-F4RfXi7ymNA3HFOlaujRJxAb3I8ciErCRQq+MZVaqjSPF9LSw23IizZsGpLaY43K2bGoBSxyNQRZWxsUEBujPQ==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@truffle/dashboard-message-bus-common/-/dashboard-message-bus-common-0.1.6.tgz", + "integrity": "sha512-93HNXILKeKgmW1YaWPdsQ55MJ0MaLzOA8kRXPnM5jF2H3KRlRxOeEg77R4YWtGH+cVZP4VYGXdpvUap/lOAnvw==", "dev": true, "optional": true }, "node_modules/@truffle/db": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/@truffle/db/-/db-2.0.27.tgz", - "integrity": "sha512-dpeiEm1tqujnLtyGNn0q3trm8nQ5XB1dqNOBXKl60c//dYTKjUdpzqhSAjGHCNRbTppsDKUVoJKsnABANVjJag==", + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/@truffle/db/-/db-2.0.28.tgz", + "integrity": "sha512-R9FfBeVxd/SEIdw6IrMwg2vLMNXuiHMJ5XwW7ivCSyNMYXesJMA85fWYPe9bWyJ8eufLOAWlX8xr55vua4DwZQ==", "dev": true, "optional": true, "dependencies": { "@graphql-tools/delegate": "^8.4.3", "@graphql-tools/schema": "^8.3.1", - "@truffle/abi-utils": "^1.0.0", - "@truffle/code-utils": "^3.0.2", - "@truffle/config": "^1.3.56", + "@truffle/abi-utils": "^1.0.1", + "@truffle/code-utils": "^3.0.3", + "@truffle/config": "^1.3.57", "abstract-leveldown": "^7.2.0", "apollo-server": "^3.11.0", "debug": "^4.3.1", @@ -2937,12 +2937,12 @@ } }, "node_modules/@truffle/db-loader": { - "version": "0.2.27", - "resolved": "https://registry.npmjs.org/@truffle/db-loader/-/db-loader-0.2.27.tgz", - "integrity": "sha512-hKWpiLGZWZNbe9SsOD4olRzCzG972BZkRv157wbqnOX2chHzLqzWgmHzjM7dT28xHTummXYYfG65VXAp1/J8IA==", + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/@truffle/db-loader/-/db-loader-0.2.28.tgz", + "integrity": "sha512-oVXQXtYhM3Mu/pnfLR5KoqqEdw6GO6FDAFM7zZm647mIAtXCqv+EYSNt3efyqsFgQZwv3UZY6KP8TMxnjeWWGA==", "dev": true, "optionalDependencies": { - "@truffle/db": "^2.0.27" + "@truffle/db": "^2.0.28" } }, "node_modules/@truffle/db/node_modules/fs-extra": { @@ -2999,15 +2999,15 @@ } }, "node_modules/@truffle/debugger": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/@truffle/debugger/-/debugger-11.1.3.tgz", - "integrity": "sha512-KvZgrfzcLAFDmcsLusBndTzD35d/z7yhcREaqJy/mzROYGQoRix6VpG+LWJ7/CsiGb6DEwDPsvOOaYDEftK4hw==", + "version": "11.1.4", + "resolved": "https://registry.npmjs.org/@truffle/debugger/-/debugger-11.1.4.tgz", + "integrity": "sha512-dWpf89fHZYaW/18x1ZfQhZozg3hZqxz7Czd6vIWVQc3OiV59xpA0+YLm+aumrebj6vmjqzGWu+iHfCaLiYhwQA==", "dev": true, "dependencies": { "@ensdomains/ensjs": "^2.1.0", - "@truffle/abi-utils": "^1.0.0", - "@truffle/codec": "^0.15.1", - "@truffle/source-map-utils": "^1.3.112", + "@truffle/abi-utils": "^1.0.1", + "@truffle/codec": "^0.15.2", + "@truffle/source-map-utils": "^1.3.113", "bn.js": "^5.1.3", "debug": "^4.3.1", "json-pointer": "^0.6.1", @@ -3055,29 +3055,29 @@ "dev": true }, "node_modules/@truffle/error": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.2.0.tgz", - "integrity": "sha512-Fe0/z4WWb7IP2gBnv3l6zqP87Y0kSMs7oiSLakKJq17q3GUunrHSdioKuNspdggxkXIBhEQLhi8C+LJdwmHKWQ==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.2.1.tgz", + "integrity": "sha512-5Qy+z9dg9hP37WNdLnXH4b9MzemWrjTufRq7/DTKqimjyxCP/1zlL8gQEMdiSx1BBtAZz0xypkID/jb7AF/Osg==", "dev": true }, "node_modules/@truffle/events": { - "version": "0.1.23", - "resolved": "https://registry.npmjs.org/@truffle/events/-/events-0.1.23.tgz", - "integrity": "sha512-OIcOZXDCJPz9zzK4uTj0HxCqASNKVcs6g3Z9fT6sehGZRD4ubGHpQZoMchLBwXcggoDRApq2svTdghai624pLg==", + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/@truffle/events/-/events-0.1.24.tgz", + "integrity": "sha512-rS+jKDjmdM0g+14H/H8MzhohaTKsSS6plNNzO95MIcUs0Ytinu1DXfSkUovDpgv5h2NcRoU0BMTKCR21Y3JiNw==", "dev": true, "optional": true, "dependencies": { - "@truffle/dashboard-message-bus-client": "^0.1.10", - "@truffle/spinners": "^0.2.3", + "@truffle/dashboard-message-bus-client": "^0.1.11", + "@truffle/spinners": "^0.2.4", "debug": "^4.3.1", "emittery": "^0.4.1", "web3-utils": "1.10.0" } }, "node_modules/@truffle/interface-adapter": { - "version": "0.5.33", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.33.tgz", - "integrity": "sha512-vbVcH2I8hX+wM0Xj9uAjpgxMHqfT+y6m26zSkOVvZ2wo9Ez1slaOJkK1/TZK+7nJitGZSXeJeB4purMDuADvGA==", + "version": "0.5.34", + "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.34.tgz", + "integrity": "sha512-gPxabfMi2TueE4VxnNuyeudOfvGJQ1ofVC02PFw14cnRQhzH327JikjjQbZ1bT6S7kWl9H6P3hQPFeYFMHdm1g==", "dev": true, "dependencies": { "bn.js": "^5.1.3", @@ -3144,33 +3144,33 @@ "dev": true }, "node_modules/@truffle/promise-tracker": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@truffle/promise-tracker/-/promise-tracker-0.1.5.tgz", - "integrity": "sha512-wZx8eeu/6rcwwkmRF0Y832/NSQR9A9u6pyhTozv+j77jklnd/KZvu2JlACaAjP30eL5SOtSrSOzAMcSh/trJjg==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@truffle/promise-tracker/-/promise-tracker-0.1.6.tgz", + "integrity": "sha512-oUZ4Mc6Yt/qTvFZ/yD4nnUIN8pXhrBN0h4/SZ4e8W1TcHNvQkV6gUkkYkn8fZRvFwTMYjvWot+eAHHNRsSl/eA==", "dev": true, "optional": true }, "node_modules/@truffle/provider": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.3.9.tgz", - "integrity": "sha512-6vVSpbP8b2SuNz1fE1KeeQHMBaQ7oD5Nf4CLikXNWrj3SVyMpN3PxsEnaHMnlslAfHICpLSOHpcIWETGxfOgbg==", + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.3.10.tgz", + "integrity": "sha512-oT7WKlxj1BrZBnCh9Dd4ex623yPG5ASAW5wK9kscS81MSkPYpSjld2B3tEZH9F6Lyz6lluQO1TcssuzZUek5Qg==", "dev": true, "optional": true, "dependencies": { - "@truffle/error": "^0.2.0", - "@truffle/interface-adapter": "^0.5.33", + "@truffle/error": "^0.2.1", + "@truffle/interface-adapter": "^0.5.34", "debug": "^4.3.1", "web3": "1.10.0" } }, "node_modules/@truffle/source-map-utils": { - "version": "1.3.112", - "resolved": "https://registry.npmjs.org/@truffle/source-map-utils/-/source-map-utils-1.3.112.tgz", - "integrity": "sha512-bi95RcJzrRRfItHLLuQKTKcKMmNbrkxMqZD09r6hLFN1QpxocIBJ3RE7+n66GaXIYEYP6pvQHy0/m/O/pye4qw==", + "version": "1.3.113", + "resolved": "https://registry.npmjs.org/@truffle/source-map-utils/-/source-map-utils-1.3.113.tgz", + "integrity": "sha512-lzsocqZC0HIJYrPe+V3mSi9Pv0gu9vh8ETZJKe+8lr3prbeWEXeqZYXF+HI8Qw70cPE7or6L5A9d+wGVei5KNA==", "dev": true, "dependencies": { - "@truffle/code-utils": "^3.0.2", - "@truffle/codec": "^0.15.1", + "@truffle/code-utils": "^3.0.3", + "@truffle/codec": "^0.15.2", "debug": "^4.3.1", "json-pointer": "^0.6.1", "node-interval-tree": "^1.3.3", @@ -3178,9 +3178,9 @@ } }, "node_modules/@truffle/spinners": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@truffle/spinners/-/spinners-0.2.3.tgz", - "integrity": "sha512-YnaQ+oBRQ1I1+/P18i8oSW4orUYi6vwpZQxauEZ5X0L8atjKq+RWdiNaza6J6L+KOLunXM4+pWxnNzuUmxlJZw==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@truffle/spinners/-/spinners-0.2.4.tgz", + "integrity": "sha512-8GsIX9GzO6wBDGoNF4yAmQEe95TiIuAJq9p+2szCKGArYbAD3kbn+mG3TMS3Gr/zAS5p7fTJxnCm60E2HghsUQ==", "dev": true, "optional": true, "dependencies": { @@ -17495,14 +17495,14 @@ } }, "node_modules/truffle": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/truffle/-/truffle-5.9.3.tgz", - "integrity": "sha512-oteKoiXJR7j/Rum5OSSYZuww4Gus3O4aCtiJF13mr7Yt12S1TkgbEwy+qJVF/aJQmA4oMiUlxLoiGJiCDdlUfA==", + "version": "5.9.4", + "resolved": "https://registry.npmjs.org/truffle/-/truffle-5.9.4.tgz", + "integrity": "sha512-35UUp6Y+TAZ/ZTrUUtmIr6XSacKlq36QalC96tABsPdATKe5xBJkUKqbJBKuQcLtV1BL7nOLqgQs7fyecSXKaA==", "dev": true, "hasInstallScript": true, "dependencies": { - "@truffle/db-loader": "^0.2.27", - "@truffle/debugger": "^11.1.3", + "@truffle/db-loader": "^0.2.28", + "@truffle/debugger": "^11.1.4", "app-module-path": "^2.2.0", "ganache": "7.8.0", "mocha": "10.1.0", @@ -17512,7 +17512,7 @@ "truffle": "build/cli.bundled.js" }, "optionalDependencies": { - "@truffle/db": "^2.0.27" + "@truffle/db": "^2.0.28" } }, "node_modules/truffle/node_modules/ansi-colors": { @@ -21156,9 +21156,9 @@ } }, "@truffle/abi-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-1.0.0.tgz", - "integrity": "sha512-h1wGFB28YfByAWm/uBeMCwqDlGsrcMYTumLC/sB/qYhHisi1LK6tV47FEF7zKyf6Al2CtsO28v02+wfLXbUVRg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@truffle/abi-utils/-/abi-utils-1.0.1.tgz", + "integrity": "sha512-ZQUY3XUxEPdqxNaoXsOqF0spTtb6f5RNlnN4MUrVsJ64sOh0FJsY7rxZiUI3khfePmNh4i2qcJrQlKT36YcWUA==", "dev": true, "requires": { "change-case": "3.0.2", @@ -21173,9 +21173,9 @@ "dev": true }, "@truffle/code-utils": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@truffle/code-utils/-/code-utils-3.0.2.tgz", - "integrity": "sha512-Q4FyYIX9G4GyMa8RJDk19kvgiyGZ1CGEx2RmVcXoCDZqEyiHLzqjvCRp+/fuBz2fv7szO6d+60LO1gLCGS1drQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@truffle/code-utils/-/code-utils-3.0.3.tgz", + "integrity": "sha512-VMQMXvt/nXxWvHo5K1t697se1NU7VNh3zmiFw41qaSE1DjFZ2FMsZuW1ZoLhO4NKc14uB8k8pX3NN7XoF3uP4w==", "dev": true, "requires": { "cbor": "^5.2.0" @@ -21206,13 +21206,13 @@ } }, "@truffle/codec": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.15.1.tgz", - "integrity": "sha512-OBANcmefxEXLApWl/uU1SOHQJixO8pDaRTybP0YMvxPhgyj7G7+wC+fUvnZdmrTJD2WJFLuoYvZbxILmycEvPg==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@truffle/codec/-/codec-0.15.2.tgz", + "integrity": "sha512-rLLy1RmDq3stE1Bd6cnPO9kGpoB5QE4caY665ghmAURqlqD0ik1Bhbfi4MIRwM7YVx2sYw485qsxfPzlewnT4g==", "dev": true, "requires": { - "@truffle/abi-utils": "^1.0.0", - "@truffle/compile-common": "^0.9.5", + "@truffle/abi-utils": "^1.0.1", + "@truffle/compile-common": "^0.9.6", "big.js": "^6.0.3", "bn.js": "^5.1.3", "cbor": "^5.2.0", @@ -21272,25 +21272,25 @@ } }, "@truffle/compile-common": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.9.5.tgz", - "integrity": "sha512-qOIT7nYzQsrnpjk8LurKE6EYYvvJIk3rCHfn+xed88aG6F1l4WYtkUKl+Dcwgxgv3LH0khcQOpjqkXK5kUIJ8A==", + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/@truffle/compile-common/-/compile-common-0.9.6.tgz", + "integrity": "sha512-TCcmr1E0GqMZJ2tOaCRNEllxTBJ/g7TuD6jDJpw5Gt9Bw0YO3Cmp6yPQRynRSO4xMJbHUgiEsSfRgIhswut5UA==", "dev": true, "requires": { - "@truffle/error": "^0.2.0", + "@truffle/error": "^0.2.1", "colors": "1.4.0" } }, "@truffle/config": { - "version": "1.3.56", - "resolved": "https://registry.npmjs.org/@truffle/config/-/config-1.3.56.tgz", - "integrity": "sha512-2wg6zfaUlP3iZP9jHugx3WsyJ2dbIB+nEBULPK5YVbSkqBfXrzW0b9RJYQvyuk/AyFrp/7ycD4r5LnFLq1IHZA==", + "version": "1.3.57", + "resolved": "https://registry.npmjs.org/@truffle/config/-/config-1.3.57.tgz", + "integrity": "sha512-Cfude7ZMT2pykvMoHZ/47MvlVoZDQLs+Y85ChRw/1RKWsHrzz1BOyjDmnPLnSTOc056OuNOcgID1IdUMorVOIQ==", "dev": true, "optional": true, "requires": { - "@truffle/error": "^0.2.0", - "@truffle/events": "^0.1.23", - "@truffle/provider": "^0.3.9", + "@truffle/error": "^0.2.1", + "@truffle/events": "^0.1.24", + "@truffle/provider": "^0.3.10", "conf": "^10.1.2", "debug": "^4.3.1", "find-up": "^2.1.0", @@ -21447,14 +21447,14 @@ } }, "@truffle/dashboard-message-bus-client": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/@truffle/dashboard-message-bus-client/-/dashboard-message-bus-client-0.1.10.tgz", - "integrity": "sha512-r9GpdR96T8xzk2Z3Qq5lowixT6hQwDZ9F3D3oNjOv2AOwBrC7dGkt1Ra1FQRsABn4K7LUVvnjjn6rALlsatAdw==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@truffle/dashboard-message-bus-client/-/dashboard-message-bus-client-0.1.11.tgz", + "integrity": "sha512-ABoKtaogh5KjOw0UM5/6wYuhg4T5cMPVSSNF1rv4j3s2XGzExx3vUObvXqNO6I8gZ8xuvzClw4RmcEk8JkM8yA==", "dev": true, "optional": true, "requires": { - "@truffle/dashboard-message-bus-common": "^0.1.5", - "@truffle/promise-tracker": "^0.1.5", + "@truffle/dashboard-message-bus-common": "^0.1.6", + "@truffle/promise-tracker": "^0.1.6", "axios": "1.2.4", "debug": "^4.3.1", "delay": "^5.0.0", @@ -21465,24 +21465,24 @@ } }, "@truffle/dashboard-message-bus-common": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@truffle/dashboard-message-bus-common/-/dashboard-message-bus-common-0.1.5.tgz", - "integrity": "sha512-F4RfXi7ymNA3HFOlaujRJxAb3I8ciErCRQq+MZVaqjSPF9LSw23IizZsGpLaY43K2bGoBSxyNQRZWxsUEBujPQ==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@truffle/dashboard-message-bus-common/-/dashboard-message-bus-common-0.1.6.tgz", + "integrity": "sha512-93HNXILKeKgmW1YaWPdsQ55MJ0MaLzOA8kRXPnM5jF2H3KRlRxOeEg77R4YWtGH+cVZP4VYGXdpvUap/lOAnvw==", "dev": true, "optional": true }, "@truffle/db": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/@truffle/db/-/db-2.0.27.tgz", - "integrity": "sha512-dpeiEm1tqujnLtyGNn0q3trm8nQ5XB1dqNOBXKl60c//dYTKjUdpzqhSAjGHCNRbTppsDKUVoJKsnABANVjJag==", + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/@truffle/db/-/db-2.0.28.tgz", + "integrity": "sha512-R9FfBeVxd/SEIdw6IrMwg2vLMNXuiHMJ5XwW7ivCSyNMYXesJMA85fWYPe9bWyJ8eufLOAWlX8xr55vua4DwZQ==", "dev": true, "optional": true, "requires": { "@graphql-tools/delegate": "^8.4.3", "@graphql-tools/schema": "^8.3.1", - "@truffle/abi-utils": "^1.0.0", - "@truffle/code-utils": "^3.0.2", - "@truffle/config": "^1.3.56", + "@truffle/abi-utils": "^1.0.1", + "@truffle/code-utils": "^3.0.3", + "@truffle/config": "^1.3.57", "abstract-leveldown": "^7.2.0", "apollo-server": "^3.11.0", "debug": "^4.3.1", @@ -21533,12 +21533,12 @@ } }, "@truffle/db-loader": { - "version": "0.2.27", - "resolved": "https://registry.npmjs.org/@truffle/db-loader/-/db-loader-0.2.27.tgz", - "integrity": "sha512-hKWpiLGZWZNbe9SsOD4olRzCzG972BZkRv157wbqnOX2chHzLqzWgmHzjM7dT28xHTummXYYfG65VXAp1/J8IA==", + "version": "0.2.28", + "resolved": "https://registry.npmjs.org/@truffle/db-loader/-/db-loader-0.2.28.tgz", + "integrity": "sha512-oVXQXtYhM3Mu/pnfLR5KoqqEdw6GO6FDAFM7zZm647mIAtXCqv+EYSNt3efyqsFgQZwv3UZY6KP8TMxnjeWWGA==", "dev": true, "requires": { - "@truffle/db": "^2.0.27" + "@truffle/db": "^2.0.28" } }, "@truffle/debug-utils": { @@ -21556,15 +21556,15 @@ } }, "@truffle/debugger": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/@truffle/debugger/-/debugger-11.1.3.tgz", - "integrity": "sha512-KvZgrfzcLAFDmcsLusBndTzD35d/z7yhcREaqJy/mzROYGQoRix6VpG+LWJ7/CsiGb6DEwDPsvOOaYDEftK4hw==", + "version": "11.1.4", + "resolved": "https://registry.npmjs.org/@truffle/debugger/-/debugger-11.1.4.tgz", + "integrity": "sha512-dWpf89fHZYaW/18x1ZfQhZozg3hZqxz7Czd6vIWVQc3OiV59xpA0+YLm+aumrebj6vmjqzGWu+iHfCaLiYhwQA==", "dev": true, "requires": { "@ensdomains/ensjs": "^2.1.0", - "@truffle/abi-utils": "^1.0.0", - "@truffle/codec": "^0.15.1", - "@truffle/source-map-utils": "^1.3.112", + "@truffle/abi-utils": "^1.0.1", + "@truffle/codec": "^0.15.2", + "@truffle/source-map-utils": "^1.3.113", "bn.js": "^5.1.3", "debug": "^4.3.1", "json-pointer": "^0.6.1", @@ -21605,29 +21605,29 @@ } }, "@truffle/error": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.2.0.tgz", - "integrity": "sha512-Fe0/z4WWb7IP2gBnv3l6zqP87Y0kSMs7oiSLakKJq17q3GUunrHSdioKuNspdggxkXIBhEQLhi8C+LJdwmHKWQ==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.2.1.tgz", + "integrity": "sha512-5Qy+z9dg9hP37WNdLnXH4b9MzemWrjTufRq7/DTKqimjyxCP/1zlL8gQEMdiSx1BBtAZz0xypkID/jb7AF/Osg==", "dev": true }, "@truffle/events": { - "version": "0.1.23", - "resolved": "https://registry.npmjs.org/@truffle/events/-/events-0.1.23.tgz", - "integrity": "sha512-OIcOZXDCJPz9zzK4uTj0HxCqASNKVcs6g3Z9fT6sehGZRD4ubGHpQZoMchLBwXcggoDRApq2svTdghai624pLg==", + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/@truffle/events/-/events-0.1.24.tgz", + "integrity": "sha512-rS+jKDjmdM0g+14H/H8MzhohaTKsSS6plNNzO95MIcUs0Ytinu1DXfSkUovDpgv5h2NcRoU0BMTKCR21Y3JiNw==", "dev": true, "optional": true, "requires": { - "@truffle/dashboard-message-bus-client": "^0.1.10", - "@truffle/spinners": "^0.2.3", + "@truffle/dashboard-message-bus-client": "^0.1.11", + "@truffle/spinners": "^0.2.4", "debug": "^4.3.1", "emittery": "^0.4.1", "web3-utils": "1.10.0" } }, "@truffle/interface-adapter": { - "version": "0.5.33", - "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.33.tgz", - "integrity": "sha512-vbVcH2I8hX+wM0Xj9uAjpgxMHqfT+y6m26zSkOVvZ2wo9Ez1slaOJkK1/TZK+7nJitGZSXeJeB4purMDuADvGA==", + "version": "0.5.34", + "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.5.34.tgz", + "integrity": "sha512-gPxabfMi2TueE4VxnNuyeudOfvGJQ1ofVC02PFw14cnRQhzH327JikjjQbZ1bT6S7kWl9H6P3hQPFeYFMHdm1g==", "dev": true, "requires": { "bn.js": "^5.1.3", @@ -21697,33 +21697,33 @@ } }, "@truffle/promise-tracker": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@truffle/promise-tracker/-/promise-tracker-0.1.5.tgz", - "integrity": "sha512-wZx8eeu/6rcwwkmRF0Y832/NSQR9A9u6pyhTozv+j77jklnd/KZvu2JlACaAjP30eL5SOtSrSOzAMcSh/trJjg==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@truffle/promise-tracker/-/promise-tracker-0.1.6.tgz", + "integrity": "sha512-oUZ4Mc6Yt/qTvFZ/yD4nnUIN8pXhrBN0h4/SZ4e8W1TcHNvQkV6gUkkYkn8fZRvFwTMYjvWot+eAHHNRsSl/eA==", "dev": true, "optional": true }, "@truffle/provider": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.3.9.tgz", - "integrity": "sha512-6vVSpbP8b2SuNz1fE1KeeQHMBaQ7oD5Nf4CLikXNWrj3SVyMpN3PxsEnaHMnlslAfHICpLSOHpcIWETGxfOgbg==", + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.3.10.tgz", + "integrity": "sha512-oT7WKlxj1BrZBnCh9Dd4ex623yPG5ASAW5wK9kscS81MSkPYpSjld2B3tEZH9F6Lyz6lluQO1TcssuzZUek5Qg==", "dev": true, "optional": true, "requires": { - "@truffle/error": "^0.2.0", - "@truffle/interface-adapter": "^0.5.33", + "@truffle/error": "^0.2.1", + "@truffle/interface-adapter": "^0.5.34", "debug": "^4.3.1", "web3": "1.10.0" } }, "@truffle/source-map-utils": { - "version": "1.3.112", - "resolved": "https://registry.npmjs.org/@truffle/source-map-utils/-/source-map-utils-1.3.112.tgz", - "integrity": "sha512-bi95RcJzrRRfItHLLuQKTKcKMmNbrkxMqZD09r6hLFN1QpxocIBJ3RE7+n66GaXIYEYP6pvQHy0/m/O/pye4qw==", + "version": "1.3.113", + "resolved": "https://registry.npmjs.org/@truffle/source-map-utils/-/source-map-utils-1.3.113.tgz", + "integrity": "sha512-lzsocqZC0HIJYrPe+V3mSi9Pv0gu9vh8ETZJKe+8lr3prbeWEXeqZYXF+HI8Qw70cPE7or6L5A9d+wGVei5KNA==", "dev": true, "requires": { - "@truffle/code-utils": "^3.0.2", - "@truffle/codec": "^0.15.1", + "@truffle/code-utils": "^3.0.3", + "@truffle/codec": "^0.15.2", "debug": "^4.3.1", "json-pointer": "^0.6.1", "node-interval-tree": "^1.3.3", @@ -21731,9 +21731,9 @@ } }, "@truffle/spinners": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@truffle/spinners/-/spinners-0.2.3.tgz", - "integrity": "sha512-YnaQ+oBRQ1I1+/P18i8oSW4orUYi6vwpZQxauEZ5X0L8atjKq+RWdiNaza6J6L+KOLunXM4+pWxnNzuUmxlJZw==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@truffle/spinners/-/spinners-0.2.4.tgz", + "integrity": "sha512-8GsIX9GzO6wBDGoNF4yAmQEe95TiIuAJq9p+2szCKGArYbAD3kbn+mG3TMS3Gr/zAS5p7fTJxnCm60E2HghsUQ==", "dev": true, "optional": true, "requires": { @@ -33072,14 +33072,14 @@ "dev": true }, "truffle": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/truffle/-/truffle-5.9.3.tgz", - "integrity": "sha512-oteKoiXJR7j/Rum5OSSYZuww4Gus3O4aCtiJF13mr7Yt12S1TkgbEwy+qJVF/aJQmA4oMiUlxLoiGJiCDdlUfA==", + "version": "5.9.4", + "resolved": "https://registry.npmjs.org/truffle/-/truffle-5.9.4.tgz", + "integrity": "sha512-35UUp6Y+TAZ/ZTrUUtmIr6XSacKlq36QalC96tABsPdATKe5xBJkUKqbJBKuQcLtV1BL7nOLqgQs7fyecSXKaA==", "dev": true, "requires": { - "@truffle/db": "^2.0.27", - "@truffle/db-loader": "^0.2.27", - "@truffle/debugger": "^11.1.3", + "@truffle/db": "^2.0.28", + "@truffle/db-loader": "^0.2.28", + "@truffle/debugger": "^11.1.4", "app-module-path": "^2.2.0", "ganache": "7.8.0", "mocha": "10.1.0", diff --git a/package.json b/package.json index 5b5a6867c..4f989b903 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "eslint-config-prettier": "^8.6.0", "eslint-plugin-no-only-tests": "^3.1.0", "ethereum-input-data-decoder": "^0.4.2", - "glob": "^10.2.6", + "glob": "^10.2.7", "hardhat": "^2.14.1", "hardhat-contract-sizer": "^2.7.0", "hardhat-preprocessor": "^0.1.5", @@ -97,7 +97,7 @@ "prettier-plugin-solidity": "^1.0.0-beta.19", "simple-statistics": "^7.8.2", "solhint": "^3.3.8", - "truffle": "^5.9.3", + "truffle": "^5.9.4", "web3": "^1.8.1" } } diff --git a/scripts/config/revert-reasons.js b/scripts/config/revert-reasons.js index 17138a460..4e3b70eda 100644 --- a/scripts/config/revert-reasons.js +++ b/scripts/config/revert-reasons.js @@ -66,8 +66,8 @@ exports.RevertReasons = { 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", - NOT_ASSISTANT_AND_CLERK: "Not assistant and clerk", - NOT_ADMIN_ASSISTANT_AND_CLERK: "Not admin, assistant and clerk", + 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", diff --git a/scripts/domain/DisputeResolver.js b/scripts/domain/DisputeResolver.js index b3b15be9e..c60f8db2f 100644 --- a/scripts/domain/DisputeResolver.js +++ b/scripts/domain/DisputeResolver.js @@ -12,7 +12,7 @@ class DisputeResolver { uint256 escalationResponsePeriod; address assistant; address admin; - address clerk; + address clerk; // NB: deprecated, kept for backwards compatibility address payable treasury; string metadataUri; bool active; diff --git a/scripts/domain/DisputeResolverUpdateFields.js b/scripts/domain/DisputeResolverUpdateFields.js index 06d6bed2e..fc43f825e 100644 --- a/scripts/domain/DisputeResolverUpdateFields.js +++ b/scripts/domain/DisputeResolverUpdateFields.js @@ -5,12 +5,12 @@ class DisputeResolverUpdateFields {} DisputeResolverUpdateFields.Admin = 0; DisputeResolverUpdateFields.Assistant = 1; -DisputeResolverUpdateFields.Clerk = 2; +DisputeResolverUpdateFields.Clerk = 2; // NB: deprecated DisputeResolverUpdateFields.Types = [ DisputeResolverUpdateFields.Admin, DisputeResolverUpdateFields.Assistant, - DisputeResolverUpdateFields.Clerk, + DisputeResolverUpdateFields.Clerk, // NB: deprecated ]; // Export diff --git a/scripts/domain/Seller.js b/scripts/domain/Seller.js index 83cd3d25d..5592ede2e 100644 --- a/scripts/domain/Seller.js +++ b/scripts/domain/Seller.js @@ -11,7 +11,7 @@ class Seller { uint256 id; address assistant; address admin; - address clerk; + address clerk; // NB: deprecated, kept for backwards compatibility address payable treasury; bool active; string metadataUri; diff --git a/scripts/domain/SellerUpdateFields.js b/scripts/domain/SellerUpdateFields.js index cd4ba9496..f5afce2a7 100644 --- a/scripts/domain/SellerUpdateFields.js +++ b/scripts/domain/SellerUpdateFields.js @@ -5,7 +5,7 @@ class SellerUpdateFields {} SellerUpdateFields.Admin = 0; SellerUpdateFields.Assistant = 1; -SellerUpdateFields.Clerk = 2; +SellerUpdateFields.Clerk = 2; // Deprecated SellerUpdateFields.AuthToken = 3; SellerUpdateFields.Types = [ diff --git a/scripts/util/create-dispute-resolver.js b/scripts/util/create-dispute-resolver.js index 493902225..9e6513c63 100644 --- a/scripts/util/create-dispute-resolver.js +++ b/scripts/util/create-dispute-resolver.js @@ -18,7 +18,7 @@ Path should contain a JSON file with the following: "escalationResponsePeriod": string, "assistant": string, "admin": string, - "clerk": string, + "clerk": string, // ignored, zero address is used instead "treasury": string, "metadataUri": string, "active": boolean @@ -86,7 +86,7 @@ const createDisputeResolver = async (path) => { let initialDisputeResolver = { ...disputeResolver }; initialDisputeResolver.admin = disputeResolverSigner.address; initialDisputeResolver.assistant = disputeResolverSigner.address; - initialDisputeResolver.clerk = disputeResolverSigner.address; + initialDisputeResolver.clerk = ethers.constants.AddressZero; tx = await accountHandler .connect(disputeResolverSigner) @@ -98,8 +98,7 @@ const createDisputeResolver = async (path) => { // this is primarily used when one does not have access to private key of dispute resolver or it does not exist (i.e. DR is a smart contract) if ( initialDisputeResolver.admin.toLowerCase() != disputeResolver.admin.toLowerCase() || - initialDisputeResolver.assistant.toLowerCase() != disputeResolver.assistant.toLowerCase() || - initialDisputeResolver.clerk.toLowerCase() != disputeResolver.clerk.toLowerCase() + initialDisputeResolver.assistant.toLowerCase() != disputeResolver.assistant.toLowerCase() ) { disputeResolver.id = initialDisputeResolver.id; tx = await accountHandler.connect(disputeResolverSigner).updateDisputeResolver(disputeResolver); diff --git a/test/domain/SellerTest.js b/test/domain/SellerTest.js index 36d61793a..0e21c3492 100644 --- a/test/domain/SellerTest.js +++ b/test/domain/SellerTest.js @@ -16,7 +16,7 @@ describe("Seller", function () { accounts = await ethers.getSigners(); assistant = accounts[0].address; admin = accounts[1].address; - clerk = accounts[2].address; + clerk = ethers.constants.AddressZero; treasury = accounts[3].address; // Required constructor params diff --git a/test/example/SnapshotGateTest.js b/test/example/SnapshotGateTest.js index 27ae42836..970f7bed8 100644 --- a/test/example/SnapshotGateTest.js +++ b/test/example/SnapshotGateTest.js @@ -83,8 +83,9 @@ describe("SnapshotGate", function () { ] = await ethers.getSigners(); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; // Deploy the Protocol Diamond [protocolDiamond, , , , accessController] = await deployProtocolDiamond(maxPriorityFeePerGas); @@ -189,7 +190,7 @@ describe("SnapshotGate", function () { expect(seller.isValid()).is.true; // Create a second seller - seller2 = mockSeller(assistant2.address, assistant2.address, assistant2.address, assistant2.address); + seller2 = mockSeller(assistant2.address, assistant2.address, ethers.constants.AddressZero, assistant2.address); expect(seller2.isValid()).is.true; // AuthToken diff --git a/test/integration/01-update-account-roles-addresses.js b/test/integration/01-update-account-roles-addresses.js index e9dd63237..35087d4ae 100644 --- a/test/integration/01-update-account-roles-addresses.js +++ b/test/integration/01-update-account-roles-addresses.js @@ -54,8 +54,9 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; // Get snapshot id snapshotId = await getSnapshot(); @@ -257,20 +258,20 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { .withArgs(buyerAccount.id, rando.address, ethers.constants.AddressZero, buyerPayoff, rando.address); }); - it("Seller should be able to withdraw funds after updating clerk address", async function () { - seller.clerk = rando.address; + it("Seller should be able to withdraw funds after updating assistant address", async function () { + seller.assistant = rando.address; expect(seller.isValid()).is.true; - sellerPendingUpdate.clerk = rando.address; + sellerPendingUpdate.assistant = rando.address; // Update the seller wallet, testing for the event await expect(accountHandler.connect(admin).updateSeller(seller, emptyAuthToken)) .to.emit(accountHandler, "SellerUpdatePending") .withArgs(seller.id, sellerPendingUpdate.toStruct(), emptyAuthToken.toStruct(), admin.address); - sellerPendingUpdate.clerk = ethers.constants.AddressZero; + sellerPendingUpdate.assistant = ethers.constants.AddressZero; // Approve the update - await expect(accountHandler.connect(rando).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk])) + await expect(accountHandler.connect(rando).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant])) .to.emit(accountHandler, "SellerUpdateApplied") .withArgs( seller.id, @@ -281,12 +282,12 @@ describe("[@skip-on-coverage] Update account roles addresses", function () { rando.address ); - // Attempt to withdraw funds with old seller clerk, should fail + // Attempt to withdraw funds with old seller assistant, should fail await expect( - fundsHandler.connect(clerk).withdrawFunds(seller.id, [ethers.constants.AddressZero], [sellerPayoff]) + fundsHandler.connect(assistant).withdrawFunds(seller.id, [ethers.constants.AddressZero], [sellerPayoff]) ).to.revertedWith(RevertReasons.NOT_AUTHORIZED); - // Attempt to withdraw funds with new seller clerk, should succeed + // Attempt to withdraw funds with new seller assistant, should succeed await expect( fundsHandler.connect(rando).withdrawFunds(seller.id, [ethers.constants.AddressZero], [sellerPayoff]) ) diff --git a/test/integration/02-Upgraded-facet.js b/test/integration/02-Upgraded-facet.js index 56e0a6bbc..3f887cb56 100644 --- a/test/integration/02-Upgraded-facet.js +++ b/test/integration/02-Upgraded-facet.js @@ -70,8 +70,9 @@ describe("[@skip-on-coverage] After facet upgrade, everything is still operation } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; [deployer] = await ethers.getSigners(); // Initial ids for all the things @@ -777,10 +778,12 @@ describe("[@skip-on-coverage] After facet upgrade, everything is still operation const tokenAmountsBuyer = [buyerPayoff, ethers.BigNumber.from(buyerPayoff).div("5").toString()]; // seller withdrawal - const tx = await fundsHandler.connect(clerk).withdrawFunds(seller.id, tokenListSeller, tokenAmountsSeller); + const tx = await fundsHandler + .connect(assistant) + .withdrawFunds(seller.id, tokenListSeller, tokenAmountsSeller); await expect(tx) .to.emit(fundsHandler, "FundsWithdrawn") - .withArgs(seller.id, treasury.address, mockToken.address, sellerPayoff, clerk.address); + .withArgs(seller.id, treasury.address, mockToken.address, sellerPayoff, assistant.address); await expect(tx) .to.emit(fundsHandler, "FundsWithdrawn") @@ -789,7 +792,7 @@ describe("[@skip-on-coverage] After facet upgrade, everything is still operation treasury.address, ethers.constants.Zero, ethers.BigNumber.from(sellerPayoff).div("2"), - clerk.address + assistant.address ); // buyer withdrawal @@ -839,7 +842,7 @@ describe("[@skip-on-coverage] After facet upgrade, everything is still operation // seller withdrawal // Attempt to withdraw the funds, expecting revert await expect( - fundsHandler.connect(clerk).withdrawFunds(seller.id, tokenListSeller, tokenAmountsSeller) + fundsHandler.connect(assistant).withdrawFunds(seller.id, tokenListSeller, tokenAmountsSeller) ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); // buyer withdrawal diff --git a/test/integration/03-DR-removes-the-seller-from-allowed-list.js b/test/integration/03-DR-removes-the-seller-from-allowed-list.js index 0e605ebbc..79b6743d9 100644 --- a/test/integration/03-DR-removes-the-seller-from-allowed-list.js +++ b/test/integration/03-DR-removes-the-seller-from-allowed-list.js @@ -54,8 +54,9 @@ describe("[@skip-on-coverage] DR removes sellers from the approved seller list", } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; // Get snapshot id snapshotId = await getSnapshot(); @@ -76,7 +77,7 @@ describe("[@skip-on-coverage] DR removes sellers from the approved seller list", seller = mockSeller(assistant.address, admin.address, clerk.address, treasury.address); expect(seller.isValid()).is.true; - const seller2 = mockSeller(other1.address, other1.address, other1.address, other1.address); + const seller2 = mockSeller(other1.address, other1.address, ethers.constants.AddressZero, other1.address); expect(seller2.isValid()).is.true; // VoucherInitValues diff --git a/test/integration/04-DR-removes-fees.js b/test/integration/04-DR-removes-fees.js index f0235756a..18edbb5ac 100644 --- a/test/integration/04-DR-removes-fees.js +++ b/test/integration/04-DR-removes-fees.js @@ -55,8 +55,9 @@ describe("[@skip-on-coverage] DR removes fee", function () { } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; expectedCloneAddress = calculateContractAddress(accountHandler.address, "1"); emptyAuthToken = mockAuthToken(); diff --git a/test/integration/seaport/seaport-integration.js b/test/integration/seaport/seaport-integration.js index 90bb3c674..c8744419c 100644 --- a/test/integration/seaport/seaport-integration.js +++ b/test/integration/seaport/seaport-integration.js @@ -44,13 +44,13 @@ describe("[@skip-on-coverage] Seaport integration", function () { contractInstances: { accountHandler, offerHandler, fundsHandler }, } = await setupTestEnvironment(contracts)); - const seller = mockSeller(assistant.address, assistant.address, assistant.address, assistant.address); + const seller = mockSeller(assistant.address, assistant.address, ethers.constants.AddressZero, assistant.address); const emptyAuthToken = mockAuthToken(); const voucherInitValues = mockVoucherInitValues(); await accountHandler.connect(assistant).createSeller(seller, emptyAuthToken, voucherInitValues); - const disputeResolver = mockDisputeResolver(DR.address, DR.address, DR.address, DR.address, true); + const disputeResolver = mockDisputeResolver(DR.address, DR.address, ethers.constants.AddressZero, DR.address, true); const disputeResolverFees = [new DisputeResolverFee(ethers.constants.AddressZero, "Native", "0")]; const sellerAllowList = []; diff --git a/test/protocol/AccountHandlerTest.js b/test/protocol/AccountHandlerTest.js index 2626802a7..590dbee11 100644 --- a/test/protocol/AccountHandlerTest.js +++ b/test/protocol/AccountHandlerTest.js @@ -12,6 +12,7 @@ const { accountId, } = require("../util/mock"); const { setupTestEnvironment, getSnapshot, revertToSnapshot } = require("../util/utils"); +const { ethers } = require("hardhat"); /** * Test the Boson Account Handler interface @@ -49,7 +50,8 @@ describe("IBosonAccountHandler", function () { } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; + assistant = admin; + clerk = { address: ethers.constants.AddressZero }; // Get snapshot id snapshotId = await getSnapshot(); @@ -148,7 +150,7 @@ describe("IBosonAccountHandler", function () { //addresses need to be unique to seller Id, so setting them to random addresses here seller.assistant = rando.address; seller.admin = rando.address; - seller.clerk = rando.address; + seller.clerk = ethers.constants.AddressZero; // Create another seller await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); diff --git a/test/protocol/BundleHandlerTest.js b/test/protocol/BundleHandlerTest.js index 5d5ac2ed1..5fab960e5 100644 --- a/test/protocol/BundleHandlerTest.js +++ b/test/protocol/BundleHandlerTest.js @@ -93,8 +93,9 @@ describe("IBosonBundleHandler", function () { } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; // Deploy the mock tokens [bosonToken] = await deployMockTokens(); @@ -385,7 +386,7 @@ describe("IBosonBundleHandler", function () { it("Caller is not the seller of all offers", async function () { // create another seller and an offer let expectedNewOfferId = "6"; - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); const tx = await offerHandler @@ -425,7 +426,7 @@ describe("IBosonBundleHandler", function () { it("Caller is not the seller of all twins", async function () { // create another seller and a twin let expectedNewTwinId = "6"; - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); await bosonToken.connect(rando).approve(twinHandler.address, 1); // approving the twin handler diff --git a/test/protocol/BuyerHandlerTest.js b/test/protocol/BuyerHandlerTest.js index 0b34c6e89..9471e1f85 100644 --- a/test/protocol/BuyerHandlerTest.js +++ b/test/protocol/BuyerHandlerTest.js @@ -53,7 +53,8 @@ describe("BuyerHandler", function () { } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; + assistant = admin; + clerk = { address: ethers.constants.AddressZero }; // Get snapshot id snapshotId = await getSnapshot(); diff --git a/test/protocol/DisputeHandlerTest.js b/test/protocol/DisputeHandlerTest.js index 1fdc30b36..4e6dac311 100644 --- a/test/protocol/DisputeHandlerTest.js +++ b/test/protocol/DisputeHandlerTest.js @@ -115,8 +115,9 @@ describe("IBosonDisputeHandler", function () { } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; // Get snapshot id snapshotId = await getSnapshot(); @@ -866,7 +867,7 @@ describe("IBosonDisputeHandler", function () { it("Buyer can also have a seller account and this will work", async function () { // Create a valid seller with buyer's wallet - seller = mockSeller(buyer.address, buyer.address, buyer.address, buyer.address); + seller = mockSeller(buyer.address, buyer.address, ethers.constants.AddressZero, buyer.address); expect(seller.isValid()).is.true; await accountHandler.connect(buyer).createSeller(seller, emptyAuthToken, voucherInitValues); @@ -1117,7 +1118,7 @@ describe("IBosonDisputeHandler", function () { // Wallet with seller account, but not the seller in this exchange // Create a valid seller - seller = mockSeller(other1.address, other1.address, other1.address, other1.address); + seller = mockSeller(other1.address, other1.address, ethers.constants.AddressZero, other1.address); expect(seller.isValid()).is.true; await accountHandler.connect(other1).createSeller(seller, emptyAuthToken, voucherInitValues); diff --git a/test/protocol/DisputeResolverHandlerTest.js b/test/protocol/DisputeResolverHandlerTest.js index 7d134b00f..40e25a6f5 100644 --- a/test/protocol/DisputeResolverHandlerTest.js +++ b/test/protocol/DisputeResolverHandlerTest.js @@ -103,7 +103,8 @@ describe("DisputeResolverHandler", function () { } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; + assistant = admin; + clerk = { address: ethers.constants.AddressZero }; // Get snapshot id snapshotId = await getSnapshot(); @@ -126,8 +127,8 @@ describe("DisputeResolverHandler", function () { // Create two additional sellers and create seller allow list seller = mockSeller(assistant.address, admin.address, clerk.address, treasury.address); - seller2 = mockSeller(other1.address, other1.address, other1.address, other1.address); - let seller3 = mockSeller(other2.address, other2.address, other2.address, other2.address); + seller2 = mockSeller(other1.address, other1.address, ethers.constants.AddressZero, other1.address); + let seller3 = mockSeller(other2.address, other2.address, ethers.constants.AddressZero, other2.address); // VoucherInitValues voucherInitValues = mockVoucherInitValues(); @@ -326,7 +327,13 @@ describe("DisputeResolverHandler", function () { ); // Create a dispute resolver 2 - disputeResolver2 = mockDisputeResolver(other1.address, other1.address, other1.address, other1.address, true); + disputeResolver2 = mockDisputeResolver( + other1.address, + other1.address, + ethers.constants.AddressZero, + other1.address, + true + ); expect(disputeResolver2.isValid()).is.true; await accountHandler @@ -404,7 +411,13 @@ describe("DisputeResolverHandler", function () { expect(valid).is.true; // Create a valid dispute resolver, then set fields in tests directly - disputeResolver2 = mockDisputeResolver(other1.address, other1.address, other1.address, treasury.address, true); + disputeResolver2 = mockDisputeResolver( + other1.address, + other1.address, + ethers.constants.AddressZero, + treasury.address, + true + ); expect(disputeResolver2.isValid()).is.true; expectedDisputeResolverStruct = disputeResolver2.toStruct(); @@ -452,27 +465,28 @@ describe("DisputeResolverHandler", function () { ).to.revertedWith(RevertReasons.INVALID_ADDRESS); disputeResolver.admin = admin.address; - disputeResolver.clerk = ethers.constants.AddressZero; + disputeResolver.treasury = ethers.constants.AddressZero; // Attempt to Create a DisputeResolver, expecting revert await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + }); - disputeResolver.clerk = clerk.address; - disputeResolver.treasury = ethers.constants.AddressZero; + it("Supplied clerk is not a zero address", async function () { + disputeResolver.clerk = rando.address; // Attempt to Create a DisputeResolver, expecting revert await expect( accountHandler.connect(admin).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); + ).to.revertedWith(RevertReasons.CLERK_DEPRECATED); }); it("Address is not unique to this dispute resolver Id", async function () { disputeResolver2 = mockDisputeResolver( assistant.address, assistant.address, - assistant.address, + ethers.constants.AddressZero, assistant.address ); expect(disputeResolver2.isValid()).is.true; @@ -558,32 +572,20 @@ describe("DisputeResolverHandler", function () { it("Caller is not the supplied admin", async function () { disputeResolver.assistant = rando.address; - disputeResolver.clerk = rando.address; // Create a dispute resolver await expect( accountHandler.connect(rando).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.NOT_ADMIN_ASSISTANT_AND_CLERK); + ).to.revertedWith(RevertReasons.NOT_ADMIN_AND_ASSISTANT); }); it("Caller is not the supplied assistant", async function () { disputeResolver.admin = rando.address; - disputeResolver.clerk = rando.address; // Create a dispute resolver await expect( accountHandler.connect(rando).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.NOT_ADMIN_ASSISTANT_AND_CLERK); - }); - - it("Caller is not the supplied clerk", async function () { - disputeResolver.admin = rando.address; - disputeResolver.assistant = rando.address; - - // Create a dispute resolver - await expect( - accountHandler.connect(rando).createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList) - ).to.revertedWith(RevertReasons.NOT_ADMIN_ASSISTANT_AND_CLERK); + ).to.revertedWith(RevertReasons.NOT_ADMIN_AND_ASSISTANT); }); it("Active is false", async function () { @@ -737,7 +739,6 @@ describe("DisputeResolverHandler", function () { ).toString(); disputeResolver.assistant = disputeResolverPendingUpdate.assistant = other1.address; disputeResolver.admin = disputeResolverPendingUpdate.admin = other2.address; - disputeResolver.clerk = disputeResolverPendingUpdate.clerk = other3.address; disputeResolver.treasury = other4.address; disputeResolver.metadataUri = "https://ipfs.io/ipfs/updatedUri"; disputeResolver.active = true; @@ -755,10 +756,10 @@ describe("DisputeResolverHandler", function () { .to.emit(accountHandler, "DisputeResolverUpdatePending") .withArgs(disputeResolver.id, disputeResolverPendingUpdateStruct, admin.address); - // Assistant admin and clerk needs owner approval and won't be updated until then + // Assistant and admin needs owner approval and won't be updated until then expectedDisputeResolver.assistant = assistant.address; expectedDisputeResolver.admin = admin.address; - expectedDisputeResolver.clerk = clerk.address; + expectedDisputeResolver.clerk = ethers.constants.AddressZero; expectedDisputeResolverStruct = expectedDisputeResolver.toStruct(); // Testing for the DisputeResolverUpdateApplied event @@ -778,7 +779,7 @@ describe("DisputeResolverHandler", function () { ).toString(); disputeResolver.assistant = other1.address; disputeResolver.admin = other2.address; - disputeResolver.clerk = other3.address; + disputeResolver.clerk = ethers.constants.AddressZero; disputeResolver.treasury = other4.address; disputeResolver.metadataUri = "https://ipfs.io/ipfs/updatedUri"; disputeResolver.active = true; @@ -799,11 +800,6 @@ describe("DisputeResolverHandler", function () { .connect(other2) .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Admin]); - // Approve clerk update - await accountHandler - .connect(other3) - .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Clerk]); - // Get the disupte resolver as structs [, disputeResolverStruct, disputeResolverFeeListStruct] = await accountHandler .connect(rando) @@ -841,9 +837,6 @@ describe("DisputeResolverHandler", function () { [exists] = await accountHandler.connect(rando).getDisputeResolverByAddress(disputeResolver.admin); expect(exists).to.be.true; - - [exists] = await accountHandler.connect(rando).getDisputeResolverByAddress(disputeResolver.clerk); - expect(exists).to.be.true; }); it("should ignore active flag passed in", async function () { @@ -914,7 +907,12 @@ describe("DisputeResolverHandler", function () { it("should update the correct dispute resolver", async function () { // Configure another dispute resolver - disputeResolver2 = mockDisputeResolver(other1.address, other1.address, other1.address, other1.address); + disputeResolver2 = mockDisputeResolver( + other1.address, + other1.address, + ethers.constants.AddressZero, + other1.address + ); expect(disputeResolver2.isValid()).is.true; const expectedDisputeResolver2 = disputeResolver2.clone(); @@ -947,7 +945,7 @@ describe("DisputeResolverHandler", function () { ).toString(); disputeResolver.assistant = rando.address; disputeResolver.admin = rando.address; - disputeResolver.clerk = rando.address; + disputeResolver.clerk = ethers.constants.AddressZero; disputeResolver.treasury = rando.address; disputeResolver.metadataUri = "https://ipfs.io/ipfs/updatedUri"; expect(disputeResolver.isValid()).is.true; @@ -958,13 +956,12 @@ describe("DisputeResolverHandler", function () { // Update the first dispute resolver await accountHandler.connect(admin).updateDisputeResolver(disputeResolver); - // Approve assistant, clerk and admin update + // Approve assistant and admin update await accountHandler .connect(rando) .optInToDisputeResolverUpdate(disputeResolver.id, [ DisputeResolverUpdateFields.Assistant, DisputeResolverUpdateFields.Admin, - DisputeResolverUpdateFields.Clerk, ]); [, disputeResolverStruct, disputeResolverFeeListStruct] = await accountHandler @@ -1080,7 +1077,7 @@ describe("DisputeResolverHandler", function () { // Update dispute resolver fields disputeResolver.assistant = other1.address; disputeResolver.admin = other2.address; - disputeResolver.clerk = other3.address; + disputeResolver.clerk = ethers.constants.AddressZero; disputeResolver.active = true; expect(disputeResolver.isValid()).is.true; @@ -1088,7 +1085,7 @@ describe("DisputeResolverHandler", function () { disputeResolverPendingUpdate.assistant = other1.address; disputeResolverPendingUpdate.admin = other2.address; - disputeResolverPendingUpdate.clerk = other3.address; + disputeResolverPendingUpdate.clerk = ethers.constants.AddressZero; disputeResolverPendingUpdateStruct = disputeResolverPendingUpdate.toStruct(); // Request to update a dispute resolver, testing for the DisputeResolerUpdatePending event @@ -1106,13 +1103,13 @@ describe("DisputeResolverHandler", function () { .connect(other2) .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Admin]); - // Approve clerk update - await accountHandler - .connect(other3) - .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Clerk]); - // Configure another dispute resolver - disputeResolver2 = mockDisputeResolver(rando.address, rando.address, rando.address, rando.address); + disputeResolver2 = mockDisputeResolver( + rando.address, + rando.address, + ethers.constants.AddressZero, + rando.address + ); expect(disputeResolver2.isValid()).is.true; // Create another dispute resolver @@ -1134,11 +1131,11 @@ describe("DisputeResolverHandler", function () { .withArgs(disputeResolver2.id, disputeResolver2Struct, disputeResolverPendingUpdateStruct, rando.address); }); - it("should be possible to use the same address for assistant, admin, clerk, and treasury", async function () { + it("should be possible to use the same address for assistant, admin and treasury", async function () { // Update dispute resolver fields disputeResolver.assistant = other1.address; disputeResolver.admin = other1.address; - disputeResolver.clerk = other1.address; + disputeResolver.clerk = ethers.constants.AddressZero; disputeResolver.treasury = other1.address; expect(disputeResolver.isValid()).is.true; @@ -1146,12 +1143,12 @@ describe("DisputeResolverHandler", function () { expectedDisputeResolver = disputeResolver.clone(); expectedDisputeResolver.assistant = assistant.address; expectedDisputeResolver.admin = admin.address; - expectedDisputeResolver.clerk = clerk.address; + expectedDisputeResolver.clerk = ethers.constants.AddressZero; expectedDisputeResolverStruct = expectedDisputeResolver.toStruct(); disputeResolverPendingUpdate.assistant = other1.address; disputeResolverPendingUpdate.admin = other1.address; - disputeResolverPendingUpdate.clerk = other1.address; + disputeResolverPendingUpdate.clerk = ethers.constants.AddressZero; disputeResolverPendingUpdateStruct = disputeResolverPendingUpdate.toStruct(); // Update a dispute resolver @@ -1187,7 +1184,6 @@ describe("DisputeResolverHandler", function () { .optInToDisputeResolverUpdate(disputeResolver.id, [ DisputeResolverUpdateFields.Assistant, DisputeResolverUpdateFields.Admin, - DisputeResolverUpdateFields.Clerk, ]) ) .to.emit(accountHandler, "DisputeResolverUpdateApplied") @@ -1252,24 +1248,30 @@ describe("DisputeResolverHandler", function () { ); disputeResolver.admin = admin.address; - disputeResolver.clerk = ethers.constants.AddressZero; + disputeResolver.treasury = ethers.constants.AddressZero; // Attempt to update the disputer resolver, expecting revert await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( RevertReasons.INVALID_ADDRESS ); + }); - disputeResolver.clerk = clerk.address; - disputeResolver.treasury = ethers.constants.AddressZero; + it("Supplied clerk is not a zero address", async function () { + disputeResolver.clerk = rando.address; // Attempt to update the disputer resolver, expecting revert await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( - RevertReasons.INVALID_ADDRESS + RevertReasons.CLERK_DEPRECATED ); }); it("Address is not unique to this dispute resolver Id", async function () { - disputeResolver2 = mockDisputeResolver(other1.address, other1.address, other1.address, other1.address); + disputeResolver2 = mockDisputeResolver( + other1.address, + other1.address, + ethers.constants.AddressZero, + other1.address + ); expect(disputeResolver2.isValid()).is.true; disputeResolver2Struct = disputeResolver2.toStruct(); await accountHandler @@ -1291,21 +1293,17 @@ describe("DisputeResolverHandler", function () { await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE ); - - disputeResolver.admin = admin.address; - disputeResolver.clerk = other1.address; - - // Attempt to update dispute resolver 1 with non-unique clerk address, expecting revert - await expect(accountHandler.connect(admin).updateDisputeResolver(disputeResolver)).to.revertedWith( - RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE - ); }); it("Address is not unique to this dispute resolver Id", async function () { - disputeResolver2 = mockDisputeResolver(other1.address, other1.address, other1.address, other1.address); + disputeResolver2 = mockDisputeResolver( + other1.address, + other1.address, + ethers.constants.AddressZero, + other1.address + ); expect(disputeResolver2.isValid()).is.true; - //disputeResolver2Struct = disputeResolver2.toStruct(); await accountHandler .connect(other1) .createDisputeResolver(disputeResolver2, disputeResolverFees, sellerAllowList); @@ -1318,23 +1316,14 @@ describe("DisputeResolverHandler", function () { RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE ); - //Set dispute resolver 2's assistant address to dispute resolver 1's clerk address + //Set dispute resolver 2's assistant address to dispute resolver 1's assistant address disputeResolver2.admin = other2.address; - disputeResolver2.assistant = clerk.address; + disputeResolver2.assistant = assistant.address; // 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 ); - - //Set dispute resolver 2's clerk address to dispute resolver 1's admin address - disputeResolver2.assistant = other1.address; - disputeResolver2.clerk = admin.address; - - // Attempt to update dispute resolver 1 with non-unique clerk address, expecting revert - await expect(accountHandler.connect(other1).updateDisputeResolver(disputeResolver2)).to.revertedWith( - RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE - ); }); it("EscalationResponsePeriod is invalid", async function () { @@ -1772,7 +1761,7 @@ describe("DisputeResolverHandler", function () { .createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList); // make another seller with id = "5" - let seller4 = mockSeller(other3.address, other3.address, other3.address, other3.address); + let seller4 = mockSeller(other3.address, other3.address, ethers.constants.AddressZero, other3.address); await accountHandler.connect(other3).createSeller(seller4, emptyAuthToken, voucherInitValues); @@ -1935,7 +1924,7 @@ describe("DisputeResolverHandler", function () { .createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList); // make another seller with id = "5" - const seller4 = mockSeller(other3.address, other3.address, other3.address, other3.address); + const seller4 = mockSeller(other3.address, other3.address, ethers.constants.AddressZero, other3.address); // AuthToken emptyAuthToken = mockAuthToken(); @@ -2029,7 +2018,7 @@ describe("DisputeResolverHandler", function () { expect(returnedSellerAllowList.toString()).to.eql(expectedSellerAllowList.toString(), "Allowed list wrong"); // make another seller with id = "6" - const seller6 = mockSeller(other4.address, other4.address, other4.address, other4.address); + const seller6 = mockSeller(other4.address, other4.address, ethers.constants.AddressZero, other4.address); await accountHandler.connect(other4).createSeller(seller6, emptyAuthToken, voucherInitValues); // check that mappings of allowed selleres were updated @@ -2095,7 +2084,7 @@ describe("DisputeResolverHandler", function () { it("Seller id is not approved", async function () { // make another seller with id = "6" - const seller6 = mockSeller(other4.address, other4.address, other4.address, other4.address); + const seller6 = mockSeller(other4.address, other4.address, ethers.constants.AddressZero, other4.address); await accountHandler.connect(other4).createSeller(seller6, emptyAuthToken, voucherInitValues); // seller exists, it's not approved @@ -2169,29 +2158,8 @@ describe("DisputeResolverHandler", function () { ); }); - it("New clerk should opt-in to update disputeResolver", async function () { - disputeResolver.clerk = other1.address; - expectedDisputeResolver.clerk = other1.address; - expectedDisputeResolverStruct = expectedDisputeResolver.toStruct(); - - await accountHandler.connect(admin).updateDisputeResolver(disputeResolver); - - await expect( - accountHandler - .connect(other1) - .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Clerk]) - ) - .to.emit(accountHandler, "DisputeResolverUpdateApplied") - .withArgs( - disputeResolver.id, - expectedDisputeResolverStruct, - disputeResolverPendingUpdateStruct, - other1.address - ); - }); - - it("Should update admin, clerk and assistant in a single call ", async function () { - disputeResolver.clerk = expectedDisputeResolver.clerk = other1.address; + it("Should update admin and assistant in a single call ", async function () { + disputeResolver.clerk = expectedDisputeResolver.clerk = ethers.constants.AddressZero; disputeResolver.admin = expectedDisputeResolver.admin = other1.address; disputeResolver.assistant = expectedDisputeResolver.assistant = other1.address; expectedDisputeResolverStruct = expectedDisputeResolver.toStruct(); @@ -2202,7 +2170,6 @@ describe("DisputeResolverHandler", function () { accountHandler .connect(other1) .optInToDisputeResolverUpdate(disputeResolver.id, [ - DisputeResolverUpdateFields.Clerk, DisputeResolverUpdateFields.Admin, DisputeResolverUpdateFields.Assistant, ]) @@ -2277,13 +2244,13 @@ describe("DisputeResolverHandler", function () { await expect( accountHandler .connect(other1) - .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Clerk]) + .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Admin]) ).to.not.emit(accountHandler, "DisputeResolverUpdateApplied"); }); context("💔 Revert Reasons", async function () { it("There are no pending updates", async function () { - disputeResolver.clerk = other1.address; + disputeResolver.clerk = ethers.constants.AddressZero; disputeResolver.admin = other1.address; disputeResolver.assistant = other1.address; expectedDisputeResolver = disputeResolver.clone(); @@ -2297,7 +2264,6 @@ describe("DisputeResolverHandler", function () { accountHandler .connect(other1) .optInToDisputeResolverUpdate(disputeResolver.id, [ - DisputeResolverUpdateFields.Clerk, DisputeResolverUpdateFields.Admin, DisputeResolverUpdateFields.Assistant, ]) @@ -2328,19 +2294,6 @@ describe("DisputeResolverHandler", function () { ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); }); - it("Caller is not the new clerk", async function () { - disputeResolver.clerk = other1.address; - disputeResolverStruct = disputeResolver.toStruct(); - - await accountHandler.connect(admin).updateDisputeResolver(disputeResolver); - - await expect( - accountHandler - .connect(other2) - .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Clerk]) - ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); - }); - it("Caller is not the new assistant", async function () { disputeResolver.assistant = other1.address; disputeResolverStruct = disputeResolver.toStruct(); @@ -2373,7 +2326,12 @@ describe("DisputeResolverHandler", function () { await accountHandler.connect(admin).updateDisputeResolver(disputeResolver); // Create disputeResolver with same admin - disputeResolver2 = mockDisputeResolver(other1.address, other1.address, other1.address, other1.address); + disputeResolver2 = mockDisputeResolver( + other1.address, + other1.address, + ethers.constants.AddressZero, + other1.address + ); expect(disputeResolver2.isValid()).is.true; await accountHandler @@ -2388,46 +2346,43 @@ describe("DisputeResolverHandler", function () { ).to.revertedWith(RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE); }); - it("Clerk is not unique to this disputeResolver", async function () { - // Update disputeResolver clerk - disputeResolver.clerk = other1.address; + it("Assistant is not unique to this disputeResolver", async function () { + // Update disputeResolver assistant + disputeResolver.assistant = other1.address; await accountHandler.connect(admin).updateDisputeResolver(disputeResolver); - // Create disputeResolver with same clerk - disputeResolver2 = mockDisputeResolver(other1.address, other1.address, other1.address, other1.address); + // Create disputeResolver with same assistant + disputeResolver2 = mockDisputeResolver( + other1.address, + other1.address, + ethers.constants.AddressZero, + other1.address + ); expect(disputeResolver2.isValid()).is.true; await accountHandler .connect(other1) .createDisputeResolver(disputeResolver2, disputeResolverFees, sellerAllowList); - // Attemp to approve the update with non-unique clerk, expecting revert + // Attemp to approve the update with non-unique assistant, expecting revert await expect( accountHandler .connect(other1) - .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Clerk]) + .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Assistant]) ).to.revertedWith(RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE); }); - it("Assistant is not unique to this disputeResolver", async function () { - // Update disputeResolver assistant + it("Dispute resolver tries to update the clerk", async function () { disputeResolver.assistant = other1.address; - await accountHandler.connect(admin).updateDisputeResolver(disputeResolver); - - // Create disputeResolver with same assistant - disputeResolver2 = mockDisputeResolver(other1.address, other1.address, other1.address, other1.address); - expect(disputeResolver2.isValid()).is.true; + disputeResolverStruct = disputeResolver.toStruct(); - await accountHandler - .connect(other1) - .createDisputeResolver(disputeResolver2, disputeResolverFees, sellerAllowList); + await accountHandler.connect(admin).updateDisputeResolver(disputeResolver); - // Attemp to approve the update with non-unique assistant, expecting revert await expect( accountHandler - .connect(other1) - .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Assistant]) - ).to.revertedWith(RevertReasons.DISPUTE_RESOLVER_ADDRESS_MUST_BE_UNIQUE); + .connect(other2) + .optInToDisputeResolverUpdate(disputeResolver.id, [DisputeResolverUpdateFields.Clerk]) + ).to.revertedWith(RevertReasons.CLERK_DEPRECATED); }); }); }); diff --git a/test/protocol/ExchangeHandlerTest.js b/test/protocol/ExchangeHandlerTest.js index f6c531bcb..e7524c168 100644 --- a/test/protocol/ExchangeHandlerTest.js +++ b/test/protocol/ExchangeHandlerTest.js @@ -156,8 +156,9 @@ describe("IBosonExchangeHandler", function () { [deployer] = await ethers.getSigners(); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; // Deploy the mock tokens [foreign20, foreign721, foreign1155] = await deployMockTokens(["Foreign20", "Foreign721", "Foreign1155"]); @@ -358,7 +359,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucherClone = await ethers.getContractAt("IBosonVoucher", expectedCloneAddress); // Create a new seller to get new clone - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); seller.id = "3"; // buyer is created after seller in this test expect(seller.isValid()).is.true; @@ -442,7 +443,7 @@ describe("IBosonExchangeHandler", function () { bosonVoucherClone = await ethers.getContractAt("IBosonVoucher", expectedCloneAddress); // Create a new seller to get new clone - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); seller.id = "3"; // buyer is created after seller in this test expect(seller.isValid()).is.true; @@ -3556,7 +3557,7 @@ describe("IBosonExchangeHandler", function () { it("Caller is not a clone address associated with the seller", async function () { // Create a new seller to get new clone - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); expect(seller.isValid()).is.true; await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); diff --git a/test/protocol/FundsHandlerTest.js b/test/protocol/FundsHandlerTest.js index 27d3de436..9212ed4cf 100644 --- a/test/protocol/FundsHandlerTest.js +++ b/test/protocol/FundsHandlerTest.js @@ -133,8 +133,9 @@ describe("IBosonFundsHandler", function () { } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; [deployer, protocolTreasury] = await ethers.getSigners(); @@ -476,10 +477,12 @@ describe("IBosonFundsHandler", function () { tokenAmountsBuyer = [buyerPayoff, ethers.BigNumber.from(buyerPayoff).div("5").toString()]; // seller withdrawal - const tx = await fundsHandler.connect(clerk).withdrawFunds(seller.id, tokenListSeller, tokenAmountsSeller); + const tx = await fundsHandler + .connect(assistant) + .withdrawFunds(seller.id, tokenListSeller, tokenAmountsSeller); await expect(tx) .to.emit(fundsHandler, "FundsWithdrawn") - .withArgs(seller.id, treasury.address, mockToken.address, sellerPayoff, clerk.address); + .withArgs(seller.id, treasury.address, mockToken.address, sellerPayoff, assistant.address); await expect(tx) .to.emit(fundsHandler, "FundsWithdrawn") @@ -488,7 +491,7 @@ describe("IBosonFundsHandler", function () { treasury.address, ethers.constants.Zero, ethers.BigNumber.from(sellerPayoff).div("2"), - clerk.address + assistant.address ); // buyer withdrawal @@ -529,7 +532,9 @@ describe("IBosonFundsHandler", function () { const withdrawAmount = ethers.BigNumber.from(sellerPayoff) .sub(ethers.utils.parseUnits("0.1", "ether")) .toString(); - await fundsHandler.connect(clerk).withdrawFunds(seller.id, [ethers.constants.AddressZero], [withdrawAmount]); + await fundsHandler + .connect(assistant) + .withdrawFunds(seller.id, [ethers.constants.AddressZero], [withdrawAmount]); // Read on chain state sellersAvailableFunds = FundsList.fromStruct(await fundsHandler.getAvailableFunds(seller.id)); @@ -605,7 +610,7 @@ describe("IBosonFundsHandler", function () { ); // withdraw all funds - await fundsHandler.connect(clerk).withdrawFunds(seller.id, [], []); + await fundsHandler.connect(assistant).withdrawFunds(seller.id, [], []); // Read on chain state sellersAvailableFunds = FundsList.fromStruct(await fundsHandler.getAvailableFunds(seller.id)); @@ -650,7 +655,7 @@ describe("IBosonFundsHandler", function () { ); // withdraw all funds - await fundsHandler.connect(clerk).withdrawFunds(seller.id, [], []); + await fundsHandler.connect(assistant).withdrawFunds(seller.id, [], []); // Read on chain state sellersAvailableFunds = FundsList.fromStruct(await fundsHandler.getAvailableFunds(seller.id)); @@ -677,7 +682,7 @@ describe("IBosonFundsHandler", function () { ); // withdraw all funds again - await fundsHandler.connect(clerk).withdrawFunds(seller.id, [], []); + await fundsHandler.connect(assistant).withdrawFunds(seller.id, [], []); // Read on chain state sellersAvailableFunds = FundsList.fromStruct(await fundsHandler.getAvailableFunds(seller.id)); @@ -704,7 +709,9 @@ describe("IBosonFundsHandler", function () { tokenAmountsSeller = [ethers.BigNumber.from(sellerPayoff).sub(reduction).toString(), reduction]; // seller withdrawal - const tx = await fundsHandler.connect(clerk).withdrawFunds(seller.id, tokenListSeller, tokenAmountsSeller); + const tx = await fundsHandler + .connect(assistant) + .withdrawFunds(seller.id, tokenListSeller, tokenAmountsSeller); await expect(tx) .to.emit(fundsHandler, "FundsWithdrawn") .withArgs( @@ -712,12 +719,12 @@ describe("IBosonFundsHandler", function () { treasury.address, mockToken.address, ethers.BigNumber.from(sellerPayoff).sub(reduction).toString(), - clerk.address + assistant.address ); await expect(tx) .to.emit(fundsHandler, "FundsWithdrawn") - .withArgs(seller.id, treasury.address, mockToken.address, reduction, clerk.address); + .withArgs(seller.id, treasury.address, mockToken.address, reduction, assistant.address); }); context("Agent Withdraws funds", async function () { @@ -869,9 +876,9 @@ describe("IBosonFundsHandler", function () { tokenAmounts = [sellerPayoff]; // Attempt to withdraw the funds, expecting revert - await expect(fundsHandler.connect(clerk).withdrawFunds(seller.id, tokenList, tokenAmounts)).to.revertedWith( - RevertReasons.TOKEN_AMOUNT_MISMATCH - ); + await expect( + fundsHandler.connect(assistant).withdrawFunds(seller.id, tokenList, tokenAmounts) + ).to.revertedWith(RevertReasons.TOKEN_AMOUNT_MISMATCH); }); it("Caller wants to withdraw more different tokens than allowed", async function () { @@ -879,9 +886,9 @@ describe("IBosonFundsHandler", function () { tokenAmounts = new Array(101).fill("1"); // Attempt to withdraw the funds, expecting revert - await expect(fundsHandler.connect(clerk).withdrawFunds(seller.id, tokenList, tokenAmounts)).to.revertedWith( - RevertReasons.TOO_MANY_TOKENS - ); + await expect( + fundsHandler.connect(assistant).withdrawFunds(seller.id, tokenList, tokenAmounts) + ).to.revertedWith(RevertReasons.TOO_MANY_TOKENS); }); it("Caller tries to withdraw more than they have in the available funds", async function () { @@ -890,9 +897,9 @@ describe("IBosonFundsHandler", function () { tokenAmounts = [ethers.BigNumber.from(sellerPayoff).mul("2")]; // Attempt to withdraw the funds, expecting revert - await expect(fundsHandler.connect(clerk).withdrawFunds(seller.id, tokenList, tokenAmounts)).to.revertedWith( - RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS - ); + await expect( + fundsHandler.connect(assistant).withdrawFunds(seller.id, tokenList, tokenAmounts) + ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); }); it("Caller tries to withdraw the same token twice", async function () { @@ -901,9 +908,9 @@ describe("IBosonFundsHandler", function () { tokenAmounts = [sellerPayoff, sellerPayoff]; // Attempt to withdraw the funds, expecting revert - await expect(fundsHandler.connect(clerk).withdrawFunds(seller.id, tokenList, tokenAmounts)).to.revertedWith( - RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS - ); + await expect( + fundsHandler.connect(assistant).withdrawFunds(seller.id, tokenList, tokenAmounts) + ).to.revertedWith(RevertReasons.INSUFFICIENT_AVAILABLE_FUNDS); }); it("Nothing to withdraw", async function () { @@ -911,15 +918,15 @@ describe("IBosonFundsHandler", function () { tokenList = [mockToken.address]; tokenAmounts = ["0"]; - await expect(fundsHandler.connect(clerk).withdrawFunds(seller.id, tokenList, tokenAmounts)).to.revertedWith( - RevertReasons.NOTHING_TO_WITHDRAW - ); + await expect( + fundsHandler.connect(assistant).withdrawFunds(seller.id, tokenList, tokenAmounts) + ).to.revertedWith(RevertReasons.NOTHING_TO_WITHDRAW); // first withdraw everything - await fundsHandler.connect(clerk).withdrawFunds(seller.id, [], []); + await fundsHandler.connect(assistant).withdrawFunds(seller.id, [], []); // Attempt to withdraw the funds, expecting revert - await expect(fundsHandler.connect(clerk).withdrawFunds(seller.id, [], [])).to.revertedWith( + await expect(fundsHandler.connect(assistant).withdrawFunds(seller.id, [], [])).to.revertedWith( RevertReasons.NOTHING_TO_WITHDRAW ); }); @@ -982,7 +989,7 @@ describe("IBosonFundsHandler", function () { // destruct mockToken await mockToken.destruct(); - await expect(fundsHandler.connect(clerk).withdrawFunds(seller.id, [], [])).to.revertedWith( + await expect(fundsHandler.connect(assistant).withdrawFunds(seller.id, [], [])).to.revertedWith( RevertReasons.EOA_FUNCTION_CALL_SAFE_ERC20 ); }); @@ -991,7 +998,7 @@ describe("IBosonFundsHandler", function () { // pause mockToken await mockToken.pause(); - await expect(fundsHandler.connect(clerk).withdrawFunds(seller.id, [], [])).to.revertedWith( + await expect(fundsHandler.connect(assistant).withdrawFunds(seller.id, [], [])).to.revertedWith( RevertReasons.ERC20_PAUSED ); }); @@ -1005,7 +1012,7 @@ describe("IBosonFundsHandler", function () { await fundsHandler.connect(assistant).depositFunds(seller.id, foreign20ReturnFalse.address, sellerDeposit); await expect( - fundsHandler.connect(clerk).withdrawFunds(seller.id, [foreign20ReturnFalse.address], [sellerDeposit]) + fundsHandler.connect(assistant).withdrawFunds(seller.id, [foreign20ReturnFalse.address], [sellerDeposit]) ).to.revertedWith(RevertReasons.SAFE_ERC20_NOT_SUCCEEDED); }); }); diff --git a/test/protocol/GroupHandlerTest.js b/test/protocol/GroupHandlerTest.js index d6a764df9..466c6f017 100644 --- a/test/protocol/GroupHandlerTest.js +++ b/test/protocol/GroupHandlerTest.js @@ -66,8 +66,9 @@ describe("IBosonGroupHandler", function () { } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; accounts = await ethers.getSigners(); @@ -303,7 +304,7 @@ describe("IBosonGroupHandler", function () { it("Caller is not the seller of all offers", async function () { // create another seller and an offer - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); await offerHandler.connect(rando).createOffer(offer, offerDates, offerDurations, disputeResolverId, agentId); // creates an offer with id 6 @@ -571,7 +572,7 @@ describe("IBosonGroupHandler", function () { it("Caller is not the seller of all offers", async function () { // create another seller and an offer - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); await offerHandler.connect(rando).createOffer(offer, offerDates, offerDurations, disputeResolverId, agentId); // creates an offer with id 6 diff --git a/test/protocol/MetaTransactionsHandlerTest.js b/test/protocol/MetaTransactionsHandlerTest.js index 7b0ca1ce6..9287b79e2 100644 --- a/test/protocol/MetaTransactionsHandlerTest.js +++ b/test/protocol/MetaTransactionsHandlerTest.js @@ -150,8 +150,9 @@ describe("IBosonMetaTransactionsHandler", function () { } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; [deployer] = await ethers.getSigners(); @@ -245,7 +246,7 @@ describe("IBosonMetaTransactionsHandler", function () { assert.equal(result, expectedResult, "Nonce is used"); // Create a valid seller for meta transaction - seller = mockSeller(assistant.address, assistant.address, assistant.address, assistant.address); + seller = mockSeller(assistant.address, assistant.address, ethers.constants.AddressZero, assistant.address); expect(seller.isValid()).is.true; // VoucherInitValues @@ -510,7 +511,7 @@ describe("IBosonMetaTransactionsHandler", function () { context("👉 AccountHandlerFacet 👉 createSeller()", async function () { beforeEach(async function () { // Create a valid seller for meta transaction - seller = mockSeller(assistant.address, assistant.address, assistant.address, assistant.address); + seller = mockSeller(assistant.address, assistant.address, ethers.constants.AddressZero, assistant.address); expect(seller.isValid()).is.true; // VoucherInitValues @@ -1061,7 +1062,7 @@ describe("IBosonMetaTransactionsHandler", function () { context("👉TwinHandler 👉 removeTwin()", async function () { beforeEach(async function () { // Create a valid seller for meta transaction - seller = mockSeller(assistant.address, assistant.address, assistant.address, assistant.address); + seller = mockSeller(assistant.address, assistant.address, ethers.constants.AddressZero, assistant.address); expect(seller.isValid()).is.true; // VoucherInitValues @@ -1182,7 +1183,7 @@ describe("IBosonMetaTransactionsHandler", function () { it("Returns default revert reason if called function reverts without a reason", async function () { // Create a valid seller for meta transaction - seller = mockSeller(assistant.address, assistant.address, assistant.address, assistant.address); + seller = mockSeller(assistant.address, assistant.address, ethers.constants.AddressZero, assistant.address); voucherInitValues = mockVoucherInitValues(); emptyAuthToken = mockAuthToken(); await accountHandler.connect(assistant).createSeller(seller, emptyAuthToken, voucherInitValues); @@ -1224,7 +1225,7 @@ describe("IBosonMetaTransactionsHandler", function () { context("Reentrancy guard", async function () { beforeEach(async function () { // Create a valid seller for meta transaction - seller = mockSeller(assistant.address, assistant.address, assistant.address, assistant.address); + seller = mockSeller(assistant.address, assistant.address, ethers.constants.AddressZero, assistant.address); expect(seller.isValid()).is.true; // VoucherInitValues @@ -1453,7 +1454,7 @@ describe("IBosonMetaTransactionsHandler", function () { offerId = "1"; // Create a valid seller - seller = mockSeller(assistant.address, assistant.address, assistant.address, assistant.address); + seller = mockSeller(assistant.address, assistant.address, ethers.constants.AddressZero, assistant.address); expect(seller.isValid()).is.true; // VoucherInitValues @@ -3012,7 +3013,7 @@ describe("IBosonMetaTransactionsHandler", function () { offerId = "1"; // Create a valid seller - seller = mockSeller(assistant.address, assistant.address, assistant.address, assistant.address); + seller = mockSeller(assistant.address, assistant.address, ethers.constants.AddressZero, assistant.address); expect(seller.isValid()).is.true; // VoucherInitValues diff --git a/test/protocol/OfferHandlerTest.js b/test/protocol/OfferHandlerTest.js index 31b8858c0..f182e0441 100644 --- a/test/protocol/OfferHandlerTest.js +++ b/test/protocol/OfferHandlerTest.js @@ -128,8 +128,9 @@ describe("IBosonOfferHandler", function () { } = await setupTestEnvironment(contracts, { bosonTokenAddress: bosonToken.address })); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; [deployer] = await ethers.getSigners(); // Get snapshot id @@ -505,7 +506,7 @@ describe("IBosonOfferHandler", function () { it("Should allow creation of an offer if DR has a sellerAllowList and seller is on it", async function () { // Create new seller so sellerAllowList can have an entry - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); @@ -702,7 +703,13 @@ describe("IBosonOfferHandler", function () { // TODO - revisit when account deactivations are supported it.skip("Dispute resolver is not active", async function () { // create another dispute resolver, but don't activate it - disputeResolver = mockDisputeResolver(rando.address, rando.address, rando.address, rando.address, false); + disputeResolver = mockDisputeResolver( + rando.address, + rando.address, + ethers.constants.AddressZero, + rando.address, + false + ); await accountHandler .connect(rando) .createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList); @@ -735,7 +742,13 @@ describe("IBosonOfferHandler", function () { // TODO - revisit when account deactivations are supported it.skip("For absolute zero offer, specified dispute resolver is not active", async function () { // create another dispute resolver, but don't activate it - disputeResolver = mockDisputeResolver(rando.address, rando.address, rando.address, rando.address, false); + disputeResolver = mockDisputeResolver( + rando.address, + rando.address, + ethers.constants.AddressZero, + rando.address, + false + ); await accountHandler .connect(rando) .createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList); @@ -759,7 +772,7 @@ describe("IBosonOfferHandler", function () { it("Seller is not on dispute resolver's seller allow list", async function () { // Create new seller so sellerAllowList can have an entry - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); @@ -1003,7 +1016,7 @@ describe("IBosonOfferHandler", function () { // caller is an assistant of another seller // Create a valid seller, then set fields in tests directly - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); // AuthToken emptyAuthToken = mockAuthToken(); @@ -1103,7 +1116,7 @@ describe("IBosonOfferHandler", function () { // caller is an assistant of another seller // Create a valid seller, then set fields in tests directly - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); // AuthToken emptyAuthToken = mockAuthToken(); @@ -1431,7 +1444,7 @@ describe("IBosonOfferHandler", function () { // caller is an assistant of another seller // Create a valid seller, then set fields in tests directly - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); // AuthToken emptyAuthToken = mockAuthToken(); @@ -2104,7 +2117,7 @@ describe("IBosonOfferHandler", function () { it("Should allow creation of an offer if DR has a sellerAllowList and seller is on it", async function () { // Create new seller so sellerAllowList can have an entry - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); @@ -2340,7 +2353,13 @@ describe("IBosonOfferHandler", function () { // TODO - revisit when account deactivations are supported it.skip("For some offer, dispute resolver is not active", async function () { // create another dispute resolver, but don't activate it - disputeResolver = mockDisputeResolver(rando.address, rando.address, rando.address, rando.address, false); + disputeResolver = mockDisputeResolver( + rando.address, + rando.address, + ethers.constants.AddressZero, + rando.address, + false + ); await accountHandler .connect(rando) .createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList); @@ -2382,7 +2401,13 @@ describe("IBosonOfferHandler", function () { // TODO - revisit when account deactivations are supported it.skip("For some absolute zero offer, specified dispute resolver is not active", async function () { // create another dispute resolver, but don't activate it - disputeResolver = mockDisputeResolver(rando.address, rando.address, rando.address, rando.address, false); + disputeResolver = mockDisputeResolver( + rando.address, + rando.address, + ethers.constants.AddressZero, + rando.address, + false + ); await accountHandler .connect(rando) .createDisputeResolver(disputeResolver, disputeResolverFees, sellerAllowList); @@ -2411,7 +2436,7 @@ describe("IBosonOfferHandler", function () { it("For some offer seller is not on dispute resolver's seller allow list", async function () { // Create new seller so sellerAllowList can have an entry - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); await accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues); @@ -2765,7 +2790,7 @@ describe("IBosonOfferHandler", function () { ); // caller is an assistant of another seller - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); // AuthToken emptyAuthToken = mockAuthToken(); @@ -2896,7 +2921,7 @@ describe("IBosonOfferHandler", function () { ); // caller is an assistant of another seller - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); // AuthToken emptyAuthToken = mockAuthToken(); diff --git a/test/protocol/OrchestrationHandlerTest.js b/test/protocol/OrchestrationHandlerTest.js index f42978d28..a13413570 100644 --- a/test/protocol/OrchestrationHandlerTest.js +++ b/test/protocol/OrchestrationHandlerTest.js @@ -163,8 +163,9 @@ describe("IBosonOrchestrationHandler", function () { } = await setupTestEnvironment(contracts, { bosonTokenAddress: bosonToken.address })); // make all account the same - clerk = assistant = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; [deployer] = await ethers.getSigners(); @@ -1107,7 +1108,7 @@ describe("IBosonOrchestrationHandler", function () { ); // create another offer, now with bosonToken as exchange token - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); contractURI = `https://ipfs.io/ipfs/QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ`; offer.exchangeToken = bosonToken.address; offer.id = "2"; @@ -1417,7 +1418,7 @@ describe("IBosonOrchestrationHandler", function () { // Create a seller await accountHandler.connect(assistant).createSeller(seller, emptyAuthToken, voucherInitValues); - // Attempt to create a seller with non-unique admin, assistant and clerk, expecting revert + // Attempt to create a seller with non-unique admin and assistant, expecting revert // N.B. assistant and admin are tested together, since they must be the same await expect( orchestrationHandler @@ -1437,7 +1438,6 @@ describe("IBosonOrchestrationHandler", function () { it("Caller is not the supplied admin", async function () { seller.assistant = rando.address; - seller.clerk = rando.address; // Attempt to create a seller and an offer, expecting revert await expect( @@ -1459,7 +1459,6 @@ describe("IBosonOrchestrationHandler", function () { it("Caller does not own supplied auth token", async function () { seller.admin = ethers.constants.AddressZero; seller.assistant = rando.address; - seller.clerk = rando.address; // Attempt to create a seller and an offer, expecting revert await expect( @@ -1480,7 +1479,6 @@ describe("IBosonOrchestrationHandler", function () { it("Caller is not the supplied assistant", async function () { seller.admin = rando.address; - seller.clerk = rando.address; // Attempt to create a seller and an offer, expecting revert await expect( @@ -1496,12 +1494,13 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT_AND_CLERK); + ).to.revertedWith(RevertReasons.NOT_ASSISTANT); }); - it("Caller is not the supplied clerk", async function () { + it("Clerk is not a zero address", async function () { seller.admin = rando.address; seller.assistant = rando.address; + seller.clerk = rando.address; // Attempt to create a seller and an offer, expecting revert await expect( @@ -1517,7 +1516,7 @@ describe("IBosonOrchestrationHandler", function () { voucherInitValues, agentId ) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT_AND_CLERK); + ).to.revertedWith(RevertReasons.CLERK_DEPRECATED); }); it("admin address is NOT zero address and AuthTokenType is NOT None", async function () { @@ -1870,7 +1869,13 @@ describe("IBosonOrchestrationHandler", function () { // TODO - revisit when account deactivations are supported it.skip("Dispute resolver is not active", async function () { // create another dispute resolver, but don't activate it - disputeResolver = mockDisputeResolver(rando.address, rando.address, rando.address, rando.address, false); + disputeResolver = mockDisputeResolver( + rando.address, + rando.address, + ethers.constants.AddressZero, + rando.address, + false + ); disputeResolver.id = "2"; // mock id is 3 because seller was mocked first but here we are creating dispute resolver first seller.id = "3"; await accountHandler @@ -1919,7 +1924,13 @@ describe("IBosonOrchestrationHandler", function () { // TODO - revisit when account deactivations are supported it.skip("For absolute zero offer, specified dispute resolver is not active", async function () { // create another dispute resolver, but don't activate it - disputeResolver = mockDisputeResolver(rando.address, rando.address, rando.address, rando.address, false); + disputeResolver = mockDisputeResolver( + rando.address, + rando.address, + ethers.constants.AddressZero, + rando.address, + false + ); disputeResolver.id = "2"; // mock id is 3 because seller was mocked first but here we are creating dispute resolver first seller.id = "3"; @@ -1949,7 +1960,7 @@ describe("IBosonOrchestrationHandler", function () { it("Seller is not on dispute resolver's seller allow list", async function () { // Create new seller so sellerAllowList can have an entry - const newSeller = mockSeller(rando.address, rando.address, rando.address, rando.address); + const newSeller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); await accountHandler.connect(rando).createSeller(newSeller, emptyAuthToken, voucherInitValues); diff --git a/test/protocol/ProtocolInitializationHandlerTest.js b/test/protocol/ProtocolInitializationHandlerTest.js index 71103ce4d..bc2a56ed5 100644 --- a/test/protocol/ProtocolInitializationHandlerTest.js +++ b/test/protocol/ProtocolInitializationHandlerTest.js @@ -710,14 +710,14 @@ describe("ProtocolInitializationHandler", async function () { ).to.be.revertedWith(RevertReasons.WRONG_CURRENT_VERSION); }); - it("Next twin id is not 1", async () => { + it.only("Next twin id is not 1", async () => { const twinHandler = await ethers.getContractAt("IBosonTwinHandler", protocolDiamond.address); const accountHandler = await ethers.getContractAt("IBosonAccountHandler", protocolDiamond.address); const [bosonToken] = await deployMockTokens(); let twin = mockTwin(bosonToken.address, TokenType.FungibleToken); - const seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + const seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); expect(seller.isValid()).is.true; const emptyAuthToken = mockAuthToken(); diff --git a/test/protocol/SellerHandlerTest.js b/test/protocol/SellerHandlerTest.js index 5fd649f34..f282f44b3 100644 --- a/test/protocol/SellerHandlerTest.js +++ b/test/protocol/SellerHandlerTest.js @@ -30,7 +30,6 @@ describe("SellerHandler", function () { other5, other6, other7, - other8, authTokenOwner; let accountHandler, exchangeHandler, configHandler, pauseHandler; let seller, @@ -64,12 +63,13 @@ describe("SellerHandler", function () { }; ({ - signers: [pauser, admin, treasury, rando, other1, other2, other3, other4, other5, other6, other7, other8], + signers: [pauser, admin, treasury, rando, other1, other2, other3, other4, other5, other6, other7], contractInstances: { accountHandler, exchangeHandler, pauseHandler, configHandler }, } = await setupTestEnvironment(contracts)); // make all account the same - authTokenOwner = assistant = clerk = admin; + authTokenOwner = assistant = admin; + clerk = { address: ethers.constants.AddressZero }; [deployer] = await ethers.getSigners(); // Deploy mock ERC721 tokens @@ -350,10 +350,10 @@ describe("SellerHandler", function () { expect(exists).to.be.true; }); - it("should be possible to use the same address for assistant, admin, clerk, and treasury", async function () { + it("should be possible to use the same address for assistant, admin and treasury", async function () { seller.assistant = other1.address; seller.admin = other1.address; - seller.clerk = other1.address; + seller.clerk = ethers.constants.AddressZero; seller.treasury = other1.address; //Create struct again with new addresses @@ -374,7 +374,6 @@ describe("SellerHandler", function () { seller.id = accountId.next().value; seller.assistant = other1.address; seller.admin = other1.address; - seller.clerk = other1.address; //Create struct again with new addresses sellerStruct = seller.toStruct(); @@ -396,7 +395,7 @@ describe("SellerHandler", function () { // second seller expectedCloneAddress = calculateContractAddress(accountHandler.address, "2"); - seller = mockSeller(other1.address, other1.address, other1.address, other1.address); + seller = mockSeller(other1.address, other1.address, ethers.constants.AddressZero, other1.address); // Create a seller, testing for the event await expect(accountHandler.connect(other1).createSeller(seller, emptyAuthToken, voucherInitValues)) @@ -417,9 +416,8 @@ describe("SellerHandler", function () { .withArgs(seller.id, sellerStruct, expectedCloneAddress, authTokenStruct, authTokenOwner.address); seller.assistant = other1.address; - seller.clerk = other1.address; - // Update assistant and clerk addresses so we can create a seller with the same auth token id but different type + // Update assistant address so we can create a seller with the same auth token id but different type const tx = await accountHandler.connect(authTokenOwner).updateSeller(seller, authToken); pendingSellerUpdate = seller.clone(); @@ -446,11 +444,9 @@ describe("SellerHandler", function () { pendingSellerUpdate.clerk = ethers.constants.AddressZero; pendingSellerUpdateStruct = pendingSellerUpdate.toStruct(); - // Assistant and clerk addresses owner must approve the update + // Assistant address owner must approve the update await expect( - await accountHandler - .connect(other1) - .optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant, SellerUpdateFields.Clerk]) + await accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]) ) .to.emit(accountHandler, "SellerUpdateApplied") .withArgs( @@ -464,7 +460,6 @@ describe("SellerHandler", function () { seller.id = accountId.next().value; seller.assistant = authTokenOwner.address; - seller.clerk = authTokenOwner.address; //Create struct again with new addresses sellerStruct = seller.toStruct(); @@ -498,7 +493,6 @@ describe("SellerHandler", function () { .withArgs(seller.id, sellerStruct, expectedCloneAddress, authTokenStruct, authTokenOwner.address); seller.assistant = other1.address; - seller.clerk = other1.address; pendingSellerUpdate = seller.clone(); pendingSellerUpdate.id = "0"; @@ -513,7 +507,7 @@ describe("SellerHandler", function () { pendingAuthToken.tokenType = 0; pendingAuthTokenStruct = pendingAuthToken.toStruct(); - // Update assistant and clerk addresses so we can create a seller with the same auth token id but different type + // Update assistant address so we can create a seller with the same auth token id but different type const tx = await accountHandler.connect(authTokenOwner).updateSeller(seller, authToken); await expect(tx) @@ -527,12 +521,8 @@ describe("SellerHandler", function () { sellerStruct = seller.toStruct(); - // Assistant and clerk addresses owner must approve the update - await expect( - accountHandler - .connect(other1) - .optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant, SellerUpdateFields.Clerk]) - ) + // Assistant address owner must approve the update + await expect(accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant])) .to.emit(accountHandler, "SellerUpdateApplied") .withArgs( seller.id, @@ -546,7 +536,6 @@ describe("SellerHandler", function () { const newAuthTokenOwner = rando; seller.id = accountId.next().value; seller.assistant = newAuthTokenOwner.address; - seller.clerk = newAuthTokenOwner.address; //Create struct again with new addresses sellerStruct = seller.toStruct(); @@ -599,7 +588,6 @@ describe("SellerHandler", function () { await accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]); seller.admin = other1.address; - seller.clerk = other1.address; // Attempt to Create a seller with non-unique assistant, expecting revert await expect( @@ -608,27 +596,11 @@ describe("SellerHandler", function () { seller.admin = admin.address; seller.assistant = assistant.address; - seller.clerk = clerk.address; // 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); - - // Update seller clerk - seller.clerk = other2.address; - await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); - - // Approve the update - await accountHandler.connect(other2).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk]); - - seller.admin = other2.address; - seller.assistant = other2.address; - - // Attempt to Create a seller with non-unique clerk, expecting revert - await expect( - accountHandler.connect(other2).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); }); it("addresses are not unique to this seller Id when address used for different role", async function () { @@ -643,37 +615,13 @@ describe("SellerHandler", function () { await accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]); seller.admin = other1.address; - seller.clerk = other1.address; // 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); - // Update seller clerk - seller.clerk = other2.address; - seller.admin = admin.address; - seller.assistant = assistant.address; - - await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); - - // Approve the update - await accountHandler.connect(other2).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk]); - // Admin and assistant are the same address - await accountHandler - .connect(assistant) - .optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant, SellerUpdateFields.Admin]); - - seller.admin = other2.address; - seller.assistant = other2.address; - - // Attempt to Create a seller with non-unique clerk, expecting revert - await expect( - accountHandler.connect(other2).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); - // Update seller admin - seller.clerk = clerk.address; seller.admin = other3.address; seller.assistant = assistant.address; @@ -681,13 +629,9 @@ describe("SellerHandler", function () { // Approve the update await accountHandler.connect(other3).optInToSellerUpdate(seller.id, [SellerUpdateFields.Admin]); - // Assistant and clerk are the same - await accountHandler - .connect(clerk) - .optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk, SellerUpdateFields.Assistant]); + await accountHandler.connect(assistant).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]); seller.assistant = other3.address; - seller.clerk = other3.address; // Attempt to Create a seller with non-unique admin, expecting revert await expect( @@ -699,12 +643,11 @@ describe("SellerHandler", function () { // Create a seller seller.admin = rando.address; seller.assistant = rando.address; - seller.clerk = rando.address; seller2 = mockSeller( authTokenOwner.address, ethers.constants.AddressZero, - authTokenOwner.address, + ethers.constants.AddressZero, authTokenOwner.address ); @@ -721,34 +664,6 @@ describe("SellerHandler", function () { await expect( accountHandler.connect(authTokenOwner).createSeller(seller2, authToken, voucherInitValues) ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); - - // Update seller assistant and clerk, so clerk matches authTokenOwner - seller.clerk = authTokenOwner.address; - seller.assistant = rando.address; - await accountHandler.connect(rando).updateSeller(seller, emptyAuthToken); - - // Approve the update - await accountHandler.connect(authTokenOwner).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk]); - await accountHandler.connect(rando).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]); - - // Attempt to Create a seller with non-unique clerk, expecting revert - await expect( - accountHandler.connect(authTokenOwner).createSeller(seller2, authToken, voucherInitValues) - ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); - - // Update the seller admin and clerk, so admin matches authTokenOwner - seller.admin = authTokenOwner.address; - seller.clerk = rando.address; - await accountHandler.connect(rando).updateSeller(seller, emptyAuthToken); - - // Approve the update - await accountHandler.connect(authTokenOwner).optInToSellerUpdate(seller.id, [SellerUpdateFields.Admin]); - await accountHandler.connect(rando).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk]); - - // 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); }); it("admin address is NOT zero address and AuthTokenType is NOT None", async function () { @@ -771,7 +686,6 @@ describe("SellerHandler", function () { // Set admin == zero address because seller will be created with auth token seller.admin = ethers.constants.AddressZero; seller.assistant = authTokenOwner.address; - seller.clerk = authTokenOwner.address; // Create a seller await accountHandler.connect(authTokenOwner).createSeller(seller, authToken, voucherInitValues); @@ -796,7 +710,6 @@ describe("SellerHandler", function () { it("Caller is not the supplied admin", async function () { seller.assistant = rando.address; - seller.clerk = rando.address; // Attempt to Create a seller with admin not the same to caller address await expect( @@ -808,7 +721,6 @@ describe("SellerHandler", function () { // Set admin == zero address because seller will be created with auth token seller.admin = ethers.constants.AddressZero; seller.assistant = rando.address; - seller.clerk = rando.address; // Attempt to Create a seller without owning the auth token await expect( @@ -818,28 +730,27 @@ describe("SellerHandler", function () { it("Caller is not the supplied assistant", async function () { seller.admin = rando.address; - seller.clerk = rando.address; // 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_AND_CLERK); + ).to.revertedWith(RevertReasons.NOT_ASSISTANT); }); - it("Caller is not the supplied clerk", async function () { + it("Clerk is not a zero address", async function () { seller.admin = rando.address; seller.assistant = rando.address; + seller.clerk = rando.address; // Attempt to Create a seller with clerk not the same to caller address await expect( accountHandler.connect(rando).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.NOT_ASSISTANT_AND_CLERK); + ).to.revertedWith(RevertReasons.CLERK_DEPRECATED); }); it("addresses are the zero address", async function () { seller.assistant = ethers.constants.AddressZero; seller.treasury = ethers.constants.AddressZero; - seller.clerk = ethers.constants.AddressZero; // Attempt to update a seller, expecting revert await expect( @@ -856,15 +767,6 @@ describe("SellerHandler", function () { ).to.revertedWith(RevertReasons.INVALID_ADDRESS); }); - it("Clerk address is zero address", async function () { - seller.clerk = ethers.constants.AddressZero; - - // Attempt to Create a seller with clerk == zero address - await expect( - accountHandler.connect(authTokenOwner).createSeller(seller, emptyAuthToken, voucherInitValues) - ).to.revertedWith(RevertReasons.INVALID_ADDRESS); - }); - it("Treasury address is zero address", async function () { seller.treasury = ethers.constants.AddressZero; @@ -892,7 +794,7 @@ describe("SellerHandler", function () { await accountHandler.connect(authTokenOwner).createSeller(seller, authToken, voucherInitValues); // Create a another seller - seller2 = mockSeller(other1.address, other1.address, other1.address, other1.address); + seller2 = mockSeller(other1.address, other1.address, ethers.constants.AddressZero, other1.address); expect(seller2.isValid()).is.true; await accountHandler.connect(other1).createSeller(seller2, emptyAuthToken, voucherInitValues); @@ -969,7 +871,7 @@ describe("SellerHandler", function () { await accountHandler.connect(authTokenOwner).createSeller(seller, authToken, voucherInitValues); // Create a another seller - seller2 = mockSeller(other1.address, other1.address, other1.address, other1.address); + seller2 = mockSeller(other1.address, other1.address, ethers.constants.AddressZero, other1.address); expect(seller2.isValid()).is.true; contractURI = `https://ipfs.io/ipfs/QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ`; @@ -1026,26 +928,6 @@ describe("SellerHandler", function () { } }); - it("should return the correct seller when searching on clerk address", async function () { - [exists, sellerStruct, authTokenStruct] = await accountHandler.connect(rando).getSellerByAddress(clerk.address); - - expect(exists).is.true; - - // Parse into entity - let returnedSeller = Seller.fromStruct(sellerStruct); - let returnedAuthToken = AuthToken.fromStruct(authTokenStruct); - - // Returned values should match the input in createSeller - for ([key, value] of Object.entries(seller)) { - expect(JSON.stringify(returnedSeller[key]) === JSON.stringify(value)).is.true; - } - - // Returned auth token values should match the input in createSeller - for ([key, value] of Object.entries(authToken)) { - expect(JSON.stringify(returnedAuthToken[key]) === JSON.stringify(value)).is.true; - } - }); - it("should return exists false and default values when searching on treasury address", async function () { [exists, sellerStruct, emptyAuthTokenStruct] = await accountHandler .connect(rando) @@ -1170,7 +1052,7 @@ describe("SellerHandler", function () { await accountHandler.connect(authTokenOwner).createSeller(seller, authToken, voucherInitValues); // Create seller 2 - seller2 = mockSeller(other1.address, other1.address, other1.address, other1.address); + seller2 = mockSeller(other1.address, other1.address, ethers.constants.AddressZero, other1.address); expect(seller2.isValid()).is.true; contractURI = `https://ipfs.io/ipfs/QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ`; @@ -1178,7 +1060,12 @@ describe("SellerHandler", function () { await accountHandler.connect(other1).createSeller(seller2, emptyAuthToken, voucherInitValues); // Create seller 3 - seller3 = mockSeller(other5.address, ethers.constants.AddressZero, other5.address, treasury.address); + seller3 = mockSeller( + other5.address, + ethers.constants.AddressZero, + ethers.constants.AddressZero, + treasury.address + ); expect(seller3.isValid()).is.true; contractURI = `https://ipfs.io/ipfs/QmPChd2hVbrJ6bfo3WBcTW4iZnpHm8TEzWkLHmLpXhF68A`; @@ -1238,7 +1125,12 @@ describe("SellerHandler", function () { expect(authToken3.isValid()).is.true; // Create seller 4 - seller4 = mockSeller(rando.address, ethers.constants.AddressZero, rando.address, treasury.address); + seller4 = mockSeller( + rando.address, + ethers.constants.AddressZero, + ethers.constants.AddressZero, + treasury.address + ); expect(seller4.isValid()).is.true; await mockAuthERC721Contract2.connect(rando).mint(authToken3.tokenId, 1); @@ -1289,7 +1181,12 @@ describe("SellerHandler", function () { expect(authToken3.isValid()).is.true; // Create seller 4 - seller4 = mockSeller(rando.address, ethers.constants.AddressZero, rando.address, treasury.address); + seller4 = mockSeller( + rando.address, + ethers.constants.AddressZero, + ethers.constants.AddressZero, + treasury.address + ); expect(seller4.isValid()).is.true; await mockAuthERC721Contract.connect(rando).mint(authToken3.tokenId, 1); @@ -1385,7 +1282,6 @@ describe("SellerHandler", function () { seller.admin = ethers.constants.AddressZero; seller.assistant = other1.address; - seller.clerk = other3.address; expect(seller.isValid()).is.true; pendingSellerUpdate = seller.clone(); @@ -1430,7 +1326,6 @@ describe("SellerHandler", function () { pendingSellerUpdate.assistant = ethers.constants.AddressZero; pendingSellerUpdateStruct = pendingSellerUpdate.toStruct(); - seller.clerk = clerk.address; seller.admin = admin.address; sellerStruct = seller.toStruct(); @@ -1467,26 +1362,6 @@ describe("SellerHandler", function () { pendingAuthTokenStruct, authTokenOwner.address ); - - tx = await accountHandler.connect(other3).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk]); - - pendingSellerUpdate.clerk = ethers.constants.AddressZero; - pendingSellerUpdateStruct = pendingSellerUpdate.toStruct(); - - seller.clerk = other3.address; - sellerStruct = seller.toStruct(); - - // Check clerk updated - await expect(tx) - .to.emit(accountHandler, "SellerUpdateApplied") - .withArgs( - seller.id, - sellerStruct, - pendingSellerUpdateStruct, - authTokenStruct, - pendingAuthTokenStruct, - other3.address - ); }); it("should only emit SellerUpdatePending event if no update has been immediately applied", async function () { @@ -1510,7 +1385,6 @@ describe("SellerHandler", function () { it("should update state of all fields except Id and active flag", async function () { seller.assistant = other1.address; seller.admin = ethers.constants.AddressZero; - seller.clerk = other3.address; seller.treasury = other4.address; seller.active = false; @@ -1525,9 +1399,6 @@ describe("SellerHandler", function () { // Approve assistant update await accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]); - // Approve clerk update - await accountHandler.connect(other3).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk]); - // Approve auth token update await accountHandler.connect(authTokenOwner).optInToSellerUpdate(seller.id, [SellerUpdateFields.AuthToken]); @@ -1555,9 +1426,6 @@ describe("SellerHandler", function () { [exists] = await accountHandler.connect(rando).getSellerByAddress(admin.address); expect(exists).to.be.false; - [exists] = await accountHandler.connect(rando).getSellerByAddress(clerk.address); - expect(exists).to.be.false; - //Check that new addresses are mapped. We don't map the treasury address. [exists] = await accountHandler.connect(rando).getSellerByAddress(seller.assistant); expect(exists).to.be.true; @@ -1566,9 +1434,6 @@ describe("SellerHandler", function () { [exists] = await accountHandler.connect(rando).getSellerByAddress(seller.admin); expect(exists).to.be.false; - [exists] = await accountHandler.connect(rando).getSellerByAddress(seller.clerk); - expect(exists).to.be.true; - // Voucher clone contract const bosonVoucherCloneAddress = calculateContractAddress(exchangeHandler.address, "1"); bosonVoucher = await ethers.getContractAt("OwnableUpgradeable", bosonVoucherCloneAddress); @@ -1577,10 +1442,15 @@ describe("SellerHandler", function () { }); it("should update state from auth token to empty auth token", async function () { - seller2 = mockSeller(other1.address, ethers.constants.AddressZero, other1.address, other1.address); + seller2 = mockSeller( + other1.address, + ethers.constants.AddressZero, + ethers.constants.AddressZero, + other1.address + ); expect(seller2.isValid()).is.true; - // msg.sender must be equal to seller's assistant and clerk + // msg.sender must be equal to seller's assistant await mockAuthERC721Contract.connect(authTokenOwner).transferFrom(authTokenOwner.address, other1.address, 8400); const newAuthTokenOwner = other1; @@ -1589,8 +1459,7 @@ describe("SellerHandler", function () { seller2.assistant = other5.address; seller2.admin = other6.address; - seller2.clerk = other7.address; - seller2.treasury = other8.address; + seller2.treasury = other7.address; seller2.active = false; //Update should not change id or active flag @@ -1607,9 +1476,6 @@ describe("SellerHandler", function () { // Approve admin update await accountHandler.connect(other6).optInToSellerUpdate(seller2.id, [SellerUpdateFields.Admin]); - // Approve clerk update - await accountHandler.connect(other7).optInToSellerUpdate(seller2.id, [SellerUpdateFields.Clerk]); - // Get the seller as a struct [, sellerStruct, authTokenStruct] = await accountHandler.connect(rando).getSeller(seller2.id); @@ -1644,9 +1510,6 @@ describe("SellerHandler", function () { [exists] = await accountHandler.connect(rando).getSellerByAddress(seller2.admin); expect(exists).to.be.true; - [exists] = await accountHandler.connect(rando).getSellerByAddress(seller2.clerk); - expect(exists).to.be.true; - // Voucher clone contract const bosonVoucherCloneAddress = calculateContractAddress(exchangeHandler.address, "1"); bosonVoucher = await ethers.getContractAt("OwnableUpgradeable", bosonVoucherCloneAddress); @@ -1655,10 +1518,15 @@ describe("SellerHandler", function () { }); it("should update state from auth token to new auth token", async function () { - seller2 = mockSeller(other1.address, ethers.constants.AddressZero, other1.address, other1.address); + seller2 = mockSeller( + other1.address, + ethers.constants.AddressZero, + ethers.constants.AddressZero, + other1.address + ); expect(seller2.isValid()).is.true; - // msg.sender must be equal to seller's assistant and clerk + // msg.sender must be equal to seller's assistant await mockAuthERC721Contract.connect(authTokenOwner).transferFrom(authTokenOwner.address, other1.address, 8400); const newAuthTokenOwner = other1; @@ -1667,8 +1535,7 @@ describe("SellerHandler", function () { seller2.assistant = other5.address; seller2.admin = ethers.constants.AddressZero; - seller2.clerk = other7.address; - seller2.treasury = other8.address; + seller2.treasury = other7.address; seller2.active = false; await mockAuthERC721Contract2.connect(newAuthTokenOwner).mint(0, 1); @@ -1685,7 +1552,6 @@ describe("SellerHandler", function () { await accountHandler.connect(newAuthTokenOwner).updateSeller(seller2, authToken2); await accountHandler.connect(other5).optInToSellerUpdate(seller2.id, [SellerUpdateFields.Assistant]); - await accountHandler.connect(other7).optInToSellerUpdate(seller2.id, [SellerUpdateFields.Clerk]); await accountHandler.connect(newAuthTokenOwner).optInToSellerUpdate(seller2.id, [SellerUpdateFields.AuthToken]); // Get the seller as a struct @@ -1722,9 +1588,6 @@ describe("SellerHandler", function () { [exists] = await accountHandler.connect(rando).getSellerByAddress(seller2.admin); expect(exists).to.be.false; - [exists] = await accountHandler.connect(rando).getSellerByAddress(seller2.clerk); - expect(exists).to.be.true; - // Voucher clone contract const bosonVoucherCloneAddress = calculateContractAddress(exchangeHandler.address, "1"); bosonVoucher = await ethers.getContractAt("OwnableUpgradeable", bosonVoucherCloneAddress); @@ -1763,12 +1626,17 @@ describe("SellerHandler", function () { it("should update the correct seller", async function () { // Configure another seller - seller2 = mockSeller(other1.address, ethers.constants.AddressZero, other1.address, other1.address); + seller2 = mockSeller( + other1.address, + ethers.constants.AddressZero, + ethers.constants.AddressZero, + other1.address + ); expect(seller2.isValid()).is.true; contractURI = `https://ipfs.io/ipfs/QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ`; - // msg.sender must be equal to seller's assistant and clerk + // msg.sender must be equal to seller's assistant let authTokenOwner = other1; await mockAuthERC721Contract.connect(authTokenOwner).mint(8500, 1); @@ -1781,7 +1649,6 @@ describe("SellerHandler", function () { //Update seller2 seller2.assistant = rando.address; seller2.admin = ethers.constants.AddressZero; - seller2.clerk = rando.address; seller2.treasury = rando.address; seller2.active = false; @@ -1797,9 +1664,7 @@ describe("SellerHandler", function () { await accountHandler.connect(authTokenOwner).updateSeller(seller2, authToken2); // Approve update - await accountHandler - .connect(rando) - .optInToSellerUpdate(seller2.id, [SellerUpdateFields.Assistant, SellerUpdateFields.Clerk]); + await accountHandler.connect(rando).optInToSellerUpdate(seller2.id, [SellerUpdateFields.Assistant]); // Approve auth token update authTokenOwner = assistant; @@ -1971,7 +1836,6 @@ describe("SellerHandler", function () { seller.assistant = other1.address; seller.admin = other1.address; - seller.clerk = other1.address; pendingSellerUpdate = seller.clone(); pendingSellerUpdate.active = false; @@ -1994,11 +1858,7 @@ describe("SellerHandler", function () { // Approve update await accountHandler .connect(other1) - .optInToSellerUpdate(seller.id, [ - SellerUpdateFields.Assistant, - SellerUpdateFields.Admin, - SellerUpdateFields.Clerk, - ]); + .optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant, SellerUpdateFields.Admin]); // Make sure seller treasury didn't change [, sellerStruct, authTokenStruct] = await accountHandler.connect(rando).getSeller(seller.id); @@ -2018,19 +1878,18 @@ describe("SellerHandler", function () { expect(returnedSeller2.treasury).to.equal(treasury.address); }); - it("should be possible to use the same address for assistant, admin, clerk, and treasury", async function () { + it("should be possible to use the same address for assistant, admin and treasury", async function () { // Only treasury doesn't need owner approval and will be updated immediately seller.treasury = other1.address; sellerStruct = seller.toStruct(); seller.assistant = other1.address; seller.admin = other1.address; - seller.clerk = other1.address; // Update seller const tx = await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); - // Pending seller is filled with only admin, clerk, and assistant addresses + // Pending seller is filled with only admin and assistant addresses pendingSellerUpdate = seller.clone(); pendingSellerUpdate.id = "0"; pendingSellerUpdate.active = false; @@ -2066,11 +1925,7 @@ describe("SellerHandler", function () { await expect( await accountHandler .connect(other1) - .optInToSellerUpdate(seller.id, [ - SellerUpdateFields.Assistant, - SellerUpdateFields.Admin, - SellerUpdateFields.Clerk, - ]) + .optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant, SellerUpdateFields.Admin]) ) .to.emit(accountHandler, "SellerUpdateApplied") .withArgs( @@ -2122,7 +1977,6 @@ describe("SellerHandler", function () { it("addresses are the zero address", async function () { seller.assistant = ethers.constants.AddressZero; seller.treasury = ethers.constants.AddressZero; - seller.clerk = ethers.constants.AddressZero; // Attempt to update a seller, expecting revert await expect(accountHandler.connect(authTokenOwner).updateSeller(seller, emptyAuthToken)).to.revertedWith( @@ -2139,12 +1993,12 @@ describe("SellerHandler", function () { ); }); - it("Clerk is the zero address", async function () { - seller.clerk = ethers.constants.AddressZero; + it("Clerk is not a zero address", async function () { + seller.clerk = rando.address; // Attempt to update a seller, expecting revert await expect(accountHandler.connect(authTokenOwner).updateSeller(seller, emptyAuthToken)).to.revertedWith( - RevertReasons.INVALID_ADDRESS + RevertReasons.CLERK_DEPRECATED ); }); @@ -2161,7 +2015,6 @@ describe("SellerHandler", function () { seller.id = accountId.next().value; seller.assistant = other1.address; seller.admin = other1.address; - seller.clerk = other1.address; seller.treasury = other1.address; seller.active = true; sellerStruct = seller.toStruct(); @@ -2187,21 +2040,12 @@ describe("SellerHandler", function () { await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWith( RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE ); - - seller.clerk = clerk.address; //already being used by seller 1 - seller.admin = other1.address; - - // Attempt to Update a seller with non-unique clerk, expecting revert - await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWith( - RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE - ); }); it("addresses are not unique to this seller Id when address used for different role", async function () { seller.id = accountId.next().value; seller.assistant = other1.address; seller.admin = other1.address; - seller.clerk = other1.address; seller.treasury = other1.address; seller.active = true; sellerStruct = seller.toStruct(); @@ -2220,23 +2064,14 @@ describe("SellerHandler", function () { RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE ); - //Set seller 2's assistant address to seller 1's clerk address + //Set seller 2's assistant address to seller 1's admin address seller.admin = other1.address; - seller.assistant = clerk.address; + seller.assistant = admin.address; // Attempt to update a seller with non-unique admin, expecting revert await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWith( RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE ); - - //Set seller 2's clerk address to seller 1's admin address - seller.assistant = other1.address; - seller.clerk = admin.address; - - // Attempt to Update a seller with non-unique clerk, expecting revert - await expect(accountHandler.connect(other1).updateSeller(seller, emptyAuthToken)).to.revertedWith( - RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE - ); }); it("admin address is NOT zero address and AuthTokenType is NOT None", async function () { @@ -2265,7 +2100,7 @@ describe("SellerHandler", function () { await accountHandler.connect(authTokenOwner).optInToSellerUpdate(seller.id, [SellerUpdateFields.AuthToken]); //Set seller 2's auth token to empty - seller2 = mockSeller(other1.address, other1.address, other1.address, other1.address); + seller2 = mockSeller(other1.address, other1.address, ethers.constants.AddressZero, other1.address); expect(seller2.isValid()).is.true; // Create a seller with auth token @@ -2294,7 +2129,12 @@ describe("SellerHandler", function () { it("seller is not owner of auth token currently stored for seller", async function () { const authTokenOwner = other1; //Create seller 2 with auth token - seller2 = mockSeller(other1.address, ethers.constants.AddressZero, other1.address, other1.address); + seller2 = mockSeller( + other1.address, + ethers.constants.AddressZero, + ethers.constants.AddressZero, + other1.address + ); expect(seller2.isValid()).is.true; //Create auth token for token Id that seller does not own @@ -2307,7 +2147,7 @@ describe("SellerHandler", function () { await accountHandler.connect(authTokenOwner).createSeller(seller2, authToken2, voucherInitValues); //Transfer the token to a different address - await mockAuthERC721Contract2.connect(authTokenOwner).transferFrom(authTokenOwner.address, other8.address, 0); + await mockAuthERC721Contract2.connect(authTokenOwner).transferFrom(authTokenOwner.address, other7.address, 0); // Attempt to update seller2 for token that seller doesn't own await expect(accountHandler.connect(authTokenOwner).updateSeller(seller2, authToken2)).to.revertedWith( @@ -2319,7 +2159,12 @@ describe("SellerHandler", function () { const authTokenOwner = other1; //Create seller 2 with auth token - seller2 = mockSeller(other1.address, ethers.constants.AddressZero, other1.address, other1.address); + seller2 = mockSeller( + other1.address, + ethers.constants.AddressZero, + ethers.constants.AddressZero, + other1.address + ); expect(seller2.isValid()).is.true; //Create auth token for token Id that seller does not own @@ -2391,26 +2236,7 @@ describe("SellerHandler", function () { ); }); - it("New clerk should opt-in to update seller", async function () { - seller.clerk = other1.address; - sellerStruct = seller.toStruct(); - - await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); - - await expect(accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk])) - .to.emit(accountHandler, "SellerUpdateApplied") - .withArgs( - seller.id, - sellerStruct, - pendingSellerUpdateStruct, - emptyAuthTokenStruct, - emptyAuthTokenStruct, - other1.address - ); - }); - - it("Should update admin, clerk and assistant in a single call ", async function () { - seller.clerk = other1.address; + it("Should update admin and assistant in a single call ", async function () { seller.admin = other1.address; seller.assistant = other1.address; sellerStruct = seller.toStruct(); @@ -2420,11 +2246,7 @@ describe("SellerHandler", function () { await expect( accountHandler .connect(other1) - .optInToSellerUpdate(seller.id, [ - SellerUpdateFields.Clerk, - SellerUpdateFields.Admin, - SellerUpdateFields.Assistant, - ]) + .optInToSellerUpdate(seller.id, [SellerUpdateFields.Admin, SellerUpdateFields.Assistant]) ) .to.emit(accountHandler, "SellerUpdateApplied") .withArgs( @@ -2437,10 +2259,9 @@ describe("SellerHandler", function () { ); }); - it("Should update assistant, clerk and auth token in a single call when addresses are the same ", async function () { + it("Should update assistant and auth token in a single call when addresses are the same ", async function () { seller.admin = ethers.constants.AddressZero; seller.assistant = authTokenOwner.address; - seller.clerk = authTokenOwner.address; sellerStruct = seller.toStruct(); await accountHandler.connect(admin).updateSeller(seller, authToken); @@ -2448,11 +2269,7 @@ describe("SellerHandler", function () { await expect( accountHandler .connect(authTokenOwner) - .optInToSellerUpdate(seller.id, [ - SellerUpdateFields.Assistant, - SellerUpdateFields.Clerk, - SellerUpdateFields.AuthToken, - ]) + .optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant, SellerUpdateFields.AuthToken]) ) .to.emit(accountHandler, "SellerUpdateApplied") .withArgs( @@ -2605,13 +2422,12 @@ describe("SellerHandler", function () { await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); await expect( - accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk]) + accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Admin]) ).to.not.emit(accountHandler, "SellerUpdateApplied"); }); context("💔 Revert Reasons", async function () { it("There are no pending updates", async function () { - seller.clerk = other1.address; seller.admin = other1.address; seller.assistant = other1.address; sellerStruct = seller.toStruct(); @@ -2622,11 +2438,7 @@ describe("SellerHandler", function () { await expect( accountHandler .connect(other1) - .optInToSellerUpdate(seller.id, [ - SellerUpdateFields.Clerk, - SellerUpdateFields.Admin, - SellerUpdateFields.Assistant, - ]) + .optInToSellerUpdate(seller.id, [SellerUpdateFields.Admin, SellerUpdateFields.Assistant]) ) .to.emit(accountHandler, "SellerUpdateApplied") .withArgs( @@ -2658,7 +2470,7 @@ describe("SellerHandler", function () { seller2 = mockSeller( newAuthTokenOwner.address, ethers.constants.AddressZero, - newAuthTokenOwner.address, + ethers.constants.AddressZero, newAuthTokenOwner.address ); expect(seller2.isValid()).is.true; @@ -2674,7 +2486,6 @@ describe("SellerHandler", function () { it("Caller is not the new admin", async function () { seller.admin = other1.address; - sellerStruct = seller.toStruct(); await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); @@ -2683,20 +2494,8 @@ describe("SellerHandler", function () { ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); }); - it("Caller is not the new clerk", async function () { - seller.clerk = other1.address; - sellerStruct = seller.toStruct(); - - await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); - - await expect( - accountHandler.connect(other2).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk]) - ).to.revertedWith(RevertReasons.UNAUTHORIZED_CALLER_UPDATE); - }); - it("Caller is not the new assistant", async function () { seller.assistant = other1.address; - sellerStruct = seller.toStruct(); await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); @@ -2707,7 +2506,6 @@ describe("SellerHandler", function () { it("Should revert if the caller is not the new auth token owner", async function () { seller.admin = ethers.constants.AddressZero; - sellerStruct = seller.toStruct(); await accountHandler.connect(admin).updateSeller(seller, authToken); @@ -2735,49 +2533,42 @@ describe("SellerHandler", function () { await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); // Create seller with same admin - seller2 = mockSeller(other1.address, other1.address, other1.address, other1.address); + seller2 = mockSeller(other1.address, other1.address, ethers.constants.AddressZero, other1.address); expect(seller2.isValid()).is.true; await accountHandler.connect(other1).createSeller(seller2, emptyAuthToken, voucherInitValues); - // Attemp to approve the update with non-unique admin, expecting revert + // 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); }); - it("Clerk is not unique to this seller", async function () { - // Update seller clerk - seller.clerk = other1.address; + it("Assistant is not unique to this seller", async function () { + // Update seller assistant + seller.assistant = other1.address; await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); - // Create seller with same clerk - seller2 = mockSeller(other1.address, other1.address, other1.address, other1.address); + // Create seller with same assistant + seller2 = mockSeller(other1.address, other1.address, ethers.constants.AddressZero, other1.address); expect(seller2.isValid()).is.true; await accountHandler.connect(other1).createSeller(seller2, emptyAuthToken, voucherInitValues); - // Attemp to approve the update with non-unique clerk, expecting revert + // Attempt to approve the update with non-unique assistant, expecting revert await expect( - accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk]) + accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]) ).to.revertedWith(RevertReasons.SELLER_ADDRESS_MUST_BE_UNIQUE); }); - it("Assistant is not unique to this seller", async function () { - // Update seller assistant + it("Seller tries to update the clerk", async function () { seller.assistant = other1.address; - await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); - - // Create seller with same assistant - seller2 = mockSeller(other1.address, other1.address, other1.address, other1.address); - expect(seller2.isValid()).is.true; - await accountHandler.connect(other1).createSeller(seller2, emptyAuthToken, voucherInitValues); + await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); - // Attemp 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); + accountHandler.connect(other2).optInToSellerUpdate(seller.id, [SellerUpdateFields.Clerk]) + ).to.revertedWith(RevertReasons.CLERK_DEPRECATED); }); }); }); diff --git a/test/protocol/TwinHandlerTest.js b/test/protocol/TwinHandlerTest.js index 7217a8a3d..6bb404c33 100644 --- a/test/protocol/TwinHandlerTest.js +++ b/test/protocol/TwinHandlerTest.js @@ -62,7 +62,8 @@ describe("IBosonTwinHandler", function () { } = await setupTestEnvironment(contracts)); // make all account the same - assistant = clerk = admin; + assistant = admin; + clerk = { address: ethers.constants.AddressZero }; // Deploy the mock tokens [bosonToken, foreign721, foreign1155, fallbackError] = await deployMockTokens(); @@ -770,7 +771,7 @@ describe("IBosonTwinHandler", function () { context("👉 getNextTwinId()", async function () { beforeEach(async function () { // Create another valid seller. - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); expect(seller.isValid()).is.true; // AuthToken diff --git a/test/protocol/clients/BosonVoucherTest.js b/test/protocol/clients/BosonVoucherTest.js index e49eb68d4..b4b9e9894 100644 --- a/test/protocol/clients/BosonVoucherTest.js +++ b/test/protocol/clients/BosonVoucherTest.js @@ -92,8 +92,9 @@ describe("IBosonVoucher", function () { })); // make all account the same - assistant = clerk = admin; - assistantDR = clerkDR = adminDR; + assistant = admin; + assistantDR = adminDR; + clerk = clerkDR = { address: ethers.constants.AddressZero }; [deployer] = await ethers.getSigners(); // Grant protocol role to eoa so it's easier to test @@ -2267,7 +2268,7 @@ describe("IBosonVoucher", function () { voucherInitValues = new VoucherInitValues("ContractURI", royaltyPercentage); // create another seller - seller = mockSeller(rando.address, rando.address, rando.address, rando.address); + seller = mockSeller(rando.address, rando.address, ethers.constants.AddressZero, rando.address); seller.id = "2"; // royalty percentage too high, expectig revert diff --git a/test/upgrade/clients/BosonVoucher-2.1.0-2.2.0.js b/test/upgrade/clients/BosonVoucher-2.1.0-2.2.0.js index d49508d64..d2449bf2b 100644 --- a/test/upgrade/clients/BosonVoucher-2.1.0-2.2.0.js +++ b/test/upgrade/clients/BosonVoucher-2.1.0-2.2.0.js @@ -157,7 +157,13 @@ describe("[@skip-on-coverage] After client upgrade, everything is still operatio beforeEach(async function () { // Create a seller sellerId = await accountHandler.getNextAccountId(); - const seller = mockSeller(assistant.address, assistant.address, assistant.address, assistant.address, true); + const seller = mockSeller( + assistant.address, + assistant.address, + ethers.constants.AddressZero, + assistant.address, + true + ); const voucherInitValues = mockVoucherInitValues(); const emptyAuthToken = mockAuthToken(); await accountHandler.connect(assistant).createSeller(seller, emptyAuthToken, voucherInitValues); diff --git a/test/util/upgrade.js b/test/util/upgrade.js index 6645eb007..9979ef44c 100644 --- a/test/util/upgrade.js +++ b/test/util/upgrade.js @@ -49,6 +49,7 @@ const { tagsByVersion } = require("../upgrade/00_config"); // Common vars const versionsWithActivateDRFunction = ["v2.0.0", "v2.1.0"]; +const versionsWithClerkRole = ["v2.0.0", "v2.1.0", "v2.2.0", "v2.2.1"]; let rando; let preUpgradeInterfaceIds, preUpgradeVersions; let facets, versionTags; @@ -340,10 +341,13 @@ async function populateProtocolContract( // create entities switch (entity) { case entityType.DR: { + const clerkAddress = versionsWithClerkRole.includes(isBefore ? versionTags.oldVersion : versionTags.newVersion) + ? wallet.address + : ethers.constants.AddressZero; const disputeResolver = mockDisputeResolver( wallet.address, wallet.address, - wallet.address, + clerkAddress, wallet.address, true, true @@ -374,7 +378,10 @@ async function populateProtocolContract( } case entityType.SELLER: { - const seller = mockSeller(wallet.address, wallet.address, wallet.address, wallet.address, true); + const clerkAddress = versionsWithClerkRole.includes(isBefore ? versionTags.oldVersion : versionTags.newVersion) + ? wallet.address + : ethers.constants.AddressZero; + const seller = mockSeller(wallet.address, wallet.address, clerkAddress, wallet.address, true); const id = (seller.id = nextAccountId.toString()); let authToken;