diff --git a/contracts/interfaces/events/IBosonConfigEvents.sol b/contracts/interfaces/events/IBosonConfigEvents.sol index 626201afc..03e3ce8d5 100644 --- a/contracts/interfaces/events/IBosonConfigEvents.sol +++ b/contracts/interfaces/events/IBosonConfigEvents.sol @@ -15,16 +15,7 @@ interface IBosonConfigEvents { event BeaconProxyAddressChanged(address indexed beaconProxyAddress, address indexed executedBy); event ProtocolFeePercentageChanged(uint256 feePercentage, address indexed executedBy); event ProtocolFeeFlatBosonChanged(uint256 feeFlatBoson, address indexed executedBy); - event MaxExchangesPerBatchChanged(uint16 maxExchangesPerBatch, address indexed executedBy); - event MaxOffersPerGroupChanged(uint16 maxOffersPerGroup, address indexed executedBy); - event MaxOffersPerBatchChanged(uint16 maxOffersPerBatch, address indexed executedBy); - event MaxTwinsPerBundleChanged(uint16 maxTwinsPerBundle, address indexed executedBy); - event MaxOffersPerBundleChanged(uint16 maxOffersPerBundle, address indexed executedBy); - event MaxTokensPerWithdrawalChanged(uint16 maxTokensPerWithdrawal, address indexed executedBy); - event MaxFeesPerDisputeResolverChanged(uint16 maxFeesPerDisputeResolver, address indexed executedBy); event MaxEscalationResponsePeriodChanged(uint256 maxEscalationResponsePeriod, address indexed executedBy); - event MaxDisputesPerBatchChanged(uint16 maxDisputesPerBatch, address indexed executedBy); - event MaxAllowedSellersChanged(uint16 maxAllowedSellers, address indexed executedBy); event BuyerEscalationFeePercentageChanged(uint256 buyerEscalationFeePercentage, address indexed executedBy); event AuthTokenContractChanged( BosonTypes.AuthTokenType indexed authTokenType, @@ -35,6 +26,5 @@ interface IBosonConfigEvents { event MaxRoyaltyPercentageChanged(uint16 maxRoyaltyPecentage, address indexed executedBy); event MaxResolutionPeriodChanged(uint256 maxResolutionPeriod, address indexed executedBy); event MinDisputePeriodChanged(uint256 minDisputePeriod, address indexed executedBy); - event MaxPremintedVouchersChanged(uint256 maxPremintedVouchers, address indexed executedBy); event AccessControllerAddressChanged(address indexed accessControllerAddress, address indexed executedBy); } diff --git a/contracts/interfaces/handlers/IBosonConfigHandler.sol b/contracts/interfaces/handlers/IBosonConfigHandler.sol index 056832cac..7130fc714 100644 --- a/contracts/interfaces/handlers/IBosonConfigHandler.sol +++ b/contracts/interfaces/handlers/IBosonConfigHandler.sol @@ -134,126 +134,6 @@ interface IBosonConfigHandler is IBosonConfigEvents { */ function getProtocolFeeFlatBoson() external view returns (uint256); - /** - * @notice Sets the maximum numbers of offers that can be created in a single transaction. - * - * Emits a MaxOffersPerBatchChanged event. - * - * Reverts if _maxOffersPerBatch is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxOffersPerBatch - the maximum length of {BosonTypes.Offer[]} - */ - function setMaxOffersPerBatch(uint16 _maxOffersPerBatch) external; - - /** - * @notice Gets the maximum numbers of offers that can be created in a single transaction. - * - * @return the maximum numbers of offers that can be created in a single transaction - */ - function getMaxOffersPerBatch() external view returns (uint16); - - /** - * @notice Sets the maximum numbers of offers that can be added to a group in a single transaction. - * - * Emits a MaxOffersPerGroupChanged event. - * - * Reverts if _maxOffersPerGroup is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxOffersPerGroup - the maximum length of {BosonTypes.Group.offerIds} - */ - function setMaxOffersPerGroup(uint16 _maxOffersPerGroup) external; - - /** - * @notice Gets the maximum numbers of offers that can be added to a group in a single transaction. - * - * @return the maximum numbers of offers that can be added to a group in a single transaction - */ - function getMaxOffersPerGroup() external view returns (uint16); - - /** - * @notice Sets the maximum numbers of twins that can be added to a bundle in a single transaction. - * - * Emits a MaxTwinsPerBundleChanged event. - * - * Reverts if _maxTwinsPerBundle is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxTwinsPerBundle - the maximum length of {BosonTypes.Bundle.twinIds} - */ - function setMaxTwinsPerBundle(uint16 _maxTwinsPerBundle) external; - - /** - * @notice Gets the maximum numbers of twins that can be added to a bundle in a single transaction. - * - * @return the maximum numbers of twins that can be added to a bundle in a single transaction. - */ - function getMaxTwinsPerBundle() external view returns (uint16); - - /** - * @notice Sets the maximum numbers of offers that can be added to a bundle in a single transaction. - * - * Emits a MaxOffersPerBundleChanged event. - * - * Reverts if _maxOffersPerBundle is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxOffersPerBundle - the maximum length of {BosonTypes.Bundle.offerIds} - */ - function setMaxOffersPerBundle(uint16 _maxOffersPerBundle) external; - - /** - * @notice Gets the maximum numbers of offers that can be added to a bundle in a single transaction. - * - * @return the maximum numbers of offers that can be added to a bundle in a single transaction - */ - function getMaxOffersPerBundle() external view returns (uint16); - - /** - * @notice Sets the maximum numbers of tokens that can be withdrawn in a single transaction. - * - * Emits a MaxTokensPerWithdrawalChanged event. - * - * Reverts if _maxTokensPerWithdrawal is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxTokensPerWithdrawal - the maximum length of token list when calling {FundsHandlerFacet.withdraw} - */ - function setMaxTokensPerWithdrawal(uint16 _maxTokensPerWithdrawal) external; - - /** - * @notice Gets the maximum numbers of tokens that can be withdrawn in a single transaction. - * - * @return the maximum length of token list when calling {FundsHandlerFacet.withdraw} - */ - function getMaxTokensPerWithdrawal() external view returns (uint16); - - /** - * @notice Sets the maximum number of dispute resolver fee structs that can be processed in a single transaction. - * - * Emits a MaxFeesPerDisputeResolverChanged event. - * - * Reverts if _maxFeesPerDisputeResolver is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxFeesPerDisputeResolver - the maximum length of dispute resolver fees list when calling {AccountHandlerFacet.createDisputeResolver} or {AccountHandlerFacet.updateDisputeResolver} - */ - function setMaxFeesPerDisputeResolver(uint16 _maxFeesPerDisputeResolver) external; - - /** - * @notice Gets the maximum number of dispute resolver fee structs that can be processed in a single transaction. - * - * @return the maximum number of dispute resolver fee structs that can be processed in a single transaction - */ - function getMaxFeesPerDisputeResolver() external view returns (uint16); - /** * @notice Sets the maximum escalation response period a dispute resolver can specify. * @@ -274,26 +154,6 @@ interface IBosonConfigHandler is IBosonConfigEvents { */ function getMaxEscalationResponsePeriod() external view returns (uint256); - /** - * @notice Sets the maximum number of disputes that can be expired in a single transaction. - * - * Emits a MaxDisputesPerBatchChanged event. - * - * Reverts if _maxDisputesPerBatch is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxDisputesPerBatch - the maximum number of disputes that can be expired - */ - function setMaxDisputesPerBatch(uint16 _maxDisputesPerBatch) external; - - /** - * @notice Gets the maximum number of disputes that can be expired in a single transaction. - * - * @return the maximum number of disputes that can be expired - */ - function getMaxDisputesPerBatch() external view returns (uint16); - /** * @notice Sets the total offer fee percentage limit which will validate the sum of (Protocol Fee percentage + Agent Fee percentage) of an offer fee. * @@ -317,26 +177,6 @@ interface IBosonConfigHandler is IBosonConfigEvents { */ function getMaxTotalOfferFeePercentage() external view returns (uint16); - /** - * @notice Sets the maximum number of seller ids that can be added to or removed from dispute resolver seller allow list in a single transaction. - * - * Emits a MaxAllowedSellersChanged event. - * - * Reverts if _maxAllowedSellers is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxAllowedSellers - the maximum number of seller ids that can be added or removed - */ - function setMaxAllowedSellers(uint16 _maxAllowedSellers) external; - - /** - * @notice Gets the maximum number of seller ids that can be added to or removed from dispute resolver seller allow list in a single transaction. - * - * @return the maximum number of seller ids that can be added or removed - */ - function getMaxAllowedSellers() external view returns (uint16); - /** * @notice Sets the buyer escalation fee percentage. * @@ -384,26 +224,6 @@ interface IBosonConfigHandler is IBosonConfigEvents { */ function getAuthTokenContract(BosonTypes.AuthTokenType _authTokenType) external view returns (address); - /** - * @notice Sets the maximum number of exchanges that can be created in a single transaction. - * - * Emits a MaxExchangesPerBatchChanged event. - * - * Reverts if _maxExchangesPerBatch is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxExchangesPerBatch - the maximum length of {BosonTypes.Exchange[]} - */ - function setMaxExchangesPerBatch(uint16 _maxExchangesPerBatch) external; - - /** - * @notice Gets the maximum number of exchanges that can be created in a single transaction. - * - * @return the maximum length of {BosonTypes.Exchange[]} - */ - function getMaxExchangesPerBatch() external view returns (uint16); - /** * @notice Sets the maximum royalty percentage that can be set by the seller. * @@ -465,22 +285,6 @@ interface IBosonConfigHandler is IBosonConfigEvents { */ function getMinDisputePeriod() external view returns (uint256); - /** - * @notice Sets the maximum number of vouchers that can be preminted in a single transaction. - * - * Emits a MaxPremintedVouchersChanged event if successful. - * - * Reverts if the _maxPremintedVouchers is zero. - * - * @param _maxPremintedVouchers - the maximum number of vouchers - */ - function setMaxPremintedVouchers(uint256 _maxPremintedVouchers) external; - - /** - * @notice Gets the maximum number of vouchers that can be preminted in a single transaction. - */ - function getMaxPremintedVouchers() external view returns (uint256); - /** * @notice Sets the access controller address. * diff --git a/contracts/protocol/bases/BundleBase.sol b/contracts/protocol/bases/BundleBase.sol index 7b63f161a..892a648e2 100644 --- a/contracts/protocol/bases/BundleBase.sol +++ b/contracts/protocol/bases/BundleBase.sol @@ -24,10 +24,8 @@ contract BundleBase is ProtocolBase, IBosonBundleEvents { * - Any of the offers belongs to different seller * - Any of the offers does not exist * - Offer exists in a different bundle - * - Number of offers exceeds maximum allowed number per bundle * - Any of the twins belongs to different seller * - Any of the twins does not exist - * - Number of twins exceeds maximum allowed number per bundle * - Duplicate twins added in same bundle * - Exchange already exists for the offer id in bundle * - Offers' total quantity is greater than twin supply when token is nonfungible @@ -38,7 +36,6 @@ contract BundleBase is ProtocolBase, IBosonBundleEvents { function createBundleInternal(Bundle memory _bundle) internal { // Cache protocol lookups and limits for reference ProtocolLib.ProtocolLookups storage lookups = protocolLookups(); - ProtocolLib.ProtocolLimits storage limits = protocolLimits(); // get message sender address sender = msgSender(); @@ -53,12 +50,6 @@ contract BundleBase is ProtocolBase, IBosonBundleEvents { BUNDLE_REQUIRES_AT_LEAST_ONE_TWIN_AND_ONE_OFFER ); - // limit maximum number of offers to avoid running into block gas limit in a loop - require(_bundle.offerIds.length <= limits.maxOffersPerBundle, TOO_MANY_OFFERS); - - // limit maximum number of twins to avoid running into block gas limit in a loop - require(_bundle.twinIds.length <= limits.maxTwinsPerBundle, TOO_MANY_TWINS); - // Get the next bundle and increment the counter uint256 bundleId = protocolCounters().nextBundleId++; // Sum of offers quantity available diff --git a/contracts/protocol/clients/voucher/BosonVoucher.sol b/contracts/protocol/clients/voucher/BosonVoucher.sol index 3ea7bab82..7e2e14461 100644 --- a/contracts/protocol/clients/voucher/BosonVoucher.sol +++ b/contracts/protocol/clients/voucher/BosonVoucher.sol @@ -200,7 +200,6 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable * Reverts if: * - Offer id is not associated with a range * - Amount to mint is more than remaining un-minted in range - * - Too many to mint in a single transaction, given current block gas limit * - Offer already expired * - Offer is voided * @@ -217,13 +216,6 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable // Revert if no more to mint in range require(range.length >= range.minted + _amount, INVALID_AMOUNT_TO_MINT); - // Get max amount that can be minted in a single transaction - address protocolDiamond = IClientExternalAddresses(BeaconClientLib._beacon()).getProtocolAddress(); - uint256 maxPremintedVouchers = IBosonConfigHandler(protocolDiamond).getMaxPremintedVouchers(); - - // Revert if too many to mint in a single transaction - require(_amount <= maxPremintedVouchers, TOO_MANY_TO_MINT); - // Make sure that offer is not expired or voided (Offer memory offer, OfferDates memory offerDates) = getBosonOffer(_offerId); require(!offer.voided && (offerDates.validUntil > block.timestamp), OFFER_EXPIRED_OR_VOIDED); @@ -283,10 +275,6 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable (Offer memory offer, OfferDates memory offerDates) = getBosonOffer(_offerId); require(offer.voided || (offerDates.validUntil <= block.timestamp), OFFER_STILL_VALID); - // Get max amount that can be burned in a single transaction - address protocolDiamond = IClientExternalAddresses(BeaconClientLib._beacon()).getProtocolAddress(); - uint256 maxPremintedVouchers = IBosonConfigHandler(protocolDiamond).getMaxPremintedVouchers(); - // Get the first token to burn uint256 start = (range.lastBurnedTokenId == 0) ? range.start : (range.lastBurnedTokenId + 1); @@ -296,11 +284,6 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable // End should be greater than start require(end > start, NOTHING_TO_BURN); - // If amount to burn is more than maxPremintedVouchers, burn only maxPremintedVouchers - if (end > start + maxPremintedVouchers) { - end = start + maxPremintedVouchers; - } - // Burn the range address rangeOwner = range.owner; uint256 burned; diff --git a/contracts/protocol/facets/ConfigHandlerFacet.sol b/contracts/protocol/facets/ConfigHandlerFacet.sol index 1a0ab5d07..92630491b 100644 --- a/contracts/protocol/facets/ConfigHandlerFacet.sol +++ b/contracts/protocol/facets/ConfigHandlerFacet.sol @@ -38,22 +38,11 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { setBeaconProxyAddress(_addresses.beaconProxy); setProtocolFeePercentage(_fees.percentage); setProtocolFeeFlatBoson(_fees.flatBoson); - setMaxExchangesPerBatch(_limits.maxExchangesPerBatch); - setMaxOffersPerGroup(_limits.maxOffersPerGroup); - setMaxTwinsPerBundle(_limits.maxTwinsPerBundle); - setMaxOffersPerBundle(_limits.maxOffersPerBundle); - setMaxOffersPerBatch(_limits.maxOffersPerBatch); - setMaxTokensPerWithdrawal(_limits.maxTokensPerWithdrawal); - setMaxFeesPerDisputeResolver(_limits.maxFeesPerDisputeResolver); - setMaxEscalationResponsePeriod(_limits.maxEscalationResponsePeriod); - setMaxDisputesPerBatch(_limits.maxDisputesPerBatch); - setMaxAllowedSellers(_limits.maxAllowedSellers); setBuyerEscalationDepositPercentage(_fees.buyerEscalationDepositPercentage); setMaxTotalOfferFeePercentage(_limits.maxTotalOfferFeePercentage); setMaxRoyaltyPecentage(_limits.maxRoyaltyPecentage); setMaxResolutionPeriod(_limits.maxResolutionPeriod); setMinDisputePeriod(_limits.minDisputePeriod); - setMaxPremintedVouchers(_limits.maxPremintedVouchers); // Initialize protocol counters ProtocolLib.ProtocolCounters storage pc = protocolCounters(); @@ -238,176 +227,6 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { return protocolFees().flatBoson; } - /** - * @notice Sets the maximum numbers of offers that can be added to a group in a single transaction. - * - * Emits a MaxOffersPerGroupChanged event if successful. - * - * Reverts if the _maxOffersPerGroup is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxOffersPerGroup - the maximum length of {BosonTypes.Group.offerIds} - */ - function setMaxOffersPerGroup(uint16 _maxOffersPerGroup) public override onlyRole(ADMIN) nonReentrant { - // Make sure _maxOffersPerGroup is greater than 0 - checkNonZero(_maxOffersPerGroup); - - protocolLimits().maxOffersPerGroup = _maxOffersPerGroup; - emit MaxOffersPerGroupChanged(_maxOffersPerGroup, msgSender()); - } - - /** - * @notice Gets the maximum numbers of offers that can be added to a group in a single transaction. - * - * @return the maximum numbers of offers that can be added to a group in a single transaction - */ - function getMaxOffersPerGroup() external view override returns (uint16) { - return protocolLimits().maxOffersPerGroup; - } - - /** - * @notice Sets the maximum numbers of twins that can be added to a bundle in a single transaction. - * - * Emits a MaxTwinsPerBundleChanged event if successful. - * - * Reverts if the _maxTwinsPerBundle is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxTwinsPerBundle - the maximum length of {BosonTypes.Bundle.twinIds} - */ - function setMaxTwinsPerBundle(uint16 _maxTwinsPerBundle) public override onlyRole(ADMIN) nonReentrant { - // Make sure _maxTwinsPerBundle is greater than 0 - checkNonZero(_maxTwinsPerBundle); - - protocolLimits().maxTwinsPerBundle = _maxTwinsPerBundle; - emit MaxTwinsPerBundleChanged(_maxTwinsPerBundle, msgSender()); - } - - /** - * @notice Gets the maximum numbers of twins that can be added to a bundle in a single transaction. - * - * @return the maximum numbers of twins that can be added to a bundle in a single transaction. - */ - function getMaxTwinsPerBundle() external view override returns (uint16) { - return protocolLimits().maxTwinsPerBundle; - } - - /** - * @notice Sets the maximum numbers of offers that can be added to a bundle in a single transaction. - * - * Emits a MaxOffersPerBundleChanged event if successful. - * - * Reverts if the _maxOffersPerBundle is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxOffersPerBundle - the maximum length of {BosonTypes.Bundle.offerIds} - */ - function setMaxOffersPerBundle(uint16 _maxOffersPerBundle) public override onlyRole(ADMIN) nonReentrant { - // Make sure _maxOffersPerBundle is greater than 0 - checkNonZero(_maxOffersPerBundle); - - protocolLimits().maxOffersPerBundle = _maxOffersPerBundle; - emit MaxOffersPerBundleChanged(_maxOffersPerBundle, msgSender()); - } - - /** - * @notice Gets the maximum numbers of offers that can be added to a bundle in a single transaction. - * - * @return the maximum numbers of offers that can be added to a bundle in a single transaction - */ - function getMaxOffersPerBundle() external view override returns (uint16) { - return protocolLimits().maxOffersPerBundle; - } - - /** - * @notice Sets the maximum numbers of offers that can be created in a single transaction. - * - * Emits a MaxOffersPerBatchChanged event if successful. - * - * Reverts if the _maxOffersPerBatch is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxOffersPerBatch - the maximum length of {BosonTypes.Offer[]} - */ - function setMaxOffersPerBatch(uint16 _maxOffersPerBatch) public override onlyRole(ADMIN) nonReentrant { - // Make sure _maxOffersPerBatch is greater than 0 - checkNonZero(_maxOffersPerBatch); - - protocolLimits().maxOffersPerBatch = _maxOffersPerBatch; - emit MaxOffersPerBatchChanged(_maxOffersPerBatch, msgSender()); - } - - /** - * @notice Gets the maximum numbers of offers that can be created in a single transaction. - * - * @return the maximum numbers of offers that can be created in a single transaction - */ - function getMaxOffersPerBatch() external view override returns (uint16) { - return protocolLimits().maxOffersPerBatch; - } - - /** - * @notice Sets the maximum numbers of tokens that can be withdrawn in a single transaction. - * - * Emits a MaxTokensPerWithdrawalChanged event if successful. - * - * Reverts if the _maxTokensPerWithdrawal is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxTokensPerWithdrawal - the maximum length of token list when calling {FundsHandlerFacet.withdraw} - */ - function setMaxTokensPerWithdrawal(uint16 _maxTokensPerWithdrawal) public override onlyRole(ADMIN) nonReentrant { - // Make sure _maxTokensPerWithdrawal is greater than 0 - checkNonZero(_maxTokensPerWithdrawal); - - protocolLimits().maxTokensPerWithdrawal = _maxTokensPerWithdrawal; - emit MaxTokensPerWithdrawalChanged(_maxTokensPerWithdrawal, msgSender()); - } - - /** - * @notice Gets the maximum numbers of tokens that can be withdrawn in a single transaction. - * - * @return the maximum length of token list when calling {FundsHandlerFacet.withdraw} - */ - function getMaxTokensPerWithdrawal() external view override returns (uint16) { - return protocolLimits().maxTokensPerWithdrawal; - } - - /** - * @notice Sets the maximum number of dispute resolver fee structs that can be processed in a single transaction. - * - * Emits a MaxFeesPerDisputeResolverChanged event if successful. - * - * Reverts if the _maxFeesPerDisputeResolver is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxFeesPerDisputeResolver - the maximum length of dispute resolver fees list when calling {AccountHandlerFacet.createDisputeResolver} or {AccountHandlerFacet.updateDisputeResolver} - */ - function setMaxFeesPerDisputeResolver( - uint16 _maxFeesPerDisputeResolver - ) public override onlyRole(ADMIN) nonReentrant { - // Make sure _maxFeesPerDisputeResolver is greater than 0 - checkNonZero(_maxFeesPerDisputeResolver); - - protocolLimits().maxFeesPerDisputeResolver = _maxFeesPerDisputeResolver; - emit MaxFeesPerDisputeResolverChanged(_maxFeesPerDisputeResolver, msgSender()); - } - - /** - * @notice Gets the maximum number of dispute resolver fee structs that can be processed in a single transaction. - * - * @return the maximum number of dispute resolver fee structs that can be processed in a single transaction - */ - function getMaxFeesPerDisputeResolver() external view override returns (uint16) { - return protocolLimits().maxFeesPerDisputeResolver; - } - /** * @notice Sets the maximum escalation response period a dispute resolver can specify. * @@ -438,32 +257,6 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { return protocolLimits().maxEscalationResponsePeriod; } - /** - * @notice Sets the maximum number of disputes that can be expired in a single transaction. - * - * Emits a MaxDisputesPerBatchChanged event if successful. - * - * @dev Caller must have ADMIN role. - * - * @param _maxDisputesPerBatch - the maximum number of disputes that can be expired - */ - function setMaxDisputesPerBatch(uint16 _maxDisputesPerBatch) public override onlyRole(ADMIN) nonReentrant { - // Make sure _maxDisputesPerBatch is greater than 0 - checkNonZero(_maxDisputesPerBatch); - - protocolLimits().maxDisputesPerBatch = _maxDisputesPerBatch; - emit MaxDisputesPerBatchChanged(_maxDisputesPerBatch, msgSender()); - } - - /** - * @notice Gets the maximum number of disputes that can be expired in a single transaction. - * - * @return the maximum number of disputes that can be expired - */ - function getMaxDisputesPerBatch() external view override returns (uint16) { - return protocolLimits().maxDisputesPerBatch; - } - /** * @notice Sets the total offer fee percentage limit that will validate the sum of (Protocol Fee percentage + Agent Fee percentage) of an offer fee. * @@ -539,34 +332,6 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { return protocolLimits().maxRoyaltyPecentage; } - /** - * @notice Sets the maximum number of seller ids that can be added to or removed from dispute resolver seller allow list in a single transaction. - * - * Emits a MaxAllowedSellersChanged event if successful. - * - * Reverts if the _maxAllowedSellers is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxAllowedSellers - the maximum number of seller ids that can be added or removed - */ - function setMaxAllowedSellers(uint16 _maxAllowedSellers) public override onlyRole(ADMIN) nonReentrant { - // Make sure _maxAllowedSellers greater than 0 - checkNonZero(_maxAllowedSellers); - - protocolLimits().maxAllowedSellers = _maxAllowedSellers; - emit MaxAllowedSellersChanged(_maxAllowedSellers, msgSender()); - } - - /** - * @notice Gets the maximum number of seller ids that can be added to or removed from dispute resolver seller allow list in a single transaction. - * - * @return the maximum number of seller ids that can be added or removed - */ - function getMaxAllowedSellers() external view override returns (uint16) { - return protocolLimits().maxAllowedSellers; - } - /** * @notice Sets the buyer escalation fee percentage. * @@ -641,34 +406,6 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { return protocolLookups().authTokenContracts[_authTokenType]; } - /** - * @notice Sets the maximum number of exchanges that can be created in a single transaction. - * - * Emits a MaxExchangesPerBatchChanged event if successful. - * - * Reverts if the _maxExchangesPerBatch is zero. - * - * @dev Caller must have ADMIN role. - * - * @param _maxExchangesPerBatch - the maximum length of {BosonTypes.Exchange[]} - */ - function setMaxExchangesPerBatch(uint16 _maxExchangesPerBatch) public override onlyRole(ADMIN) nonReentrant { - // Make sure _maxExchangePerBatch is greater than 0 - checkNonZero(_maxExchangesPerBatch); - - protocolLimits().maxExchangesPerBatch = _maxExchangesPerBatch; - emit MaxExchangesPerBatchChanged(_maxExchangesPerBatch, msgSender()); - } - - /** - * @notice Gets the maximum number of exchanges that can be created in a single transaction. - * - * @return the maximum length of {BosonTypes.Exchange[]} - */ - function getMaxExchangesPerBatch() external view override returns (uint16) { - return protocolLimits().maxExchangesPerBatch; - } - /** * @notice Sets the maximum resolution period a seller can specify. * @@ -721,30 +458,6 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { return protocolLimits().minDisputePeriod; } - /** - * @notice Sets the maximum number of vouchers that can be preminted in a single transaction. - * - * Emits a MaxPremintedVouchersChanged event if successful. - * - * Reverts if the _maxPremintedVouchers is zero. - * - * @param _maxPremintedVouchers - the maximum number of vouchers - */ - function setMaxPremintedVouchers(uint256 _maxPremintedVouchers) public override onlyRole(ADMIN) nonReentrant { - // Make sure _maxPremintedVouchers is greater than 0 - checkNonZero(_maxPremintedVouchers); - - protocolLimits().maxPremintedVouchers = _maxPremintedVouchers; - emit MaxPremintedVouchersChanged(_maxPremintedVouchers, msgSender()); - } - - /** - * @notice Gets the maximum number of vouchers that can be preminted in a single transaction. - */ - function getMaxPremintedVouchers() external view override returns (uint256) { - return protocolLimits().maxPremintedVouchers; - } - /** * @notice Sets the access controller address. * diff --git a/contracts/protocol/facets/ExchangeHandlerFacet.sol b/contracts/protocol/facets/ExchangeHandlerFacet.sol index 53c051fa0..09c47339d 100644 --- a/contracts/protocol/facets/ExchangeHandlerFacet.sol +++ b/contracts/protocol/facets/ExchangeHandlerFacet.sol @@ -286,7 +286,6 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase { * * Reverts if: * - The exchanges region of protocol is paused - * - Number of exchanges exceeds maximum allowed number per batch * - For any exchange: * - Exchange does not exist * - Exchange is not in Redeemed state @@ -295,9 +294,6 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase { * @param _exchangeIds - the array of exchanges ids */ function completeExchangeBatch(uint256[] calldata _exchangeIds) external override exchangesNotPaused { - // limit maximum number of exchanges to avoid running into block gas limit in a loop - require(_exchangeIds.length <= protocolLimits().maxExchangesPerBatch, TOO_MANY_EXCHANGES); - for (uint256 i = 0; i < _exchangeIds.length; i++) { // complete the exchange completeExchange(_exchangeIds[i]); diff --git a/contracts/protocol/facets/FundsHandlerFacet.sol b/contracts/protocol/facets/FundsHandlerFacet.sol index 58f613321..99e972497 100644 --- a/contracts/protocol/facets/FundsHandlerFacet.sol +++ b/contracts/protocol/facets/FundsHandlerFacet.sol @@ -235,14 +235,11 @@ contract FundsHandlerFacet is IBosonFundsHandler, ProtocolBase { // Make sure that at least something will be withdrawn require(tokenList.length != 0, NOTHING_TO_WITHDRAW); - // Make sure that tokenList is not too long - uint256 len = maxTokensPerWithdrawal <= tokenList.length ? maxTokensPerWithdrawal : tokenList.length; - // Get entity's availableFunds storage pointer mapping(address => uint256) storage entityFunds = lookups.availableFunds[_entityId]; // Transfer funds - for (uint256 i = 0; i < len; i++) { + for (uint256 i = 0; i < tokenList.length; i++) { // Get available funds from storage uint256 availableFunds = entityFunds[tokenList[i]]; FundsLib.transferFundsFromProtocol(_entityId, tokenList[i], _destinationAddress, availableFunds); diff --git a/contracts/protocol/facets/GroupHandlerFacet.sol b/contracts/protocol/facets/GroupHandlerFacet.sol index 547a92465..68c4ded8b 100644 --- a/contracts/protocol/facets/GroupHandlerFacet.sol +++ b/contracts/protocol/facets/GroupHandlerFacet.sol @@ -77,7 +77,6 @@ contract GroupHandlerFacet is IBosonGroupHandler, GroupBase { * - The groups region of protocol is paused * - Caller is not the seller * - Offer ids param is an empty list - * - Number of offers exceeds maximum allowed number per group * - Group does not exist * - Any offer is not part of the group * @@ -94,9 +93,6 @@ contract GroupHandlerFacet is IBosonGroupHandler, GroupBase { // Check if group can be updated (uint256 sellerId, Group storage group) = preUpdateChecks(_groupId, _offerIds); - // limit maximum number of offers to avoid running into block gas limit in a loop - require(_offerIds.length <= protocolLimits().maxOffersPerGroup, TOO_MANY_OFFERS); - for (uint256 i = 0; i < _offerIds.length; i++) { uint256 offerId = _offerIds[i]; diff --git a/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol b/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol index 376e1723a..553c372f8 100644 --- a/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol +++ b/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol @@ -122,7 +122,6 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl uint256 _maxPremintedVouchers = abi.decode(_initializationData, (uint256)); require(_maxPremintedVouchers != 0, VALUE_ZERO_NOT_ALLOWED); protocolLimits().maxPremintedVouchers = _maxPremintedVouchers; - emit MaxPremintedVouchersChanged(_maxPremintedVouchers, msgSender()); } /** diff --git a/scripts/config/limit-estimation.js b/scripts/config/limit-estimation.js deleted file mode 100644 index 5754d4cf2..000000000 --- a/scripts/config/limit-estimation.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * List of limits to test and methods that depend on them. - * This is used to test the upper limit of elements in array, passed as input arguments, before the gas block limit is hit. - * - * If a new limit is added to the smart contracts, this list should be updated. - */ -exports.limitsToEstimate = { - blockGasLimit: 30000000, - safeGasLimitPercent: 60, - maxArrayLength: 100, // length of the array used during the estimation. - limits: [ - { name: "maxExchangesPerBatch", methods: { completeExchangeBatch: "IBosonExchangeHandler" } }, - { - name: "maxOffersPerGroup", - methods: { - createGroup: "IBosonGroupHandler", - addOffersToGroup: "IBosonGroupHandler", - removeOffersFromGroup: "IBosonGroupHandler", - }, - }, - { name: "maxOffersPerBundle", methods: { createBundle: "IBosonBundleHandler" } }, - { name: "maxTwinsPerBundle", methods: { createBundle: "IBosonBundleHandler" } }, - { - name: "maxOffersPerBatch", - methods: { - createOfferBatch: "IBosonOfferHandler", - voidOfferBatch: "IBosonOfferHandler", - extendOfferBatch: "IBosonOfferHandler", - }, - }, - { - name: "maxTokensPerWithdrawal", - methods: { withdrawFunds: "IBosonFundsHandler", withdrawProtocolFees: "IBosonFundsHandler" }, - }, - { - name: "maxFeesPerDisputeResolver", - methods: { - createDisputeResolver: "IBosonAccountHandler", - addFeesToDisputeResolver: "IBosonAccountHandler", - removeFeesFromDisputeResolver: "IBosonAccountHandler", - }, - }, - { name: "maxDisputesPerBatch", methods: { expireDisputeBatch: "IBosonDisputeHandler" } }, - { - name: "maxAllowedSellers", - methods: { - createDisputeResolver: "IBosonAccountHandler", - addSellersToAllowList: "IBosonAccountHandler", - removeSellersFromAllowList: "IBosonAccountHandler", - }, - }, - { name: "maxPremintedVouchers", methods: { preMint: "IBosonVoucher" } }, - ], -}; diff --git a/scripts/util/estimate-limits.js b/scripts/util/estimate-limits.js deleted file mode 100644 index e05a0e7b7..000000000 --- a/scripts/util/estimate-limits.js +++ /dev/null @@ -1,1003 +0,0 @@ -const hre = require("hardhat"); -const ethers = hre.ethers; -const simpleStatistic = require("simple-statistics"); -const fs = require("fs"); - -const { limitsToEstimate } = require("../config/limit-estimation"); -const gasLimit = limitsToEstimate.blockGasLimit; -hre.network.config.blockGasLimit = gasLimit; - -const Role = require("../domain/Role"); -const Bundle = require("../domain/Bundle"); -const Group = require("../domain/Group"); -const EvaluationMethod = require("../domain/EvaluationMethod"); -const { DisputeResolverFee } = require("../domain/DisputeResolverFee"); -const { deployProtocolDiamond } = require("../util/deploy-protocol-diamond.js"); -const { deployAndCutFacets } = require("../util/deploy-protocol-handler-facets.js"); -const { deployProtocolClients } = require("../util/deploy-protocol-clients"); -const { deployMockTokens } = require("../util/deploy-mock-tokens"); -const { oneWeek, oneMonth } = require("../../test/util/constants"); -const { - mockSeller, - mockDisputeResolver, - mockVoucherInitValues, - mockAuthToken, - mockCondition, - mockOffer, - mockTwin, - accountId, -} = require("../../test/util/mock"); -const { setNextBlockTimestamp, getFacetsWithArgs, calculateContractAddress } = require("../../test/util/utils.js"); - -// Common vars -let deployer, - sellerWallet1, - sellerWallet2, - sellerWallet3, - dr1, - dr2, - dr3, - buyer, - rando, - other1, - other2, - other3, - protocolAdmin, - feeCollector; -let protocolDiamond, - accessController, - accountHandler, - bundleHandler, - disputeHandler, - exchangeHandler, - fundsHandler, - groupHandler, - offerHandler, - twinHandler; -let bosonVoucher; -let protocolFeePercentage, protocolFeeFlatBoson, buyerEscalationDepositPercentage; -let handlers = {}; -let result = {}; - -let setupEnvironment = {}; - -/* -For each limit from limitsToEstimate, a full setup is needed before a function that depends on a limit can be estimated. -The function that prepares an environment must return the object with invocation details for all methods that depend on a limit. -{ method_1: invocationDetails_1, method_2: invocationDetails_2, ..., method_n: invocationDetails_2} - -Invocation details contain -- account: account that calls the method (important if access is restiricted) -- args: array of arguments that needs to be passed into method -- arrayIndex: index that tells which parameter's length should be varied during the estimation -- structField: if array is part of a struct, specify the field name -*/ - -/* -Setup the environment for "maxAllowedSellers". The following functions depend on it: -- createDisputeResolver -- addSellersToAllowList -- removeSellersFromAllowList -*/ -setupEnvironment["maxAllowedSellers"] = async function (sellerCount = 10) { - // AuthToken - const emptyAuthToken = mockAuthToken(); - const voucherInitValues = mockVoucherInitValues(); - - for (let i = 0; i < sellerCount; i++) { - const wallet = ethers.Wallet.createRandom(); - - //Random wallet has no provider. Connect wallet to ethers provider. The connected wallet will have no ETH - const connectedWallet = wallet.connect(ethers.provider); - - //Fund the new wallet - let tx = { - to: connectedWallet.address, - // Convert currency unit from ether to wei - value: ethers.utils.parseEther("1"), - }; - - await other1.sendTransaction(tx); - const seller = mockSeller(wallet.address, wallet.address, wallet.address, wallet.address); - await accountHandler.connect(connectedWallet).createSeller(seller, emptyAuthToken, voucherInitValues); - } - - //Create DisputeResolverFee array - const disputeResolverFees = [ - new DisputeResolverFee(other1.address, "MockToken1", "0"), - new DisputeResolverFee(other2.address, "MockToken2", "0"), - new DisputeResolverFee(other3.address, "MockToken3", "0"), - ]; - - const sellerAllowList = [...Array(sellerCount + 1).keys()].slice(1); - - // Dispute resolver 2 - used in "addSellersToAllowList" - const disputeResolver2 = mockDisputeResolver(dr2.address, dr2.address, dr2.address, dr2.address); - await accountHandler.connect(dr2).createDisputeResolver(disputeResolver2, disputeResolverFees, []); - const args_2 = [disputeResolver2.id, sellerAllowList]; - const arrayIndex_2 = 1; - - // Dispute resolver 3 - used in "removeSellersFromAllowList" - const disputeResolver3 = mockDisputeResolver(dr3.address, dr3.address, dr3.address, dr3.address); - await accountHandler.connect(dr3).createDisputeResolver(disputeResolver3, disputeResolverFees, sellerAllowList); - const args_3 = [disputeResolver3.id, sellerAllowList]; - const arrayIndex_3 = 1; - - const disputeResolver1 = mockDisputeResolver(dr1.address, dr1.address, dr1.address, dr1.address); - const args_1 = [disputeResolver1, disputeResolverFees, sellerAllowList]; - const arrayIndex_1 = 2; - - return { - createDisputeResolver: { account: dr1, args: args_1, arrayIndex: arrayIndex_1 }, - addSellersToAllowList: { account: dr2, args: args_2, arrayIndex: arrayIndex_2 }, - removeSellersFromAllowList: { account: dr3, args: args_3, arrayIndex: arrayIndex_3 }, - }; -}; - -/* -Setup the environment for "maxFeesPerDisputeResolver". The following functions depend on it: -- createDisputeResolver -- addFeesToDisputeResolver -- removeFeesFromDisputeResolver -*/ -setupEnvironment["maxFeesPerDisputeResolver"] = async function (feesCount = 10) { - //Create DisputeResolverFee array - let disputeResolverFees = []; - for (let i = 0; i < feesCount; i++) { - const wallet = ethers.Wallet.createRandom(); - disputeResolverFees.push(new DisputeResolverFee(wallet.address, `MockToken${i}`, "0")); - } - - // Dispute resolver 2 - used in "addFeesToDisputeResolver" - const disputeResolver2 = mockDisputeResolver(dr2.address, dr2.address, dr2.address, dr2.address); - await accountHandler.connect(dr2).createDisputeResolver(disputeResolver2, [], []); - const args_2 = [disputeResolver2.id, disputeResolverFees]; - const arrayIndex_2 = 1; - - // Dispute resolver 3 - used in "removeFeesFromDisputeResolver" - const disputeResolver3 = mockDisputeResolver(dr3.address, dr3.address, dr3.address, dr3.address); - await accountHandler.connect(dr3).createDisputeResolver(disputeResolver3, disputeResolverFees, [], { gasLimit }); - const feeTokenAddressesToRemove = disputeResolverFees.map((DRfee) => DRfee.tokenAddress); - const args_3 = [disputeResolver3.id, feeTokenAddressesToRemove]; - const arrayIndex_3 = 1; - - const disputeResolver1 = mockDisputeResolver(dr1.address, dr1.address, dr1.address, dr1.address); - const args_1 = [disputeResolver1, disputeResolverFees, []]; - const arrayIndex_1 = 1; - - return { - createDisputeResolver: { account: dr1, args: args_1, arrayIndex: arrayIndex_1 }, - addFeesToDisputeResolver: { account: dr2, args: args_2, arrayIndex: arrayIndex_2 }, - removeFeesFromDisputeResolver: { account: dr3, args: args_3, arrayIndex: arrayIndex_3 }, - }; -}; - -/* -Setup the environment for "maxOffersPerBatch". The following functions depend on it: -- createOfferBatch -- voidOfferBatch -- extendOfferBatch -*/ -setupEnvironment["maxOffersPerBatch"] = async function (offerCount = 10) { - // Create a seller - // Required constructor params - const agentId = "0"; // agent id is optional while creating an offer - - const seller1 = mockSeller( - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address - ); - const voucherInitValues = mockVoucherInitValues(); - const emptyAuthToken = mockAuthToken(); - - await accountHandler.connect(sellerWallet1).createSeller(seller1, emptyAuthToken, voucherInitValues); - - // Seller 2 - used in "voidOfferBatch" - const seller2 = mockSeller( - sellerWallet2.address, - sellerWallet2.address, - sellerWallet2.address, - sellerWallet2.address - ); - await accountHandler.connect(sellerWallet2).createSeller(seller2, emptyAuthToken, voucherInitValues); - - // Seller 3 - used in "extendOfferBatch" - const seller3 = mockSeller( - sellerWallet3.address, - sellerWallet3.address, - sellerWallet3.address, - sellerWallet3.address - ); - await accountHandler.connect(sellerWallet3).createSeller(seller3, emptyAuthToken, voucherInitValues); - - const disputeResolver = mockDisputeResolver(dr1.address, dr1.address, dr1.address, dr1.address, true); - await accountHandler - .connect(dr1) - .createDisputeResolver(disputeResolver, [new DisputeResolverFee(ethers.constants.AddressZero, "Native", "0")], []); - - const { offer, offerDates, offerDurations } = await mockOffer(); - const offers = new Array(offerCount).fill(offer); - const offerDatesList = new Array(offerCount).fill(offerDates); - const offerDurationsList = new Array(offerCount).fill(offerDurations); - const disputeResolverIds = new Array(offerCount).fill(disputeResolver.id); - const agentIds = new Array(offerCount).fill(agentId); - - for (let i = 0; i < offerCount; i++) { - // Create the offers for voiding/extending - await offerHandler - .connect(sellerWallet2) - .createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId); - await offerHandler - .connect(sellerWallet3) - .createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId); - } - - const offerIds = [...Array(offerCount + 1).keys()].slice(1); - - const args_1 = [offers, offerDatesList, offerDurationsList, disputeResolverIds, agentIds]; - const arrayIndex_1 = [0, 1, 2, 3, 4]; // adjusting length of all arguments simultaneously - - // voidOfferBatch inputs - const args_2 = [offerIds.map((offerId) => 2 * offerId - 1)]; - const arrayIndex_2 = 0; - - // extendOfferBatch - const newValidUntilDate = ethers.BigNumber.from(offerDates.validUntil).add("10000").toString(); - const args_3 = [offerIds.map((offerId) => 2 * offerId), newValidUntilDate]; - const arrayIndex_3 = 0; - - return { - createOfferBatch: { account: sellerWallet1, args: args_1, arrayIndex: arrayIndex_1 }, - voidOfferBatch: { account: sellerWallet2, args: args_2, arrayIndex: arrayIndex_2 }, - extendOfferBatch: { account: sellerWallet3, args: args_3, arrayIndex: arrayIndex_3 }, - }; -}; - -/* -Setup the environment for "maxOffersPerGroup". The following functions depend on it: -- createGroup -- addOffersToGroup -- removeOffersFromGroup -*/ -setupEnvironment["maxOffersPerGroup"] = async function (offerCount = 10) { - // Create a seller - // Required constructor params - const groupId = "1"; // argument sent to contract for createSeller will be ignored - const agentId = "0"; // agent id is optional while creating an offer - - const seller1 = mockSeller( - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address - ); - const voucherInitValues = mockVoucherInitValues(); - const emptyAuthToken = mockAuthToken(); - - await accountHandler.connect(sellerWallet1).createSeller(seller1, emptyAuthToken, voucherInitValues); - - // Seller 2 - used in "addOffersToGroup" - const seller2 = mockSeller( - sellerWallet2.address, - sellerWallet2.address, - sellerWallet2.address, - sellerWallet2.address - ); - await accountHandler.connect(sellerWallet2).createSeller(seller2, emptyAuthToken, voucherInitValues); - - // Seller 3 - used in "removeOffersFromGroup" - const seller3 = mockSeller( - sellerWallet3.address, - sellerWallet3.address, - sellerWallet3.address, - sellerWallet3.address - ); - await accountHandler.connect(sellerWallet3).createSeller(seller3, emptyAuthToken, voucherInitValues); - - const disputeResolver = mockDisputeResolver(dr1.address, dr1.address, dr1.address, dr1.address, true); - await accountHandler - .connect(dr1) - .createDisputeResolver(disputeResolver, [new DisputeResolverFee(ethers.constants.AddressZero, "Native", "0")], []); - - // Mock offer, offerDates and offerDurations - const { offer, offerDates, offerDurations } = await mockOffer(); - - for (let i = 0; i < offerCount; i++) { - // Create the offer - await offerHandler - .connect(sellerWallet1) - .createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId); - await offerHandler - .connect(sellerWallet2) - .createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId); - await offerHandler - .connect(sellerWallet3) - .createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId); - } - - const offerIds = [...Array(offerCount + 1).keys()].slice(1); - const condition = mockCondition({ method: EvaluationMethod.None, threshold: "0", maxCommits: "0" }); - - const group = new Group(groupId, seller1.id, offerIds); - - let group1 = group.clone(); - group1.offerIds = offerIds.map((offerId) => 3 * offerId - 2); - const args_1 = [group1, condition]; - const arrayIndex_1 = 0; - const structField_1 = "offerIds"; - - let group2 = group.clone(); - group2.offerIds = []; - await groupHandler.connect(sellerWallet2).createGroup(group2, condition); - const args_2 = ["1", offerIds.map((offerId) => 3 * offerId - 1)]; - const arrayIndex_2 = 1; - - let group3 = group.clone(); - group3.offerIds = offerIds.map((offerId) => 3 * offerId); - await groupHandler.connect(sellerWallet3).createGroup(group3, condition, { gasLimit }); - const args_3 = ["2", group3.offerIds]; - const arrayIndex_3 = 1; - - return { - createGroup: { account: sellerWallet1, args: args_1, arrayIndex: arrayIndex_1, structField: structField_1 }, - addOffersToGroup: { account: sellerWallet2, args: args_2, arrayIndex: arrayIndex_2 }, - removeOffersFromGroup: { account: sellerWallet3, args: args_3, arrayIndex: arrayIndex_3 }, - }; -}; - -/* -Setup the environment for "maxOffersPerBundle". The following functions depend on it: -- createBundle -*/ -setupEnvironment["maxOffersPerBundle"] = async function (offerCount = 10) { - // Create a seller - // Required constructor params - const agentId = "0"; // agent id is optional while creating an offer - - const seller1 = mockSeller( - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address - ); - const voucherInitValues = mockVoucherInitValues(); - const emptyAuthToken = mockAuthToken(); - - await accountHandler.connect(sellerWallet1).createSeller(seller1, emptyAuthToken, voucherInitValues); - - const disputeResolver = mockDisputeResolver(dr1.address, dr1.address, dr1.address, dr1.address, true); - await accountHandler - .connect(dr1) - .createDisputeResolver(disputeResolver, [new DisputeResolverFee(ethers.constants.AddressZero, "Native", "0")], []); - - // Mock offer, offerDates and offerDurations - const { offer, offerDates, offerDurations } = await mockOffer(); - - for (let i = 0; i < offerCount; i++) { - // Create the offer - await offerHandler - .connect(sellerWallet1) - .createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId); - } - - // Create a valid twin. - const [bosonToken] = await deployMockTokens(); - const twin = mockTwin(bosonToken.address); - twin.supplyAvailable = ethers.BigNumber.from(twin.amount).mul(offerCount); - - // Approving the twinHandler contract to transfer seller's tokens - await bosonToken.connect(sellerWallet1).approve(twinHandler.address, twin.supplyAvailable); // approving the twin handler - - // Create a twin. - await twinHandler.connect(sellerWallet1).createTwin(twin); - const twinIds = ["1"]; - - const offerIds = [...Array(offerCount + 1).keys()].slice(1); - - const bundle = new Bundle("1", seller1.id, offerIds, twinIds); - - const args_1 = [bundle]; - const arrayIndex_1 = 0; - const structField_1 = "offerIds"; - - return { - createBundle: { account: sellerWallet1, args: args_1, arrayIndex: arrayIndex_1, structField: structField_1 }, - }; -}; - -/* -Setup the environment for "maxTwinsPerBundle". The following functions depend on it: -- createBundle -*/ -setupEnvironment["maxTwinsPerBundle"] = async function (twinCount = 10) { - // Create a seller - // Required constructor params - const agentId = "0"; // agent id is optional while creating an offer - - const seller1 = mockSeller( - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address - ); - const voucherInitValues = mockVoucherInitValues(); - const emptyAuthToken = mockAuthToken(); - - await accountHandler.connect(sellerWallet1).createSeller(seller1, emptyAuthToken, voucherInitValues); - - const disputeResolver = mockDisputeResolver(dr1.address, dr1.address, dr1.address, dr1.address, true); - await accountHandler - .connect(dr1) - .createDisputeResolver(disputeResolver, [new DisputeResolverFee(ethers.constants.AddressZero, "Native", "0")], []); - - for (let i = 0; i < twinCount; i++) { - const [twinContract] = await deployMockTokens(["Foreign20"]); - const twin = mockTwin(twinContract.address); - - // Approving the twinHandler contract to transfer seller's tokens - await twinContract.connect(sellerWallet1).approve(twinHandler.address, twin.supplyAvailable); // approving the twin handler - - // Create a twin. - await twinHandler.connect(sellerWallet1).createTwin(twin); - } - - // Create a valid offer. - // Mock offer, offerDates and offerDurations - const { offer, offerDates, offerDurations } = await mockOffer(); - - // Create the offer - await offerHandler.connect(sellerWallet1).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId); - - const offerIds = ["1"]; - const twinIds = [...Array(twinCount + 1).keys()].slice(1); - - const bundle = new Bundle("1", seller1.id, offerIds, twinIds); - - const args_1 = [bundle]; - const arrayIndex_1 = 0; - const structField_1 = "twinIds"; - - return { - createBundle: { account: sellerWallet1, args: args_1, arrayIndex: arrayIndex_1, structField: structField_1 }, - }; -}; - -/* -Setup the environment for "maxExchangesPerBatch". The following functions depend on it: -- completeExchangeBatch -*/ -setupEnvironment["maxExchangesPerBatch"] = async function (exchangesCount = 10) { - // Create a seller - // Required constructor params - const agentId = "0"; // agent id is optional while creating an offer - - const seller1 = mockSeller( - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address - ); - const voucherInitValues = mockVoucherInitValues(); - const emptyAuthToken = mockAuthToken(); - - await accountHandler.connect(sellerWallet1).createSeller(seller1, emptyAuthToken, voucherInitValues); - - const disputeResolver = mockDisputeResolver(dr1.address, dr1.address, dr1.address, dr1.address, true); - await accountHandler - .connect(dr1) - .createDisputeResolver(disputeResolver, [new DisputeResolverFee(ethers.constants.AddressZero, "Native", "0")], []); - - // Create an offer with big enough quantity - const { offer, offerDates, offerDurations } = await mockOffer(); - offer.quantityAvailable = exchangesCount; - // Create the offer - await offerHandler.connect(sellerWallet1).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId); - - // Deposit seller funds so the commit will succeed - const sellerPool = ethers.BigNumber.from(offer.price).mul(exchangesCount); - await fundsHandler - .connect(sellerWallet1) - .depositFunds(seller1.id, ethers.constants.AddressZero, sellerPool, { value: sellerPool }); - - await setNextBlockTimestamp(Number(offerDates.voucherRedeemableFrom)); - for (let i = 1; i < exchangesCount + 1; i++) { - // Commit to offer, creating a new exchange - await exchangeHandler.connect(buyer).commitToOffer(buyer.address, offer.id, { value: offer.price }); - - // Redeem voucher - await exchangeHandler.connect(buyer).redeemVoucher(i); - } - - // Set time forward to run out the dispute period - const blockNumber = await ethers.provider.getBlockNumber(); - const block = await ethers.provider.getBlock(blockNumber); - const newTime = ethers.BigNumber.from(block.timestamp).add(offerDurations.disputePeriod).add(1).toNumber(); - await setNextBlockTimestamp(newTime); - - const exchangeIds = [...Array(exchangesCount + 1).keys()].slice(1); - - const args_1 = [exchangeIds]; - const arrayIndex_1 = 0; - - return { - completeExchangeBatch: { account: rando, args: args_1, arrayIndex: arrayIndex_1 }, - }; -}; - -/* -Setup the environment for "maxDisputesPerBatch". The following functions depend on it: -- expireDisputeBatch -*/ -setupEnvironment["maxDisputesPerBatch"] = async function (exchangesCount = 10) { - // Create a seller - // Required constructor params - const agentId = "0"; // agent id is optional while creating an offer - - const seller1 = mockSeller( - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address - ); - const voucherInitValues = mockVoucherInitValues(); - const emptyAuthToken = mockAuthToken(); - - await accountHandler.connect(sellerWallet1).createSeller(seller1, emptyAuthToken, voucherInitValues); - - const disputeResolver = mockDisputeResolver(dr1.address, dr1.address, dr1.address, dr1.address, true); - await accountHandler - .connect(dr1) - .createDisputeResolver(disputeResolver, [new DisputeResolverFee(ethers.constants.AddressZero, "Native", "0")], []); - - // Create an offer with big enough quantity - const { offer, offerDates, offerDurations } = await mockOffer(); - offer.quantityAvailable = exchangesCount; - // Create the offer - await offerHandler.connect(sellerWallet1).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId); - - // Deposit seller funds so the commit will succeed - const sellerPool = ethers.BigNumber.from(offer.price).mul(exchangesCount); - await fundsHandler - .connect(sellerWallet1) - .depositFunds(seller1.id, ethers.constants.AddressZero, sellerPool, { value: sellerPool }); - - await setNextBlockTimestamp(Number(offerDates.voucherRedeemableFrom)); - for (let i = 1; i < exchangesCount + 1; i++) { - // Commit to offer, creating a new exchange - await exchangeHandler.connect(buyer).commitToOffer(buyer.address, offer.id, { value: offer.price }); - - // Redeem voucher - await exchangeHandler.connect(buyer).redeemVoucher(i); - - // Raise dispute - await disputeHandler.connect(buyer).raiseDispute(i); - } - - // Set time forward to run out the dispute period - const blockNumber = await ethers.provider.getBlockNumber(); - const block = await ethers.provider.getBlock(blockNumber); - const newTime = ethers.BigNumber.from(block.timestamp).add(offerDurations.resolutionPeriod).add(1).toNumber(); - await setNextBlockTimestamp(newTime); - - const exchangeIds = [...Array(exchangesCount + 1).keys()].slice(1); - - const args_1 = [exchangeIds]; - const arrayIndex_1 = 0; - - return { - expireDisputeBatch: { account: rando, args: args_1, arrayIndex: arrayIndex_1 }, - }; -}; - -/* -Setup the environment for "maxTokensPerWithdrawal". The following functions depend on it: -- withdrawFunds -- withdrawProtocolFees -*/ -setupEnvironment["maxTokensPerWithdrawal"] = async function (tokenCount = 10) { - // Create a seller - // Required constructor params - const agentId = "0"; // agent id is optional while creating an offer - - const seller1 = mockSeller( - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address - ); - const voucherInitValues = mockVoucherInitValues(); - const emptyAuthToken = mockAuthToken(); - - await accountHandler.connect(sellerWallet1).createSeller(seller1, emptyAuthToken, voucherInitValues); - - const disputeResolver = mockDisputeResolver(dr1.address, dr1.address, dr1.address, dr1.address, true); - await accountHandler - .connect(dr1) - .createDisputeResolver(disputeResolver, [new DisputeResolverFee(ethers.constants.AddressZero, "Native", "0")], []); - - const { offer, offerDates, offerDurations } = await mockOffer(); - offerDates.voucherRedeemableFrom = offerDates.validFrom; - let tokenAddresses = []; - for (let i = 1; i < tokenCount + 1; i++) { - // create a token - const [tokenContract] = await deployMockTokens(["Foreign20"]); - tokenAddresses.push(tokenContract.address); - - offer.exchangeToken = tokenContract.address; - await tokenContract.mint(sellerWallet1.address, offer.sellerDeposit); - await tokenContract.mint(buyer.address, offer.price); - await tokenContract.connect(sellerWallet1).approve(protocolDiamond.address, offer.sellerDeposit); - await tokenContract.connect(buyer).approve(protocolDiamond.address, offer.price); - await fundsHandler.connect(sellerWallet1).depositFunds(seller1.id, tokenContract.address, offer.sellerDeposit); - - // add token to DR accepted tokens - await accountHandler - .connect(dr1) - .addFeesToDisputeResolver(disputeResolver.id, [new DisputeResolverFee(tokenContract.address, `Token${i}`, "0")]); - - // create the offer - await offerHandler - .connect(sellerWallet1) - .createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId); - - // Commit to offer, creating a new exchange - await exchangeHandler.connect(buyer).commitToOffer(buyer.address, i); - - // Redeem voucher - await exchangeHandler.connect(buyer).redeemVoucher(i); - - // Raise dispute - await exchangeHandler.connect(buyer).completeExchange(i); - } - - // seller withdrawal - const tokenAmounts_1 = new Array(tokenCount).fill(offer.price); - const args_1 = [seller1.id, tokenAddresses, tokenAmounts_1]; - const arrayIndex_1 = [1, 2]; - - // protocol fee withdrawal - await accessController.grantRole(Role.FEE_COLLECTOR, feeCollector.address); - const protocolFee = ethers.BigNumber.from(offer.price).mul(protocolFeePercentage).div(10000); - const tokenAmounts_2 = new Array(tokenCount).fill(protocolFee); - const args_2 = [tokenAddresses, tokenAmounts_2]; - const arrayIndex_2 = [0, 1]; - - return { - withdrawFunds: { account: sellerWallet1, args: args_1, arrayIndex: arrayIndex_1 }, - withdrawProtocolFees: { account: feeCollector, args: args_2, arrayIndex: arrayIndex_2 }, - }; -}; - -/* -Setup the environment for "maxPremintedVouchers". The following function depend on it: -- preMint -*/ -setupEnvironment["maxPremintedVouchers"] = async function (tokenCount = 10) { - // Create a seller - // Required constructor params - const agentId = "0"; // agent id is optional while creating an offer - - const seller1 = mockSeller( - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address, - sellerWallet1.address - ); - const voucherInitValues = mockVoucherInitValues(); - const emptyAuthToken = mockAuthToken(); - - await accountHandler.connect(sellerWallet1).createSeller(seller1, emptyAuthToken, voucherInitValues); - - const disputeResolver = mockDisputeResolver(dr1.address, dr1.address, dr1.address, dr1.address, true); - await accountHandler - .connect(dr1) - .createDisputeResolver(disputeResolver, [new DisputeResolverFee(ethers.constants.AddressZero, "Native", "0")], []); - - // create the offer - const { offer, offerDates, offerDurations } = await mockOffer(); - offer.quantityAvailable = ethers.constants.MaxUint256; - await offerHandler.connect(sellerWallet1).createOffer(offer, offerDates, offerDurations, disputeResolver.id, agentId); - - // reserve range - let length = ethers.BigNumber.from(2).pow(128).sub(1); - await offerHandler.connect(sellerWallet1).reserveRange(offer.id, length); - - // update bosonVoucher address - handlers.IBosonVoucher = bosonVoucher.attach(calculateContractAddress(accountHandler.address, seller1.id)); - - // make an empty array of length tokenCount - const amounts = new Array(tokenCount); - - const args_1 = [offer.id, amounts]; - const arrayIndex_1 = 1; - - return { - preMint: { account: sellerWallet1, args: args_1, arrayIndex: arrayIndex_1 }, - }; -}; - -/* -Invoke the methods that setup the environment and iterate over all limits and pass them to estimation. -At the end it writes the results to json file. -*/ -async function estimateLimits() { - if (hre.network.name !== "hardhat") { - console.log("Unsupported network"); - process.exit(1); - } - - for (const limit of limitsToEstimate.limits) { - console.log(`## ${limit.name} ##`); - console.log(`Setting up the environment`); - await setupCommonEnvironment(); - const inputs = await setupEnvironment[limit.name](limitsToEstimate.maxArrayLength); - console.log(`Estimating the limit`); - await estimateLimit(limit, inputs, limitsToEstimate.safeGasLimitPercent); - accountId.next(true); - } - makeReport(result, limitsToEstimate.maxArrayLength); -} - -/* -Esitmates individual limit. It estimates gas for different lenghts of input array and forwards -the result to function that calculates the actual limit. - -It stores the list of point estimates and maximum and safe lenght of the array to results. -*/ -async function estimateLimit(limit, inputs, safeGasLimitPercent) { - result[limit.name] = {}; - for (const [method, handler] of Object.entries(limit.methods)) { - console.log(`=== ${method} ===`); - const methodInputs = inputs[method]; - if (methodInputs === undefined) { - console.log(`Missing setup for ${limit.name}:${method}`); - continue; - } - - const maxArrayLength = methodInputs.structField - ? methodInputs.args[methodInputs.arrayIndex][methodInputs.structField].length - : methodInputs.args[Array.isArray(methodInputs.arrayIndex) ? methodInputs.arrayIndex[0] : methodInputs.arrayIndex] - .length; - let gasEstimates = []; - for (let o = 0; Math.pow(10, o) <= maxArrayLength; o++) { - for (let i = 1; i < 10; i++) { - let arrayLength = i * Math.pow(10, o); - if (arrayLength > maxArrayLength) arrayLength = maxArrayLength; - - const args = methodInputs.args; - let adjustedArgs = [...args]; - - if (methodInputs.structField) { - adjustedArgs[methodInputs.arrayIndex] = { ...adjustedArgs[methodInputs.arrayIndex] }; - adjustedArgs[methodInputs.arrayIndex][methodInputs.structField] = args[methodInputs.arrayIndex][ - methodInputs.structField - ].slice(0, arrayLength); - } else { - if (Array.isArray(methodInputs.arrayIndex)) { - for (const ai of methodInputs.arrayIndex) { - adjustedArgs[ai] = args[ai].slice(0, arrayLength); - } - } else { - // if args contains null values, just use arrayLength instead - adjustedArgs[methodInputs.arrayIndex] = args[methodInputs.arrayIndex][0] - ? args[methodInputs.arrayIndex].slice(0, arrayLength) - : arrayLength; - } - } - - try { - const gasEstimate = await handlers[handler] - .connect(methodInputs.account) - .estimateGas[method](...adjustedArgs, { gasLimit }); - console.log("Length:", arrayLength, "Gas:", gasEstimate.toNumber()); - gasEstimates.push([gasEstimate.toNumber(), arrayLength]); - } catch (e) { - // console.log(e) - console.log("Block gas limit already hit"); - break; - } - if (arrayLength == maxArrayLength) break; - } - } - const { maxNumber, safeNumber } = calculateLimit(gasEstimates, safeGasLimitPercent); - result[limit.name][method] = { gasEstimates, maxNumber, safeNumber }; - console.log(`Estimation complete`); - } -} - -/* -Based on point gas estimates calculates the maximum and safe length of the array that can be passed in -Safe length is determined by safeGasLimitPercent which is the percentage amount of block that is considered -safe to be taken -*/ -function calculateLimit(gasEstimates, safeGasLimitPercent) { - const regCoef = simpleStatistic.linearRegression(gasEstimates); - const line = simpleStatistic.linearRegressionLine(regCoef); - - const maxNumber = Math.floor(line(gasLimit)); - const safeNumber = Math.floor(line((gasLimit * safeGasLimitPercent) / 100)); - return { maxNumber, safeNumber }; -} - -/* -Deploys protocol contracts, casts facets to interfaces and makes accounts available -*/ -async function setupCommonEnvironment() { - // Make accounts available - [ - deployer, - sellerWallet1, - sellerWallet2, - sellerWallet3, - dr1, - dr2, - dr3, - buyer, - rando, - other1, - other2, - other3, - protocolAdmin, - feeCollector, - other1, - ] = await ethers.getSigners(); - - // Deploy the Protocol Diamond - [protocolDiamond, , , , accessController] = await deployProtocolDiamond(); - - // Temporarily grant UPGRADER role to deployer account - await accessController.grantRole(Role.UPGRADER, deployer.address); - - // Grant PROTOCOL role to ProtocolDiamond address and renounces admin - await accessController.grantRole(Role.PROTOCOL, protocolDiamond.address); - - // Grant ADMIN role to and address that can call restricted functions. - // This ADMIN role is a protocol-level role. It is not the same an admin address for an account type - await accessController.grantRole(Role.ADMIN, protocolAdmin.address); - - // Deploy the Protocol client implementation/proxy pairs (currently just the Boson Voucher) - const protocolClientArgs = [protocolDiamond.address]; - const [, beacons, proxies, bv] = await deployProtocolClients(protocolClientArgs, gasLimit); - const [beacon] = beacons; - const [proxy] = proxies; - [bosonVoucher] = bv; - - // Set protocolFees - protocolFeePercentage = "200"; // 2 % - protocolFeeFlatBoson = ethers.utils.parseUnits("0.01", "ether").toString(); - buyerEscalationDepositPercentage = "1000"; // 10% - - // Add config Handler, so ids start at 1, and so voucher address can be found - const protocolConfig = [ - // Protocol addresses - { - treasury: rando.address, - token: rando.address, - voucherBeacon: beacon.address, - beaconProxy: proxy.address, - }, - // Protocol limits - { - maxExchangesPerBatch: 10000, - maxOffersPerGroup: 10000, - maxTwinsPerBundle: 10000, - maxOffersPerBundle: 10000, - maxOffersPerBatch: 10000, - maxTokensPerWithdrawal: 10000, - maxFeesPerDisputeResolver: 10000, - maxEscalationResponsePeriod: oneMonth, - maxDisputesPerBatch: 10000, - maxAllowedSellers: 10000, - maxTotalOfferFeePercentage: 4000, //40% - maxRoyaltyPecentage: 1000, //10% - maxResolutionPeriod: oneMonth, - minDisputePeriod: oneWeek, - maxPremintedVouchers: 100, - }, - // Protocol fees - { - percentage: protocolFeePercentage, - flatBoson: protocolFeeFlatBoson, - buyerEscalationDepositPercentage, - }, - ]; - - const facetNames = [ - "AccountHandlerFacet", - "BundleHandlerFacet", - "DisputeHandlerFacet", - "DisputeResolverHandlerFacet", - "ExchangeHandlerFacet", - "FundsHandlerFacet", - "GroupHandlerFacet", - "OfferHandlerFacet", - "SellerHandlerFacet", - "TwinHandlerFacet", - "ProtocolInitializationHandlerFacet", - "ConfigHandlerFacet", - ]; - - const facetsToDeploy = await getFacetsWithArgs(facetNames, protocolConfig); - - // Cut the protocol handler facets into the Diamond - await deployAndCutFacets(protocolDiamond.address, facetsToDeploy, gasLimit); - // Cast Diamond to handlers - accountHandler = await ethers.getContractAt("IBosonAccountHandler", protocolDiamond.address); - bundleHandler = await ethers.getContractAt("IBosonBundleHandler", protocolDiamond.address); - disputeHandler = await ethers.getContractAt("IBosonDisputeHandler", protocolDiamond.address); - exchangeHandler = await ethers.getContractAt("IBosonExchangeHandler", protocolDiamond.address); - fundsHandler = await ethers.getContractAt("IBosonFundsHandler", protocolDiamond.address); - groupHandler = await ethers.getContractAt("IBosonGroupHandler", protocolDiamond.address); - offerHandler = await ethers.getContractAt("IBosonOfferHandler", protocolDiamond.address); - twinHandler = await ethers.getContractAt("IBosonTwinHandler", protocolDiamond.address); - - handlers = { - IBosonAccountHandler: accountHandler, - IBosonBundleHandler: bundleHandler, - IBosonDisputeHandler: disputeHandler, - IBosonExchangeHandler: exchangeHandler, - IBosonFundsHandler: fundsHandler, - IBosonGroupHandler: groupHandler, - IBosonOfferHandler: offerHandler, - IBosonVoucher: bosonVoucher, - }; -} - -function makeReport(res, maxArrayLength) { - // TABLE 1: suggested values - let header1 = `| limit | max value | safe value |`; - let alignment1 = `| :-- | --: | --: |`; - let rows1 = []; - - // TABLE 2: all estimates - let header2 = `| # |`; - let alignment2 = `|--| `; - let row0 = `| |`; - let rows2 = []; - let numberOfRows = 0; - - for (let o = 0; Math.pow(10, o) <= maxArrayLength; o++) { - for (let i = 1; i < 10; i++) { - let arrayLength = i * Math.pow(10, o); - if (arrayLength > maxArrayLength) arrayLength = maxArrayLength; - rows2.push(`| ${arrayLength} |`); - numberOfRows++; - if (arrayLength == maxArrayLength) break; - } - } - - let maxNumber = `| **max** |`; - let safeNumber = `| safe |`; - - for (const [limit, result] of Object.entries(res)) { - let mn = Number.MAX_SAFE_INTEGER; - let sn = Number.MAX_SAFE_INTEGER; - for (const [method, estimates] of Object.entries(result)) { - header2 = `${header2} ${limit} |`; - alignment2 = `${alignment2} ---:|`; - row0 = `${row0} ${method} |`; - for (let i = 0; i < numberOfRows; i++) { - rows2[i] = `${rows2[i]} ${estimates.gasEstimates[i] ? estimates.gasEstimates[i][0] : " "} |`; - } - maxNumber = `${maxNumber} **${estimates.maxNumber}** |`; - safeNumber = `${safeNumber} ${estimates.safeNumber} |`; - - mn = Math.min(mn, estimates.maxNumber); - sn = Math.min(sn, estimates.safeNumber); - } - - rows1.push(`| ${limit} | ${mn} | ${sn} |`); - } - - const table1 = [header1, alignment1, ...rows1].join(`\n`); - const table2 = [header2, alignment2, row0, ...rows2, maxNumber, safeNumber].join(`\n`); - - const output = `${table1}\n\n${table2}`; - - fs.writeFileSync(__dirname + "/../../logs/limit_estimates.md", output); - fs.writeFileSync(__dirname + "/../../logs/limit_estimates.json", JSON.stringify(result)); -} - -exports.estimateLimits = estimateLimits; diff --git a/test/protocol/ConfigHandlerTest.js b/test/protocol/ConfigHandlerTest.js index fe6705d91..5b4a44b0b 100644 --- a/test/protocol/ConfigHandlerTest.js +++ b/test/protocol/ConfigHandlerTest.js @@ -283,206 +283,6 @@ describe("IBosonConfigHandler", function () { // All supported methods context("📋 Setters", async function () { - context("👉 setMaxOffersPerGroup()", async function () { - let maxOffersPerGroup; - beforeEach(async function () { - // set new value for max offers per group - maxOffersPerGroup = 150; - }); - - it("should emit a MaxOffersPerGroupChanged event", async function () { - // Set new max offer per group, testing for the event - await expect(configHandler.connect(deployer).setMaxOffersPerGroup(maxOffersPerGroup)) - .to.emit(configHandler, "MaxOffersPerGroupChanged") - .withArgs(maxOffersPerGroup, deployer.address); - }); - - it("should update state", async function () { - // Set new max offer per group, - await configHandler.connect(deployer).setMaxOffersPerGroup(maxOffersPerGroup); - - // Verify that new value is stored - expect(await configHandler.connect(rando).getMaxOffersPerGroup()).to.equal(maxOffersPerGroup); - }); - - context("💔 Revert Reasons", async function () { - it("caller is not the admin", async function () { - // Attempt to set new max offer per group, expecting revert - await expect(configHandler.connect(rando).setMaxOffersPerGroup(maxOffersPerGroup)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); - }); - - it("maxOffersPerGroup is zero", async function () { - maxOffersPerGroup = 0; - - await expect(configHandler.connect(deployer).setMaxOffersPerGroup(maxOffersPerGroup)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); - }); - }); - }); - - context("👉 setMaxTwinsPerBundle()", async function () { - let maxTwinsPerBundle; - beforeEach(async function () { - // set new value for max twins per bundle - maxTwinsPerBundle = 150; - }); - - it("should emit a MaxTwinsPerBundleChanged event", async function () { - // Set new max twin per bundle, testing for the event - await expect(configHandler.connect(deployer).setMaxTwinsPerBundle(maxTwinsPerBundle)) - .to.emit(configHandler, "MaxTwinsPerBundleChanged") - .withArgs(maxTwinsPerBundle, deployer.address); - }); - - it("should update state", async function () { - // Set new max twin per bundle, - await configHandler.connect(deployer).setMaxTwinsPerBundle(maxTwinsPerBundle); - - // Verify that new value is stored - expect(await configHandler.connect(rando).getMaxTwinsPerBundle()).to.equal(maxTwinsPerBundle); - }); - - context("💔 Revert Reasons", async function () { - it("caller is not the admin", async function () { - // Attempt to set new max twin per bundle, expecting revert - await expect(configHandler.connect(rando).setMaxTwinsPerBundle(maxTwinsPerBundle)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); - }); - - it("maxTwinsPerBundle is zero", async function () { - maxTwinsPerBundle = 0; - - await expect(configHandler.connect(deployer).setMaxTwinsPerBundle(maxTwinsPerBundle)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); - }); - }); - }); - - context("👉 setMaxOffersPerBundle()", async function () { - let maxOffersPerBundle; - beforeEach(async function () { - // set new value for max offers per bundle - maxOffersPerBundle = 150; - }); - - it("should emit a MaxOffersPerBundleChanged event", async function () { - // Set new max offer per bundle, testing for the event - await expect(configHandler.connect(deployer).setMaxOffersPerBundle(maxOffersPerBundle)) - .to.emit(configHandler, "MaxOffersPerBundleChanged") - .withArgs(maxOffersPerBundle, deployer.address); - }); - - it("should update state", async function () { - // Set new max offer per bundle, - await configHandler.connect(deployer).setMaxOffersPerBundle(maxOffersPerBundle); - - // Verify that new value is stored - expect(await configHandler.connect(rando).getMaxOffersPerBundle()).to.equal(maxOffersPerBundle); - }); - - context("💔 Revert Reasons", async function () { - it("caller is not the admin", async function () { - // Attempt to set new max offer per bundle, expecting revert - await expect(configHandler.connect(rando).setMaxOffersPerBundle(maxOffersPerBundle)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); - }); - - it("maxOffersPerBundle is zero", async function () { - maxOffersPerBundle = 0; - - await expect(configHandler.connect(deployer).setMaxOffersPerBundle(maxOffersPerBundle)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); - }); - }); - }); - - context("👉 setMaxOffersPerBatch()", async function () { - let maxOffersPerBatch; - beforeEach(async function () { - // set new value for max offers per batch - maxOffersPerBatch = 135; - }); - - it("should emit a MaxOffersPerBatchChanged event", async function () { - // Set new max offer per batch, testing for the event - await expect(configHandler.connect(deployer).setMaxOffersPerBatch(maxOffersPerBatch)) - .to.emit(configHandler, "MaxOffersPerBatchChanged") - .withArgs(maxOffersPerBatch, deployer.address); - }); - - it("should update state", async function () { - // Set new max offer per batch, - await configHandler.connect(deployer).setMaxOffersPerBatch(maxOffersPerBatch); - - // Verify that new value is stored - expect(await configHandler.connect(rando).getMaxOffersPerBatch()).to.equal(maxOffersPerBatch); - }); - - context("💔 Revert Reasons", async function () { - it("caller is not the admin", async function () { - // Attempt to set new max offer per batch, expecting revert - await expect(configHandler.connect(rando).setMaxOffersPerBatch(maxOffersPerBatch)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); - }); - - it("maxOffersPerBatch is zero", async function () { - maxOffersPerBatch = 0; - - await expect(configHandler.connect(deployer).setMaxOffersPerBatch(maxOffersPerBatch)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); - }); - }); - }); - - context("👉 setMaxTokensPerWithdrawal()", async function () { - let maxTokensPerWithdrawal; - beforeEach(async function () { - // set new value for max tokens per withdrawal - maxTokensPerWithdrawal = 598; - }); - - it("should emit a MaxTokensPerWithdrawalChanged event", async function () { - // Set new max tokens per withdrawal, testing for the event - await expect(configHandler.connect(deployer).setMaxTokensPerWithdrawal(maxTokensPerWithdrawal)) - .to.emit(configHandler, "MaxTokensPerWithdrawalChanged") - .withArgs(maxTokensPerWithdrawal, deployer.address); - }); - - it("should update state", async function () { - // Set new max offer tokens per withdrawal - await configHandler.connect(deployer).setMaxTokensPerWithdrawal(maxTokensPerWithdrawal); - - // Verify that new value is stored - expect(await configHandler.connect(rando).getMaxTokensPerWithdrawal()).to.equal(maxTokensPerWithdrawal); - }); - - context("💔 Revert Reasons", async function () { - it("caller is not the admin", async function () { - // Attempt to set new tokens per withdrawal, expecting revert - await expect( - configHandler.connect(rando).setMaxTokensPerWithdrawal(maxTokensPerWithdrawal) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); - }); - - it("maxTokensPerWithdrawal is zero", async function () { - maxTokensPerWithdrawal = 0; - - await expect( - configHandler.connect(deployer).setMaxTokensPerWithdrawal(maxTokensPerWithdrawal) - ).to.revertedWith(RevertReasons.VALUE_ZERO_NOT_ALLOWED); - }); - }); - }); - context("👉 setTokenAddress()", async function () { let token; beforeEach(async function () { @@ -711,85 +511,6 @@ describe("IBosonConfigHandler", function () { }); }); - context("👉 setMaxDisputesPerBatch()", async function () { - let maxDisputesPerBatch; - beforeEach(async function () { - // set new value for max disputes per batch - maxDisputesPerBatch = 135; - }); - - it("should emit a MaxDisputesPerBatchChanged event", async function () { - // Set new max disputes per batch, testing for the event - await expect(configHandler.connect(deployer).setMaxDisputesPerBatch(maxDisputesPerBatch)) - .to.emit(configHandler, "MaxDisputesPerBatchChanged") - .withArgs(maxDisputesPerBatch, deployer.address); - }); - - it("should update state", async function () { - // Set new max disputes per batch, - await configHandler.connect(deployer).setMaxDisputesPerBatch(maxDisputesPerBatch); - - // Verify that new value is stored - expect(await configHandler.connect(rando).getMaxDisputesPerBatch()).to.equal(maxDisputesPerBatch); - }); - - context("💔 Revert Reasons", async function () { - it("caller is not the admin", async function () { - // Attempt to set new max disputes per batch, expecting revert - await expect(configHandler.connect(rando).setMaxDisputesPerBatch(maxDisputesPerBatch)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); - }); - - it("maxDisputesPerBatch is zero", async function () { - maxDisputesPerBatch = 0; - - await expect(configHandler.connect(deployer).setMaxDisputesPerBatch(maxDisputesPerBatch)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); - }); - }); - }); - - context("👉 setMaxFeesPerDisputeResolver()", async function () { - let maxFeesPerDisputeResolver; - beforeEach(async function () { - // set new value - maxFeesPerDisputeResolver = 200; - }); - - it("should emit a MaxFeesPerDisputeResolverChanged event", async function () { - // Set max fees per dispute resolver - await expect(configHandler.connect(deployer).setMaxFeesPerDisputeResolver(maxFeesPerDisputeResolver)) - .to.emit(configHandler, "MaxFeesPerDisputeResolverChanged") - .withArgs(maxFeesPerDisputeResolver, deployer.address); - }); - - it("should update state", async function () { - // Set max fees per dispute resolver - await configHandler.connect(deployer).setMaxFeesPerDisputeResolver(maxFeesPerDisputeResolver); - - // Verify that new value is stored - expect(await configHandler.connect(rando).getMaxFeesPerDisputeResolver()).to.equal(maxFeesPerDisputeResolver); - }); - - context("💔 Revert Reasons", async function () { - it("caller is not the admin", async function () { - // Attempt to set new value, expecting revert - await expect( - configHandler.connect(rando).setMaxFeesPerDisputeResolver(maxFeesPerDisputeResolver) - ).to.revertedWith(RevertReasons.ACCESS_DENIED); - }); - - it("maxFeesPerDisputeResolver is zero", async function () { - maxFeesPerDisputeResolver = 0; - await expect( - configHandler.connect(deployer).setMaxFeesPerDisputeResolver(maxFeesPerDisputeResolver) - ).to.revertedWith(RevertReasons.VALUE_ZERO_NOT_ALLOWED); - }); - }); - }); - context("👉 setMaxEscalationResponsePeriod()", async function () { let maxEscalationResponsePeriod; beforeEach(async function () { @@ -875,45 +596,6 @@ describe("IBosonConfigHandler", function () { }); }); - context("👉 setMaxAllowedSellers()", async function () { - let maxAllowedSellers; - beforeEach(async function () { - // set new value for max allowed sellers - maxAllowedSellers = 222; - }); - - it("should emit a MaxAllowedSellersChanged event", async function () { - // Set new max allowed sellers, testing for the event - await expect(configHandler.connect(deployer).setMaxAllowedSellers(maxAllowedSellers)) - .to.emit(configHandler, "MaxAllowedSellersChanged") - .withArgs(maxAllowedSellers, deployer.address); - }); - - it("should update state", async function () { - // Set new max allowed sellers, - await configHandler.connect(deployer).setMaxAllowedSellers(maxAllowedSellers); - - // Verify that new value is stored - expect(await configHandler.connect(rando).getMaxAllowedSellers()).to.equal(maxAllowedSellers); - }); - - context("💔 Revert Reasons", async function () { - it("caller is not the admin", async function () { - // Attempt to set new max allowed sellers, expecting revert - await expect(configHandler.connect(rando).setMaxAllowedSellers(maxAllowedSellers)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); - }); - - it("maxAllowedSellers is zero", async function () { - maxAllowedSellers = 0; - await expect(configHandler.connect(deployer).setMaxAllowedSellers(maxAllowedSellers)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); - }); - }); - }); - context("👉 setMaxTotalOfferFeePercentage()", async function () { let maxTotalOfferFeePercentage; beforeEach(async function () { @@ -1060,45 +742,6 @@ describe("IBosonConfigHandler", function () { }); }); - context("👉 setMaxExchangesPerBatch()", async function () { - let maxExchangesPerBatch; - beforeEach(async function () { - // set new value for max exchanges per batch - maxExchangesPerBatch = 135; - }); - - it("should emit a MaxExchangesPerBatchChanged event", async function () { - // Set new max exchange per batch, testing for the event - await expect(configHandler.connect(deployer).setMaxExchangesPerBatch(maxExchangesPerBatch)) - .to.emit(configHandler, "MaxExchangesPerBatchChanged") - .withArgs(maxExchangesPerBatch, deployer.address); - }); - - it("should update state", async function () { - // Set new max exchange per batch, - await configHandler.connect(deployer).setMaxExchangesPerBatch(maxExchangesPerBatch); - - // Verify that new value is stored - expect(await configHandler.connect(rando).getMaxExchangesPerBatch()).to.equal(maxExchangesPerBatch); - }); - - context("💔 Revert Reasons", async function () { - it("caller is not the admin", async function () { - // Attempt to set new max exchange per batch, expecting revert - await expect(configHandler.connect(rando).setMaxExchangesPerBatch(maxExchangesPerBatch)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); - }); - - it("maxExchangesPerBatch is zero", async function () { - maxExchangesPerBatch = 0; - await expect(configHandler.connect(deployer).setMaxExchangesPerBatch(maxExchangesPerBatch)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); - }); - }); - }); - context("👉 setMaxResolutionPeriod()", async function () { let maxResolutionPeriod; beforeEach(async function () { @@ -1177,45 +820,6 @@ describe("IBosonConfigHandler", function () { }); }); - context("👉 setMaxPremintedVouchers()", async function () { - let maxPremintedVouchers; - beforeEach(async function () { - // set new value - maxPremintedVouchers = 50000; - }); - - it("should emit a MaxPremintedVouchersChanged event", async function () { - // Set new minumum dispute period - await expect(configHandler.connect(deployer).setMaxPremintedVouchers(maxPremintedVouchers)) - .to.emit(configHandler, "MaxPremintedVouchersChanged") - .withArgs(maxPremintedVouchers, deployer.address); - }); - - it("should update state", async function () { - // Set new minumum dispute period - await configHandler.connect(deployer).setMaxPremintedVouchers(maxPremintedVouchers); - - // Verify that new value is stored - expect(await configHandler.connect(rando).getMaxPremintedVouchers()).to.equal(maxPremintedVouchers); - }); - - context("💔 Revert Reasons", async function () { - it("caller is not the admin", async function () { - // Attempt to set new value, expecting revert - await expect(configHandler.connect(rando).setMaxPremintedVouchers(maxPremintedVouchers)).to.revertedWith( - RevertReasons.ACCESS_DENIED - ); - }); - - it("maxPremintedVouchers is zero", async function () { - maxPremintedVouchers = 0; - await expect(configHandler.connect(deployer).setMaxPremintedVouchers(maxPremintedVouchers)).to.revertedWith( - RevertReasons.VALUE_ZERO_NOT_ALLOWED - ); - }); - }); - }); - context("👉 setAccessControllerAddress()", async function () { let newAccessController; beforeEach(async function () { @@ -1283,38 +887,10 @@ describe("IBosonConfigHandler", function () { protocolFeeFlatBoson, "Invalid flat boson fee" ); - expect(await configHandler.connect(rando).getMaxOffersPerGroup()).to.equal( - maxOffersPerGroup, - "Invalid max offers per group" - ); - expect(await configHandler.connect(rando).getMaxTwinsPerBundle()).to.equal( - maxTwinsPerBundle, - "Invalid max twins per bundle" - ); - expect(await configHandler.connect(rando).getMaxOffersPerBundle()).to.equal( - maxOffersPerBundle, - "Invalid max offers per bundle" - ); - expect(await configHandler.connect(rando).getMaxOffersPerBatch()).to.equal( - maxOffersPerBatch, - "Invalid max offers per batch" - ); - expect(await configHandler.connect(rando).getMaxTokensPerWithdrawal()).to.equal( - maxTokensPerWithdrawal, - "Invalid max tokens per withdrawal" - ); - expect(await configHandler.connect(rando).getMaxFeesPerDisputeResolver()).to.equal( - maxFeesPerDisputeResolver, - "Invalid max fees per dispute resolver" - ); expect(await configHandler.connect(rando).getMaxEscalationResponsePeriod()).to.equal( maxEscalationResponsePeriod, "Invalid max escalatio response period" ); - expect(await configHandler.connect(rando).getMaxDisputesPerBatch()).to.equal( - maxDisputesPerBatch, - "Invalid max disputes per batch" - ); expect(await configHandler.connect(rando).getMaxAllowedSellers()).to.equal( maxAllowedSellers, "Invalid max allowed sellers" @@ -1344,10 +920,6 @@ describe("IBosonConfigHandler", function () { ethers.constants.AddressZero, "Invalid auth token contract address" ); - expect(await configHandler.connect(rando).getMaxExchangesPerBatch()).to.equal( - maxExchangesPerBatch, - "Invalid max exchanges per batch" - ); expect(await configHandler.connect(rando).getMaxResolutionPeriod()).to.equal( maxResolutionPeriod, "Invalid max resolution period" @@ -1356,10 +928,6 @@ describe("IBosonConfigHandler", function () { minDisputePeriod, "Invalid min dispute period" ); - expect(await configHandler.connect(rando).getMaxPremintedVouchers()).to.equal( - maxPremintedVouchers, - "Invalid max preminted vouchers" - ); }); }); });