Skip to content

Commit

Permalink
New pausable regions (#910)
Browse files Browse the repository at this point in the history
* Add new pausable regions

* Test error args in other tests

* additional tests [skip ci]
  • Loading branch information
zajck authored Feb 19, 2024
1 parent ed67b23 commit 74d610f
Show file tree
Hide file tree
Showing 22 changed files with 510 additions and 247 deletions.
4 changes: 3 additions & 1 deletion contracts/domain/BosonErrors.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.22;

import { BosonTypes } from "./BosonTypes.sol";

interface BosonErrors {
// Pause related
// Trying to unpause a protocol when it's not paused
error NotPaused();
// Whenever a region is paused, and a method from that region is called
error RegionPaused(); //ToDo consider adding the region to the error message
error RegionPaused(BosonTypes.PausableRegion region);

// General
// Input parameter of type address is zero address
Expand Down
4 changes: 3 additions & 1 deletion contracts/domain/BosonTypes.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ contract BosonTypes {
Disputes,
Funds,
Orchestration,
MetaTransaction
MetaTransaction,
PriceDiscovery,
SequentialCommit
}

enum EvaluationMethod {
Expand Down
27 changes: 26 additions & 1 deletion contracts/protocol/bases/PausableBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,30 @@ contract PausableBase is BosonTypes {
_;
}

/**
* @notice Modifier that checks the PriceDiscovery region is not paused
*
* Reverts if region is paused
*
* See: {BosonTypes.PausableRegion}
*/
modifier priceDiscoveryNotPaused() {
revertIfPaused(PausableRegion.PriceDiscovery);
_;
}

/**
* @notice Modifier that checks the SequentialCommit region is not paused
*
* Reverts if region is paused
*
* See: {BosonTypes.PausableRegion}
*/
modifier sequentialCommitNotPaused() {
revertIfPaused(PausableRegion.SequentialCommit);
_;
}

/**
* @notice Checks if a region of the protocol is paused.
*
Expand All @@ -178,6 +202,7 @@ contract PausableBase is BosonTypes {
function revertIfPaused(PausableRegion _region) internal view {
// Region enum value must be used as the exponent in a power of 2
uint256 powerOfTwo = 1 << uint256(_region);
if ((ProtocolLib.protocolStatus().pauseScenario & powerOfTwo) == powerOfTwo) revert BosonErrors.RegionPaused();
if ((ProtocolLib.protocolStatus().pauseScenario & powerOfTwo) == powerOfTwo)
revert BosonErrors.RegionPaused(_region);
}
}
2 changes: 1 addition & 1 deletion contracts/protocol/bases/PriceDiscoveryBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ contract PriceDiscoveryBase is ProtocolBase {
PriceDiscovery calldata _priceDiscovery,
address _seller,
address _buyer
) internal returns (uint256 actualPrice) {
) internal priceDiscoveryNotPaused returns (uint256 actualPrice) {
// Make sure caller provided price discovery data
if (_priceDiscovery.priceDiscoveryContract == address(0) || _priceDiscovery.priceDiscoveryData.length == 0) {
revert InvalidPriceDiscovery();
Expand Down
9 changes: 0 additions & 9 deletions contracts/protocol/facets/PriceDiscoveryHandlerFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,11 @@ pragma solidity 0.8.22;

import { BuyerBase } from "../bases/BuyerBase.sol";
import { IBosonPriceDiscoveryHandler } from "../../interfaces/handlers/IBosonPriceDiscoveryHandler.sol";
import { IBosonVoucher } from "../../interfaces/clients/IBosonVoucher.sol";
import { ITwinToken } from "../../interfaces/ITwinToken.sol";
import { DiamondLib } from "../../diamond/DiamondLib.sol";
import { BuyerBase } from "../bases/BuyerBase.sol";
import { DisputeBase } from "../bases/DisputeBase.sol";
import { ProtocolLib } from "../libs/ProtocolLib.sol";
import { FundsLib } from "../libs/FundsLib.sol";
import "../../domain/BosonConstants.sol";
import { IERC1155 } from "../../interfaces/IERC1155.sol";
import { IERC721 } from "../../interfaces/IERC721.sol";
import { IERC20 } from "../../interfaces/IERC20.sol";
import { IERC721Receiver } from "../../interfaces/IERC721Receiver.sol";
import { PriceDiscoveryBase } from "../bases/PriceDiscoveryBase.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";

/**
* @title PriceDiscoveryHandlerFacet
Expand Down
2 changes: 1 addition & 1 deletion contracts/protocol/facets/SequentialCommitHandlerFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ contract SequentialCommitHandlerFacet is IBosonSequentialCommitHandler, PriceDis
address payable _buyer,
uint256 _tokenId,
PriceDiscovery calldata _priceDiscovery
) external payable exchangesNotPaused buyersNotPaused nonReentrant {
) external payable exchangesNotPaused buyersNotPaused sequentialCommitNotPaused nonReentrant {
// Make sure buyer address is not zero address
if (_buyer == address(0)) revert InvalidAddress();

Expand Down
4 changes: 4 additions & 0 deletions scripts/domain/PausableRegion.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ PausableRegion.Disputes = 9;
PausableRegion.Funds = 10;
PausableRegion.Orchestration = 11;
PausableRegion.MetaTransaction = 12;
PausableRegion.PriceDiscovery = 13;
PausableRegion.SequentialCommit = 14;

PausableRegion.Regions = [
PausableRegion.Offers,
Expand All @@ -31,6 +33,8 @@ PausableRegion.Regions = [
PausableRegion.Funds,
PausableRegion.Orchestration,
PausableRegion.MetaTransaction,
PausableRegion.PriceDiscovery,
PausableRegion.SequentialCommit,
];

// Export
Expand Down
14 changes: 6 additions & 8 deletions test/protocol/AgentHandlerTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,9 @@ describe("AgentHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Agents]);

// Attempt to create an agent, expecting revert
await expect(accountHandler.connect(rando).createAgent(agent)).to.revertedWithCustomError(
bosonErrors,
RevertReasons.REGION_PAUSED
);
await expect(accountHandler.connect(rando).createAgent(agent))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Agents);
});

it("active is false", async function () {
Expand Down Expand Up @@ -455,10 +454,9 @@ describe("AgentHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Agents]);

// Attempt to update an agent, expecting revert
await expect(accountHandler.connect(other1).updateAgent(agent)).to.revertedWithCustomError(
bosonErrors,
RevertReasons.REGION_PAUSED
);
await expect(accountHandler.connect(other1).updateAgent(agent))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Agents);
});

it("Agent does not exist", async function () {
Expand Down
7 changes: 3 additions & 4 deletions test/protocol/BundleHandlerTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,10 +357,9 @@ describe("IBosonBundleHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Bundles]);

// Attempt to create a bundle, expecting revert
await expect(bundleHandler.connect(assistant).createBundle(bundle)).to.revertedWithCustomError(
bosonErrors,
RevertReasons.REGION_PAUSED
);
await expect(bundleHandler.connect(assistant).createBundle(bundle))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Bundles);
});

it("Caller not assistant of any seller", async function () {
Expand Down
14 changes: 6 additions & 8 deletions test/protocol/BuyerHandlerTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,9 @@ describe("BuyerHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Buyers]);

// Attempt to create a buyer, expecting revert
await expect(accountHandler.connect(rando).createBuyer(buyer)).to.revertedWithCustomError(
bosonErrors,
RevertReasons.REGION_PAUSED
);
await expect(accountHandler.connect(rando).createBuyer(buyer))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Buyers);
});

it("active is false", async function () {
Expand Down Expand Up @@ -444,10 +443,9 @@ describe("BuyerHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Buyers]);

// Attempt to update a buyer, expecting revert
await expect(accountHandler.connect(other1).updateBuyer(buyer)).to.revertedWithCustomError(
bosonErrors,
RevertReasons.REGION_PAUSED
);
await expect(accountHandler.connect(other1).updateBuyer(buyer))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Buyers);
});

it("Buyer does not exist", async function () {
Expand Down
63 changes: 30 additions & 33 deletions test/protocol/DisputeHandlerTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,9 @@ describe("IBosonDisputeHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]);

// Attempt to raise a dispute, expecting revert
await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId)).to.revertedWithCustomError(
bosonErrors,
RevertReasons.REGION_PAUSED
);
await expect(disputeHandler.connect(buyer).raiseDispute(exchangeId))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Disputes);
});

it("Caller does not hold a voucher for the given exchange id", async function () {
Expand Down Expand Up @@ -453,10 +452,9 @@ describe("IBosonDisputeHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]);

// Attempt to retract a dispute, expecting revert
await expect(disputeHandler.connect(buyer).retractDispute(exchangeId)).to.revertedWithCustomError(
bosonErrors,
RevertReasons.REGION_PAUSED
);
await expect(disputeHandler.connect(buyer).retractDispute(exchangeId))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Disputes);
});

it("Exchange does not exist", async function () {
Expand Down Expand Up @@ -595,9 +593,9 @@ describe("IBosonDisputeHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]);

// Attempt to extend a dispute timeout, expecting revert
await expect(
disputeHandler.connect(assistant).extendDisputeTimeout(exchangeId, newDisputeTimeout)
).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED);
await expect(disputeHandler.connect(assistant).extendDisputeTimeout(exchangeId, newDisputeTimeout))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Disputes);
});

it("Exchange does not exist", async function () {
Expand Down Expand Up @@ -738,10 +736,9 @@ describe("IBosonDisputeHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]);

// Attempt to expire a dispute, expecting revert
await expect(disputeHandler.connect(rando).expireDispute(exchangeId)).to.revertedWithCustomError(
bosonErrors,
RevertReasons.REGION_PAUSED
);
await expect(disputeHandler.connect(rando).expireDispute(exchangeId))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Disputes);
});

it("Exchange does not exist", async function () {
Expand Down Expand Up @@ -1091,9 +1088,9 @@ describe("IBosonDisputeHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]);

// Attempt to resolve a dispute, expecting revert
await expect(
disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v)
).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED);
await expect(disputeHandler.connect(assistant).resolveDispute(exchangeId, buyerPercentBasisPoints, r, s, v))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Disputes);
});

it("Specified buyer percent exceeds 100%", async function () {
Expand Down Expand Up @@ -1378,7 +1375,9 @@ describe("IBosonDisputeHandler", function () {
// Attempt to escalate a dispute, expecting revert
await expect(
disputeHandler.connect(buyer).escalateDispute(exchangeId, { value: buyerEscalationDepositNative })
).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED);
)
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Disputes);
});

it("Exchange does not exist", async function () {
Expand Down Expand Up @@ -1626,9 +1625,9 @@ describe("IBosonDisputeHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]);

// Attempt to decide a dispute, expecting revert
await expect(
disputeHandler.connect(assistantDR).decideDispute(exchangeId, buyerPercentBasisPoints)
).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED);
await expect(disputeHandler.connect(assistantDR).decideDispute(exchangeId, buyerPercentBasisPoints))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Disputes);
});

it("Specified buyer percent exceeds 100%", async function () {
Expand Down Expand Up @@ -1786,10 +1785,9 @@ describe("IBosonDisputeHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]);

// Attempt to expire an escalated dispute, expecting revert
await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId)).to.revertedWithCustomError(
bosonErrors,
RevertReasons.REGION_PAUSED
);
await expect(disputeHandler.connect(rando).expireEscalatedDispute(exchangeId))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Disputes);
});

it("Exchange does not exist", async function () {
Expand Down Expand Up @@ -1932,9 +1930,9 @@ describe("IBosonDisputeHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]);

// Attempt to refuse an escalated dispute, expecting revert
await expect(
disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId)
).to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED);
await expect(disputeHandler.connect(assistantDR).refuseEscalatedDispute(exchangeId))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Disputes);
});

it("Exchange does not exist", async function () {
Expand Down Expand Up @@ -2525,10 +2523,9 @@ describe("IBosonDisputeHandler", function () {
await pauseHandler.connect(pauser).pause([PausableRegion.Disputes]);

// Attempt to expire a dispute batch, expecting revert
await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire)).to.revertedWithCustomError(
bosonErrors,
RevertReasons.REGION_PAUSED
);
await expect(disputeHandler.connect(rando).expireDisputeBatch(disputesToExpire))
.to.revertedWithCustomError(bosonErrors, RevertReasons.REGION_PAUSED)
.withArgs(PausableRegion.Disputes);
});

it("Exchange does not exist", async function () {
Expand Down
Loading

0 comments on commit 74d610f

Please sign in to comment.