From e2e43c03a9daf7eb1579534e5c5bacdb4c24285c Mon Sep 17 00:00:00 2001 From: Ana Julia Date: Mon, 31 Jul 2023 21:25:28 -0300 Subject: [PATCH 1/9] Remediate PHF-01M --- contracts/interfaces/handlers/IBosonPauseHandler.sol | 2 -- contracts/protocol/facets/PauseHandlerFacet.sol | 5 ----- 2 files changed, 7 deletions(-) diff --git a/contracts/interfaces/handlers/IBosonPauseHandler.sol b/contracts/interfaces/handlers/IBosonPauseHandler.sol index ad4b76dbc..6d103db55 100644 --- a/contracts/interfaces/handlers/IBosonPauseHandler.sol +++ b/contracts/interfaces/handlers/IBosonPauseHandler.sol @@ -19,7 +19,6 @@ interface IBosonPauseHandler is IBosonPauseEvents { * * Reverts if: * - Caller does not have PAUSER role - * - A region is specified more than once * * @param _regions - an array of regions to pause. See: {BosonTypes.PausableRegion} */ @@ -33,7 +32,6 @@ interface IBosonPauseHandler is IBosonPauseEvents { * Reverts if: * - Caller does not have PAUSER role * - Protocol is not currently paused - * - A region is specified more than once * * @param _regions - an array of regions to pause. See: {BosonTypes.PausableRegion} */ diff --git a/contracts/protocol/facets/PauseHandlerFacet.sol b/contracts/protocol/facets/PauseHandlerFacet.sol index e116e64e3..207fb113e 100644 --- a/contracts/protocol/facets/PauseHandlerFacet.sol +++ b/contracts/protocol/facets/PauseHandlerFacet.sol @@ -30,7 +30,6 @@ contract PauseHandlerFacet is ProtocolBase, IBosonPauseHandler { * * Reverts if: * - Caller does not have PAUSER role - * - A region is specified more than once * * @param _regions - an array of regions to pause. See: {BosonTypes.PausableRegion} */ @@ -49,7 +48,6 @@ contract PauseHandlerFacet is ProtocolBase, IBosonPauseHandler { * Reverts if: * - Caller does not have PAUSER role * - Protocol is not currently paused - * - A region is specified more than once */ function unpause(BosonTypes.PausableRegion[] calldata _regions) external onlyRole(PAUSER) nonReentrant { // Cache protocol status for reference @@ -105,9 +103,6 @@ contract PauseHandlerFacet is ProtocolBase, IBosonPauseHandler { * * Toggle all regions if none are specified. * - * Reverts if: - * - A region is specified more than once - * * @param _regions - an array of regions to pause/unpause. See: {BosonTypes.PausableRegion} * @param _pause - a boolean indicating whether to pause (true) or unpause (false) */ From adc244ac0bcff4940a7db367b49a13afffc4194a Mon Sep 17 00:00:00 2001 From: Ana Julia Date: Mon, 31 Jul 2023 21:35:41 -0300 Subject: [PATCH 2/9] Remedit CHF-01M --- contracts/protocol/facets/ConfigHandlerFacet.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contracts/protocol/facets/ConfigHandlerFacet.sol b/contracts/protocol/facets/ConfigHandlerFacet.sol index 7f6d531d0..0193744fa 100644 --- a/contracts/protocol/facets/ConfigHandlerFacet.sol +++ b/contracts/protocol/facets/ConfigHandlerFacet.sol @@ -427,6 +427,8 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { function setMinResolutionPeriod(uint256 _minResolutionPeriod) public override onlyRole(ADMIN) nonReentrant { // Make sure _maxResolutionPeriod is greater than 0 checkNonZero(_minResolutionPeriod); + // Make sure _minResolutionPeriod is less than _maxResolutionPeriod + require(_minResolutionPeriod < protocolLimits().maxResolutionPeriod, MIN_RESOLUTION_PERIOD_INVALID); protocolLimits().minResolutionPeriod = _minResolutionPeriod; emit MinResolutionPeriodChanged(_minResolutionPeriod, msgSender()); @@ -455,6 +457,8 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { function setMaxResolutionPeriod(uint256 _maxResolutionPeriod) public override onlyRole(ADMIN) nonReentrant { // Make sure _maxResolutionPeriod is greater than 0 checkNonZero(_maxResolutionPeriod); + // Make sure _maxResolutionPeriod is greater than _minResolutionPeriod + require(_maxResolutionPeriod > protocolLimits().minResolutionPeriod, INVALID_RESOLUTION_PERIOD); protocolLimits().maxResolutionPeriod = _maxResolutionPeriod; emit MaxResolutionPeriodChanged(_maxResolutionPeriod, msgSender()); From 54ed6e0bbc68bd49dcb40fda89205ddef702b351 Mon Sep 17 00:00:00 2001 From: Ana Julia Date: Tue, 1 Aug 2023 20:08:03 -0300 Subject: [PATCH 3/9] Adding tests to validate sanitization of resolution periods --- contracts/mock/Foreign20.sol | 4 ++ .../protocol/facets/ConfigHandlerFacet.sol | 5 +- test/protocol/ConfigHandlerTest.js | 60 ++++++++++++++++++- test/protocol/OfferHandlerTest.js | 1 + 4 files changed, 67 insertions(+), 3 deletions(-) diff --git a/contracts/mock/Foreign20.sol b/contracts/mock/Foreign20.sol index 5db0439f8..823b1d68b 100644 --- a/contracts/mock/Foreign20.sol +++ b/contracts/mock/Foreign20.sol @@ -61,6 +61,10 @@ contract Foreign20 is ERC20Pausable, MockNativeMetaTransaction { function destruct() public { selfdestruct(payable(msg.sender)); } + + function allowance(address owner, address spender) public view override returns (uint256) { + return super.allowance(owner, spender); + } } /** diff --git a/contracts/protocol/facets/ConfigHandlerFacet.sol b/contracts/protocol/facets/ConfigHandlerFacet.sol index 0193744fa..c9179bded 100644 --- a/contracts/protocol/facets/ConfigHandlerFacet.sol +++ b/contracts/protocol/facets/ConfigHandlerFacet.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.18; +import "hardhat/console.sol"; import "../../domain/BosonConstants.sol"; import { IBosonConfigHandler } from "../../interfaces/handlers/IBosonConfigHandler.sol"; import { IAccessControl } from "../../interfaces/IAccessControl.sol"; @@ -43,8 +44,8 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { setBuyerEscalationDepositPercentage(_fees.buyerEscalationDepositPercentage); setMaxTotalOfferFeePercentage(_limits.maxTotalOfferFeePercentage); setMaxRoyaltyPecentage(_limits.maxRoyaltyPecentage); - setMinResolutionPeriod(_limits.minResolutionPeriod); setMaxResolutionPeriod(_limits.maxResolutionPeriod); + setMinResolutionPeriod(_limits.minResolutionPeriod); setMinDisputePeriod(_limits.minDisputePeriod); // Initialize protocol counters @@ -428,7 +429,7 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { // Make sure _maxResolutionPeriod is greater than 0 checkNonZero(_minResolutionPeriod); // Make sure _minResolutionPeriod is less than _maxResolutionPeriod - require(_minResolutionPeriod < protocolLimits().maxResolutionPeriod, MIN_RESOLUTION_PERIOD_INVALID); + require(_minResolutionPeriod < protocolLimits().maxResolutionPeriod, INVALID_RESOLUTION_PERIOD); protocolLimits().minResolutionPeriod = _minResolutionPeriod; emit MinResolutionPeriodChanged(_minResolutionPeriod, msgSender()); diff --git a/test/protocol/ConfigHandlerTest.js b/test/protocol/ConfigHandlerTest.js index e2199b0ce..3f1e99030 100644 --- a/test/protocol/ConfigHandlerTest.js +++ b/test/protocol/ConfigHandlerTest.js @@ -1,7 +1,6 @@ const { ethers } = require("hardhat"); const { getSigners, getContractAt, ZeroAddress, parseUnits } = ethers; const { expect } = require("chai"); - const Role = require("../../scripts/domain/Role"); const { getInterfaceIds } = require("../../scripts/config/supported-interfaces.js"); const { RevertReasons } = require("../../scripts/config/revert-reasons.js"); @@ -718,6 +717,55 @@ describe("IBosonConfigHandler", function () { }); }); + context("👉 setMinResolutionPeriod()", async function () { + let minResolutionPeriod; + beforeEach(async function () { + // set new value + minResolutionPeriod = oneWeek; + }); + + it("should emit a MinResolutionPeriodChanged event", async function () { + // Set new resolution period + await expect(configHandler.connect(deployer).setMinResolutionPeriod(minResolutionPeriod)) + .to.emit(configHandler, "MinResolutionPeriodChanged") + .withArgs(minResolutionPeriod, await deployer.getAddress()); + }); + + it("should update state", async function () { + // Set new resolution period + await configHandler.connect(deployer).setMinResolutionPeriod(minResolutionPeriod); + + // Verify that new value is stored + expect(await configHandler.connect(rando).getMinResolutionPeriod()).to.equal(minResolutionPeriod); + }); + + context("💔 Revert Reasons", async function () { + it("caller is not the admin", async function () { + // Attempt to set new value, expecting revert + await expect(configHandler.connect(rando).setMinResolutionPeriod(minResolutionPeriod)).to.revertedWith( + RevertReasons.ACCESS_DENIED + ); + }); + + it("minResolutionPeriod is zero", async function () { + minResolutionPeriod = 0; + await expect(configHandler.connect(deployer).setMinResolutionPeriod(minResolutionPeriod)).to.revertedWith( + RevertReasons.VALUE_ZERO_NOT_ALLOWED + ); + }); + + it("minResolutionPeriod is greater than maxResolutionPeriod", async function () { + const maxResolutionPeriod = oneMonth; + await configHandler.connect(deployer).setMaxResolutionPeriod(maxResolutionPeriod); + + minResolutionPeriod = maxResolutionPeriod + 1n; + await expect(configHandler.connect(deployer).setMinResolutionPeriod(minResolutionPeriod)).to.revertedWith( + RevertReasons.INVALID_RESOLUTION_PERIOD + ); + }); + }); + }); + context("👉 setMaxResolutionPeriod()", async function () { let maxResolutionPeriod; beforeEach(async function () { @@ -754,6 +802,16 @@ describe("IBosonConfigHandler", function () { RevertReasons.VALUE_ZERO_NOT_ALLOWED ); }); + + it("maxResolutionPeriod is less than minResolutionPeriod", async function () { + const minResolutionPeriod = oneWeek; + await configHandler.connect(deployer).setMinResolutionPeriod(minResolutionPeriod); + + const maxResolutionPeriod = minResolutionPeriod - 1n; + await expect(configHandler.connect(deployer).setMaxResolutionPeriod(maxResolutionPeriod)).to.revertedWith( + RevertReasons.INVALID_RESOLUTION_PERIOD + ); + }); }); }); diff --git a/test/protocol/OfferHandlerTest.js b/test/protocol/OfferHandlerTest.js index f913514ad..4eed7e1f0 100644 --- a/test/protocol/OfferHandlerTest.js +++ b/test/protocol/OfferHandlerTest.js @@ -737,6 +737,7 @@ describe("IBosonOfferHandler", function () { }); it("Resolution period is greater than protocol max resolution period", async function () { + await configHandler.setMinResolutionPeriod(oneDay - 1n); // Set max resolution period to 1 day await configHandler.setMaxResolutionPeriod(oneDay); // 24 hours From d21320f997f008803f00f254a1aa25afe0312183 Mon Sep 17 00:00:00 2001 From: Ana Julia Date: Tue, 1 Aug 2023 20:30:44 -0300 Subject: [PATCH 4/9] Remediate PIH-02M --- .../protocol/facets/ConfigHandlerFacet.sol | 1 - .../ProtocolInitializationHandlerFacet.sol | 6 ++++- .../ProtocolInitializationHandlerTest.js | 23 ++++++++++++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/contracts/protocol/facets/ConfigHandlerFacet.sol b/contracts/protocol/facets/ConfigHandlerFacet.sol index c9179bded..823e4f9a3 100644 --- a/contracts/protocol/facets/ConfigHandlerFacet.sol +++ b/contracts/protocol/facets/ConfigHandlerFacet.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.18; -import "hardhat/console.sol"; import "../../domain/BosonConstants.sol"; import { IBosonConfigHandler } from "../../interfaces/handlers/IBosonConfigHandler.sol"; import { IAccessControl } from "../../interfaces/IAccessControl.sol"; diff --git a/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol b/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol index deacf4746..967f3035a 100644 --- a/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol +++ b/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol @@ -143,10 +143,11 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl * Reverts if: * - Current version is not 2.2.1 * - There are already twins. This version adds a new mapping for twins which make it incompatible with previous versions. - * - minResolutionPeriond is not present in _initializationData parameter + * - minResolutionPeriod is not present in _initializationData parameter * - length of seller creators does not match the length of seller ids * - if some of seller creators is zero address * - if some of seller ids does not bellong to a seller + * - if minResolutionPeriod is greater than maxResolutionPeriod * * @param _initializationData - data representing uint256 _minResolutionPeriod, uint256[] memory sellerIds, address[] memory sellerCreators */ @@ -161,6 +162,9 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl (uint256, uint256[], address[]) ); + // make sure _minResolutionPeriod is less than maxResolutionPeriod + require(protocolLimits().maxResolutionPeriod > _minResolutionPeriod, INVALID_RESOLUTION_PERIOD); + // Initialize limits.maxPremintedVouchers (configHandlerFacet initializer) require(_minResolutionPeriod != 0, VALUE_ZERO_NOT_ALLOWED); protocolLimits().minResolutionPeriod = _minResolutionPeriod; diff --git a/test/protocol/ProtocolInitializationHandlerTest.js b/test/protocol/ProtocolInitializationHandlerTest.js index 4a3bfe7a2..4d59a3d3c 100644 --- a/test/protocol/ProtocolInitializationHandlerTest.js +++ b/test/protocol/ProtocolInitializationHandlerTest.js @@ -18,7 +18,7 @@ const { mockTwin, mockSeller, mockAuthToken, mockVoucherInitValues } = require(" const { deployProtocolDiamond } = require("../../scripts/util/deploy-protocol-diamond.js"); const { deployAndCutFacets, deployProtocolFacets } = require("../../scripts/util/deploy-protocol-handler-facets"); const { getInterfaceIds, interfaceImplementers } = require("../../scripts/config/supported-interfaces"); -const { maxPriorityFeePerGas, oneWeek } = require("../util/constants"); +const { maxPriorityFeePerGas, oneWeek, oneMonth } = require("../util/constants"); const { getFees } = require("../../scripts/util/utils"); const { getFacetAddCut, getFacetReplaceCut } = require("../../scripts/util/diamond-utils"); @@ -831,6 +831,27 @@ describe("ProtocolInitializationHandler", async function () { ).to.be.revertedWith(RevertReasons.VALUE_ZERO_NOT_ALLOWED); }); + it("Min resolution period is greater than max resolution period", async function () { + version = "2.3.0"; + console.log("oneMonth", oneMonth); + await configHandler.connect(deployer).setMaxResolutionPeriod(oneMonth); + minResolutionPeriod = oneMonth + 1n; + console.log("minResolutionPeriod", minResolutionPeriod); + initializationData = abiCoder.encode(["uint256", "uint256[]", "address[]"], [minResolutionPeriod, [], []]); + calldataProtocolInitialization = deployedProtocolInitializationHandlerFacet.interface.encodeFunctionData( + "initialize", + [encodeBytes32String(version), [], [], true, initializationData, [], []] + ); + + await expect( + diamondCutFacet.diamondCut( + [facetCut], + deployedProtocolInitializationHandlerFacetAddress, + calldataProtocolInitialization + ) + ).to.be.revertedWith(RevertReasons.INVALID_RESOLUTION_PERIOD); + }); + it("sellerIds and sellerCreators length mismatch", async function () { version = "2.3.0"; initializationData = abiCoder.encode(["uint256", "uint256[]", "address[]"], [minResolutionPeriod, [1], []]); From 9c38704c309ba19fa7ac20c321141f46fd55795a Mon Sep 17 00:00:00 2001 From: Ana Julia Date: Wed, 2 Aug 2023 10:20:41 -0300 Subject: [PATCH 5/9] Review fixes --- contracts/mock/Foreign20.sol | 4 ---- contracts/protocol/facets/ConfigHandlerFacet.sol | 16 ++++++++++++---- .../ProtocolInitializationHandlerFacet.sol | 9 ++++++--- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/contracts/mock/Foreign20.sol b/contracts/mock/Foreign20.sol index 823b1d68b..5db0439f8 100644 --- a/contracts/mock/Foreign20.sol +++ b/contracts/mock/Foreign20.sol @@ -61,10 +61,6 @@ contract Foreign20 is ERC20Pausable, MockNativeMetaTransaction { function destruct() public { selfdestruct(payable(msg.sender)); } - - function allowance(address owner, address spender) public view override returns (uint256) { - return super.allowance(owner, spender); - } } /** diff --git a/contracts/protocol/facets/ConfigHandlerFacet.sol b/contracts/protocol/facets/ConfigHandlerFacet.sol index 823e4f9a3..a30dcf2d3 100644 --- a/contracts/protocol/facets/ConfigHandlerFacet.sol +++ b/contracts/protocol/facets/ConfigHandlerFacet.sol @@ -427,10 +427,14 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { function setMinResolutionPeriod(uint256 _minResolutionPeriod) public override onlyRole(ADMIN) nonReentrant { // Make sure _maxResolutionPeriod is greater than 0 checkNonZero(_minResolutionPeriod); + + // cache protocol limits + ProtocolLib.ProtocolLimits storage limits = protocolLimits(); + // Make sure _minResolutionPeriod is less than _maxResolutionPeriod - require(_minResolutionPeriod < protocolLimits().maxResolutionPeriod, INVALID_RESOLUTION_PERIOD); + require(_minResolutionPeriod <= limits.maxResolutionPeriod, INVALID_RESOLUTION_PERIOD); - protocolLimits().minResolutionPeriod = _minResolutionPeriod; + limits.minResolutionPeriod = _minResolutionPeriod; emit MinResolutionPeriodChanged(_minResolutionPeriod, msgSender()); } @@ -457,10 +461,14 @@ contract ConfigHandlerFacet is IBosonConfigHandler, ProtocolBase { function setMaxResolutionPeriod(uint256 _maxResolutionPeriod) public override onlyRole(ADMIN) nonReentrant { // Make sure _maxResolutionPeriod is greater than 0 checkNonZero(_maxResolutionPeriod); + + // cache protocol limits + ProtocolLib.ProtocolLimits storage limits = protocolLimits(); + // Make sure _maxResolutionPeriod is greater than _minResolutionPeriod - require(_maxResolutionPeriod > protocolLimits().minResolutionPeriod, INVALID_RESOLUTION_PERIOD); + require(_maxResolutionPeriod >= limits.minResolutionPeriod, INVALID_RESOLUTION_PERIOD); - protocolLimits().maxResolutionPeriod = _maxResolutionPeriod; + limits.maxResolutionPeriod = _maxResolutionPeriod; emit MaxResolutionPeriodChanged(_maxResolutionPeriod, msgSender()); } diff --git a/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol b/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol index 967f3035a..5196864a1 100644 --- a/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol +++ b/contracts/protocol/facets/ProtocolInitializationHandlerFacet.sol @@ -48,7 +48,7 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl * - For upgrade to v2.2.0: * - If versions is set already * - If _initializationData cannot be decoded to uin256 - * - If _initializationData is represents value 0 + * - If _initializationData is represents value * * @param _version - version of the protocol * @param _addresses - array of facet addresses to call initialize methods @@ -162,12 +162,15 @@ contract ProtocolInitializationHandlerFacet is IBosonProtocolInitializationHandl (uint256, uint256[], address[]) ); + // cache protocol limits + ProtocolLib.ProtocolLimits storage limits = protocolLimits(); + // make sure _minResolutionPeriod is less than maxResolutionPeriod - require(protocolLimits().maxResolutionPeriod > _minResolutionPeriod, INVALID_RESOLUTION_PERIOD); + require(limits.maxResolutionPeriod >= _minResolutionPeriod, INVALID_RESOLUTION_PERIOD); // Initialize limits.maxPremintedVouchers (configHandlerFacet initializer) require(_minResolutionPeriod != 0, VALUE_ZERO_NOT_ALLOWED); - protocolLimits().minResolutionPeriod = _minResolutionPeriod; + limits.minResolutionPeriod = _minResolutionPeriod; emit MinResolutionPeriodChanged(_minResolutionPeriod, msgSender()); // Initialize sellerCreators From 1a02b3edd0a56e4d03df1f3315cfbfe49389278b Mon Sep 17 00:00:00 2001 From: zajck Date: Thu, 3 Aug 2023 15:46:40 +0200 Subject: [PATCH 6/9] fix #731 --- .../protocol/clients/voucher/BosonVoucher.sol | 7 +- test/protocol/OrchestrationHandlerTest.js | 100 ++++++++++++------ test/protocol/SellerHandlerTest.js | 39 ++++--- 3 files changed, 101 insertions(+), 45 deletions(-) diff --git a/contracts/protocol/clients/voucher/BosonVoucher.sol b/contracts/protocol/clients/voucher/BosonVoucher.sol index 635710945..5b584974a 100644 --- a/contracts/protocol/clients/voucher/BosonVoucher.sol +++ b/contracts/protocol/clients/voucher/BosonVoucher.sol @@ -73,7 +73,12 @@ contract BosonVoucherBase is IBosonVoucher, BeaconClientBase, OwnableUpgradeable address _newOwner, VoucherInitValues calldata voucherInitValues ) public initializer { - string memory sellerId = string.concat(Strings.toString(_sellerId), "_", Strings.toString(_collectionIndex)); + string memory sellerId = string.concat( + "S", + Strings.toString(_sellerId), + "_C", + Strings.toString(_collectionIndex) + ); string memory voucherName = string.concat(VOUCHER_NAME, " ", sellerId); string memory voucherSymbol = string.concat(VOUCHER_SYMBOL, "_", sellerId); diff --git a/test/protocol/OrchestrationHandlerTest.js b/test/protocol/OrchestrationHandlerTest.js index aa667f85e..f4d8d1a89 100644 --- a/test/protocol/OrchestrationHandlerTest.js +++ b/test/protocol/OrchestrationHandlerTest.js @@ -777,9 +777,12 @@ describe("IBosonOrchestrationHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); }); @@ -820,9 +823,12 @@ describe("IBosonOrchestrationHandler", function () { bosonVoucher = await ethers.getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); @@ -883,9 +889,12 @@ describe("IBosonOrchestrationHandler", function () { bosonVoucher = await ethers.getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); @@ -1396,11 +1405,11 @@ describe("IBosonOrchestrationHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); expect(await bosonVoucher.name()).to.equal( - VOUCHER_NAME + " " + seller.id + "_0", + VOUCHER_NAME + " S" + seller.id + "_C0", "Wrong voucher client name" ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); const returnedRange = Range.fromStruct(await bosonVoucher.getRangeByOfferId(offer.id)); @@ -5583,9 +5592,12 @@ describe("IBosonOrchestrationHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); }); @@ -5626,9 +5638,12 @@ describe("IBosonOrchestrationHandler", function () { // Voucher clone contract bosonVoucher = await ethers.getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); @@ -5689,9 +5704,12 @@ describe("IBosonOrchestrationHandler", function () { // Voucher clone contract bosonVoucher = await ethers.getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); @@ -6067,11 +6085,11 @@ describe("IBosonOrchestrationHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); expect(await bosonVoucher.name()).to.equal( - VOUCHER_NAME + " " + seller.id + "_0", + VOUCHER_NAME + " S" + seller.id + "_C0", "Wrong voucher client name" ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); const returnedRange = Range.fromStruct(await bosonVoucher.getRangeByOfferId(offer.id)); @@ -6417,9 +6435,12 @@ describe("IBosonOrchestrationHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); }); @@ -6463,9 +6484,12 @@ describe("IBosonOrchestrationHandler", function () { // Voucher clone contract bosonVoucher = await ethers.getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); @@ -6529,9 +6553,12 @@ describe("IBosonOrchestrationHandler", function () { // Voucher clone contract bosonVoucher = await ethers.getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); @@ -6978,11 +7005,11 @@ describe("IBosonOrchestrationHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); expect(await bosonVoucher.name()).to.equal( - VOUCHER_NAME + " " + seller.id + "_0", + VOUCHER_NAME + " S" + seller.id + "_C0", "Wrong voucher client name" ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); const returnedRange = Range.fromStruct(await bosonVoucher.getRangeByOfferId(offer.id)); @@ -7397,9 +7424,12 @@ describe("IBosonOrchestrationHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); }); @@ -7444,9 +7474,12 @@ describe("IBosonOrchestrationHandler", function () { // Voucher clone contract bosonVoucher = await ethers.getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); @@ -7511,9 +7544,12 @@ describe("IBosonOrchestrationHandler", function () { // Voucher clone contract bosonVoucher = await ethers.getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); @@ -8015,11 +8051,11 @@ describe("IBosonOrchestrationHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); expect(await bosonVoucher.name()).to.equal( - VOUCHER_NAME + " " + seller.id + "_0", + VOUCHER_NAME + " S" + seller.id + "_C0", "Wrong voucher client name" ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); const returnedRange = Range.fromStruct(await bosonVoucher.getRangeByOfferId(offer.id)); diff --git a/test/protocol/SellerHandlerTest.js b/test/protocol/SellerHandlerTest.js index af1b44ef0..5464dd19a 100644 --- a/test/protocol/SellerHandlerTest.js +++ b/test/protocol/SellerHandlerTest.js @@ -254,9 +254,12 @@ describe("SellerHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); }); @@ -271,9 +274,12 @@ describe("SellerHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); @@ -308,9 +314,12 @@ describe("SellerHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); @@ -372,9 +381,12 @@ describe("SellerHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCloneAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_0", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C0", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_0", + VOUCHER_SYMBOL + "_S" + seller.id + "_C0", "Wrong voucher client symbol" ); }); @@ -2821,9 +2833,12 @@ describe("SellerHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCollectionAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); - expect(await bosonVoucher.name()).to.equal(VOUCHER_NAME + " " + seller.id + "_1", "Wrong voucher client name"); + expect(await bosonVoucher.name()).to.equal( + VOUCHER_NAME + " S" + seller.id + "_C1", + "Wrong voucher client name" + ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_1", + VOUCHER_SYMBOL + "_S" + seller.id + "_C1", "Wrong voucher client symbol" ); }); @@ -2879,11 +2894,11 @@ describe("SellerHandler", function () { bosonVoucher = await getContractAt("IBosonVoucher", expectedCollectionAddress); expect(await bosonVoucher.contractURI()).to.equal(contractURI, "Wrong contract URI"); expect(await bosonVoucher.name()).to.equal( - VOUCHER_NAME + " " + seller.id + "_" + i, + VOUCHER_NAME + " S" + seller.id + "_C" + i, "Wrong voucher client name" ); expect(await bosonVoucher.symbol()).to.equal( - VOUCHER_SYMBOL + "_" + seller.id + "_" + i, + VOUCHER_SYMBOL + "_S" + seller.id + "_C" + i, "Wrong voucher client symbol" ); } From 9070c0484634cec7bec793808a43ca20616d889a Mon Sep 17 00:00:00 2001 From: Klemen <64400885+zajck@users.noreply.github.com> Date: Tue, 8 Aug 2023 15:50:03 +0200 Subject: [PATCH 7/9] fix #730 (#748) Co-authored-by: Mischa --- .../protocol/facets/SellerHandlerFacet.sol | 4 +- test/protocol/SellerHandlerTest.js | 86 +++++++++++-------- 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/contracts/protocol/facets/SellerHandlerFacet.sol b/contracts/protocol/facets/SellerHandlerFacet.sol index 5ec42b6ac..0ed27c459 100644 --- a/contracts/protocol/facets/SellerHandlerFacet.sol +++ b/contracts/protocol/facets/SellerHandlerFacet.sol @@ -274,9 +274,9 @@ contract SellerHandlerFacet is SellerBase { IBosonVoucher(lookups.cloneAddress[_sellerId]).transferOwnership(sender); // default voucher contract Collection[] storage sellersAdditionalCollections = lookups.additionalCollections[_sellerId]; uint256 collectionCount = sellersAdditionalCollections.length; - for (i = 0; i < collectionCount; i++) { + for (uint256 j = 0; j < collectionCount; j++) { // Additional collections (if they exist) - IBosonVoucher(sellersAdditionalCollections[i].collectionAddress).transferOwnership(sender); + IBosonVoucher(sellersAdditionalCollections[j].collectionAddress).transferOwnership(sender); } // Store new seller id by assistant mapping diff --git a/test/protocol/SellerHandlerTest.js b/test/protocol/SellerHandlerTest.js index af1b44ef0..3c8ce92fa 100644 --- a/test/protocol/SellerHandlerTest.js +++ b/test/protocol/SellerHandlerTest.js @@ -2553,47 +2553,65 @@ describe("SellerHandler", function () { expect(await bosonVoucher.owner()).to.equal(other1.address); }); - it("Transfers ownerships of all additional collections", async function () { - const expectedDefaultAddress = calculateCloneAddress( - await accountHandler.getAddress(), - beaconProxyAddress, - admin.address, - "" - ); // default - bosonVoucher = await getContractAt("OwnableUpgradeable", expectedDefaultAddress); - - const additionalCollections = []; - // create 3 additional collections - for (let i = 0; i < 3; i++) { - const externalId = `Brand${i}`; - voucherInitValues.contractURI = `https://brand${i}.com`; - const expectedCollectionAddress = calculateCloneAddress( + context("Multiple collections", async function () { + let additionalCollections = []; + beforeEach(async function () { + const expectedDefaultAddress = calculateCloneAddress( await accountHandler.getAddress(), beaconProxyAddress, admin.address, - externalId - ); - await accountHandler.connect(assistant).createNewCollection(externalId, voucherInitValues); - additionalCollections.push(await getContractAt("OwnableUpgradeable", expectedCollectionAddress)); - } + "" + ); // default + bosonVoucher = await getContractAt("OwnableUpgradeable", expectedDefaultAddress); + + // create 3 additional collections + for (let i = 0; i < 3; i++) { + const externalId = `Brand${i}`; + voucherInitValues.contractURI = `https://brand${i}.com`; + const expectedCollectionAddress = calculateCloneAddress( + await accountHandler.getAddress(), + beaconProxyAddress, + admin.address, + externalId + ); + await accountHandler.connect(assistant).createNewCollection(externalId, voucherInitValues); + additionalCollections.push(await getContractAt("OwnableUpgradeable", expectedCollectionAddress)); + } + }); - // original voucher and collections contract owner - expect(await bosonVoucher.owner()).to.equal(assistant.address); - for (const collection of additionalCollections) { - expect(await collection.owner()).to.equal(assistant.address); - } + it("Transfers ownerships of all additional collections", async function () { + // original voucher and collections contract owner + expect(await bosonVoucher.owner()).to.equal(assistant.address); + for (const collection of additionalCollections) { + expect(await collection.owner()).to.equal(assistant.address); + } - seller.assistant = other1.address; - sellerStruct = seller.toStruct(); + seller.assistant = other1.address; + sellerStruct = seller.toStruct(); - await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); - await accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]); + await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); + await accountHandler.connect(other1).optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant]); - // new voucher and collections contract owner - expect(await bosonVoucher.owner()).to.equal(other1.address); - for (const collection of additionalCollections) { - expect(await collection.owner()).to.equal(other1.address); - } + // new voucher and collections contract owner + expect(await bosonVoucher.owner()).to.equal(other1.address); + for (const collection of additionalCollections) { + expect(await collection.owner()).to.equal(other1.address); + } + }); + + it("Update of other fields work", async function () { + seller.assistant = seller.admin = other1.address; + sellerStruct = seller.toStruct(); + + await accountHandler.connect(admin).updateSeller(seller, emptyAuthToken); + await accountHandler + .connect(other1) + .optInToSellerUpdate(seller.id, [SellerUpdateFields.Assistant, SellerUpdateFields.Admin]); + + const [, returnedSeller] = await accountHandler.getSeller(seller.id); + expect(returnedSeller.assistant).to.equal(seller.assistant); + expect(returnedSeller.admin).to.equal(seller.admin); + }); }); context("💔 Revert Reasons", async function () { From c14a0c56183d3ab264d2222ccd34ebf97e590f70 Mon Sep 17 00:00:00 2001 From: Mischa Date: Fri, 11 Aug 2023 09:56:14 +0100 Subject: [PATCH 8/9] This updates the bug bounty to our own one --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a7f9c1c9c..e6eae1a69 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Done or in progress are: We welcome contributions! Until now, Boson Protocol has been largely worked on by a small dedicated team. However, the ultimate goal is for all of the Boson Protocol repositories to be fully owned by the community and contributors. Issues, pull requests, suggestions, and any sort of involvement are more than welcome. -If you have noticed a bug, please report it via our [Bug Bounty program](https://immunefi.com/bounty/bosonprotocol/). +If you have noticed a bug, please report it via our [Bug Bounty program](https://github.com/bosonprotocol/community/blob/main/BugBountyProgram.md). Questions and feedback are always welcome, we will use them to improve our offering. From c6b9471c132c7a7d19ae572d70bd0cc781d5903b Mon Sep 17 00:00:00 2001 From: Klemen <64400885+zajck@users.noreply.github.com> Date: Mon, 14 Aug 2023 16:46:05 +0200 Subject: [PATCH 9/9] fix #734 (#752) Co-authored-by: Mischa Co-authored-by: Ana Julia Bittencourt --- .../protocol/facets/ExchangeHandlerFacet.sol | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/contracts/protocol/facets/ExchangeHandlerFacet.sol b/contracts/protocol/facets/ExchangeHandlerFacet.sol index 01dca6bab..811c2e943 100644 --- a/contracts/protocol/facets/ExchangeHandlerFacet.sol +++ b/contracts/protocol/facets/ExchangeHandlerFacet.sol @@ -989,8 +989,13 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase { ProtocolLib.ProtocolLookups storage lookups = protocolLookups(); if (_condition.method == EvaluationMethod.SpecificToken) { + // Cache conditionalCommitsByTokenId mapping for reference + mapping(uint256 => uint256) storage conditionalCommitsByTokenId = lookups.conditionalCommitsByTokenId[ + _tokenId + ]; + // How many times has this token id been used to commit to offers in the group? - uint256 commitCount = lookups.conditionalCommitsByTokenId[_tokenId][_groupId]; + uint256 commitCount = conditionalCommitsByTokenId[_groupId]; require(commitCount < _condition.maxCommits, MAX_COMMITS_TOKEN_REACHED); @@ -998,11 +1003,16 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase { if (allow) { // Increment number of commits to the group for this token id if they are allowed to commit - lookups.conditionalCommitsByTokenId[_tokenId][_groupId] = ++commitCount; + conditionalCommitsByTokenId[_groupId] = ++commitCount; } } else if (_condition.method == EvaluationMethod.Threshold) { + // Cache conditionalCommitsByAddress mapping for reference + mapping(uint256 => uint256) storage conditionalCommitsByAddress = lookups.conditionalCommitsByAddress[ + _buyer + ]; + // How many times has this address committed to offers in the group? - uint256 commitCount = lookups.conditionalCommitsByAddress[_buyer][_groupId]; + uint256 commitCount = conditionalCommitsByAddress[_groupId]; require(commitCount < _condition.maxCommits, MAX_COMMITS_ADDRESS_REACHED); @@ -1010,7 +1020,7 @@ contract ExchangeHandlerFacet is IBosonExchangeHandler, BuyerBase, DisputeBase { if (allow) { // Increment number of commits to the group for this address if they are allowed to commit - lookups.conditionalCommitsByAddress[_buyer][_groupId] = ++commitCount; + conditionalCommitsByAddress[_groupId] = ++commitCount; } } else { allow = true;