// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; /** * @dev Utility to create Pool factories for Pools that use the `TemporarilyPausable` contract. * * By calling `TemporarilyPausable`'s constructor with the result of `getPauseConfiguration`, all Pools created by this * factory will share the same Pause Window end time, after which both old and new Pools will not be pausable. */ contract FactoryWidePauseWindow { // This contract relies on timestamps in a similar way as `TemporarilyPausable` does - the same caveats apply. // solhint-disable not-rely-on-time uint256 private constant _INITIAL_PAUSE_WINDOW_DURATION = 90 days; uint256 private constant _BUFFER_PERIOD_DURATION = 30 days; // Time when the pause window for all created Pools expires, and the pause window duration of new Pools becomes // zero. uint256 private immutable _poolsPauseWindowEndTime; constructor() { _poolsPauseWindowEndTime = block.timestamp + _INITIAL_PAUSE_WINDOW_DURATION; } /** * @dev Returns the current `TemporarilyPausable` configuration that will be applied to Pools created by this * factory. * * `pauseWindowDuration` will decrease over time until it reaches zero, at which point both it and * `bufferPeriodDuration` will be zero forever, meaning deployed Pools will not be pausable. */ function getPauseConfiguration() public view returns (uint256 pauseWindowDuration, uint256 bufferPeriodDuration) { uint256 currentTime = block.timestamp; if (currentTime < _poolsPauseWindowEndTime) { // The buffer period is always the same since its duration is related to how much time is needed to respond // to a potential emergency. The Pause Window duration however decreases as the end time approaches. pauseWindowDuration = _poolsPauseWindowEndTime - currentTime; // No need for checked arithmetic. bufferPeriodDuration = _BUFFER_PERIOD_DURATION; } else { // After the end time, newly created Pools have no Pause Window, nor Buffer Period (since they are not // pausable in the first place). pauseWindowDuration = 0; bufferPeriodDuration = 0; } } }