Adversary can brick AutoRoller by creating another AutoRoller on the same adapter
onSponsorWindowOpened attempts to make a new series at the desired maturity. Each adapter can only have one of each maturity. If the maturity requested already exists then onSponsorWindowOpened will revert, making it impossible to roll the AutoRoller. An adversary can take advantage of this to brick an AutoRoller by creating a second AutoRoller on the same adapter that will create a target maturity before the first AutoRoller. Since the maturity now exists, the first AutoRoller will always revert when trying to Roll.\\n```\\nuint256 _maturity = utils.getFutureMaturity(targetDuration);\\n\\nfunction getFutureMaturity(uint256 monthsForward) public view returns (uint256) {\\n    (uint256 year, uint256 month, ) = DateTime.timestampToDate(DateTime.addMonths(block.timestamp, monthsForward));\\n    return DateTime.timestampFromDateTime(year, month, 1 /* top of the month */, 0, 0, 0);\\n}\\n```\\n\\nInside AutoRoller#onSponsorWindowOpened the maturity is calculated using RollerUtils#getFutureMaturity. This returns the timestamp the requested months ahead, truncated down to the first of the month. It passes this calculated maturity as the maturity to sponsor a new series.\\n```\\n(ERC20 _pt, YTLike _yt) = periphery.sponsorSeries(address(adapter), _maturity, true);\\n```\\n\\n```\\nfunction sponsorSeries(\\n    address adapter,\\n    uint256 maturity,\\n    bool withPool\\n) external returns (address pt, address yt) {\\n    (, address stake, uint256 stakeSize) = Adapter(adapter).getStakeAndTarget();\\n\\n    // Transfer stakeSize from sponsor into this contract\\n    ERC20(stake).safeTransferFrom(msg.sender, address(this), stakeSize);\\n\\n    // Approve divider to withdraw stake assets\\n    ERC20(stake).approve(address(divider), stakeSize);\\n\\n    (pt, yt) = divider.initSeries(adapter, maturity, msg.sender);\\n\\n    // Space pool is always created for verified adapters whilst is optional for unverified ones.\\n    // Automatically queueing series is only for verified adapters\\n    if (verified[adapter]) {\\n        poolManager.queueSeries(adapter, maturity, spaceFactory.create(adapter, maturity));\\n    } else {\\n        if (withPool) {\\n            spaceFactory.create(adapter, maturity);\\n        }\\n    }\\n    emit SeriesSponsored(adapter, maturity, msg.sender);\\n}\\n```\\n\\nperiphery#sponsorSeries is called with true indicating to create a space pool for the newly created series.\\n```\\nfunction create(address adapter, uint256 maturity) external returns (address pool) {\\n    address pt = divider.pt(adapter, maturity);\\n    _require(pt != address(0), Errors.INVALID_SERIES);\\n    _require(pools[adapter][maturity] == address(0), Errors.POOL_ALREADY_EXISTS);\\n\\n    pool = address(new Space(\\n        vault,\\n        adapter,\\n        maturity,\\n        pt,\\n        ts,\\n        g1,\\n        g2,\\n        oracleEnabled\\n    ));\\n\\n    pools[adapter][maturity] = pool;\\n}\\n```\\n\\nWe run into an issue inside SpaceFactory#create because it only allows a single pool per adapter/maturity. If a pool already exist then it will revert.\\nAn adversary can abuse this revert to brick an existing AutoRoller. Assume AutoRoller A has a duration of 3 months. Its current maturity is December 1st 2022, when rolled it will attempt to create a series at March 1st 2023. An adversary could abuse this and create AutoRoller B with a maturity of 4 months. When they roll for the first time it will create a series with maturity at March 1st 2023. When AutoRoller A attempts to roll it will revert since a series already exists at March 1st 2023.\\nThis conflict can happen accidentally if there is a monthly AutoRoller and a quarterly AutoRoller. It also hinders the viability of using an AutoRoller for an adapter that is popular because the series will likely have been created by the time the autoroller tries to roll into it.
Requiring that the AutoRoller has to create the series seems overly restrictive and leads to a large number of issues. Attempting to join an a series that is already initialized could also lead to pool manipulation rates. It seems like a large refactoring is needed for the rolling section of the AutoRoller
AutoRollers will frequently be bricked
```\\nuint256 _maturity = utils.getFutureMaturity(targetDuration);\\n\\nfunction getFutureMaturity(uint256 monthsForward) public view returns (uint256) {\\n    (uint256 year, uint256 month, ) = DateTime.timestampToDate(DateTime.addMonths(block.timestamp, monthsForward));\\n    return DateTime.timestampFromDateTime(year, month, 1 /* top of the month */, 0, 0, 0);\\n}\\n```\\n