AutoRoller.sol#roll can revert if lastSettle is zero because solmate ERC4626 deposit revert if previewDeposit returns 0
AutoRoller.sol#roll can revert if lastSettle is zero because solmate ERC4626 deposit revert if previewDeposit returns 0\\nlet us look into the implementation of function roll()\\n```\\n  /// @notice Roll into the next Series if there isn't an active series and the cooldown period has elapsed.\\n  function roll() external {\\n      if (maturity != MATURITY_NOT_SET) revert RollWindowNotOpen();\\n\\n      if (lastSettle == 0) {\\n          // If this is the first roll, lock some shares in by minting them for the zero address.\\n          // This prevents the contract from reaching an empty state during future active periods.\\n          deposit(firstDeposit, address(0));\\n      } else if (lastSettle + cooldown > block.timestamp) {\\n          revert RollWindowNotOpen();\\n      }\\n\\n      lastRoller = msg.sender;\\n      adapter.openSponsorWindow();\\n  }\\n```\\n\\nnote, if lastSettle is 0, we deposit a small amount of token and mint shares to address(0)\\n```\\ndeposit(firstDeposit, address(0));\\n```\\n\\nFirst deposit is a fairly small amount:\\n```\\nfirstDeposit  = (0.01e18 - 1) / scalingFactor + 1;\\n```\\n\\nWe can deposit from ERC4626 implementation:\\n```\\nfunction deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) {\\n    // Check for rounding error since we round down in previewDeposit.\\n    require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");\\n\\n    // Need to transfer before minting or ERC777s could reenter.\\n    asset.safeTransferFrom(msg.sender, address(this), assets);\\n\\n    _mint(receiver, shares);\\n\\n    emit Deposit(msg.sender, receiver, assets, shares);\\n\\n    afterDeposit(assets, shares);\\n}\\n```\\n\\nnote the restriction:\\n```\\n// Check for rounding error since we round down in previewDeposit.\\nrequire((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");\\n\\n// Need to transfer before minting or ERC777s could reenter.\\nasset.safeTransferFrom(msg.sender, address(this), assets);\\n```\\n\\nif previewDeposit returns 0 shares, transaction revert. Can previewDeposit returns 0 shares? it is very possible.\\n```\\nfunction previewDeposit(uint256 assets) public view override returns (uint256) {\\n    if (maturity == MATURITY_NOT_SET) {\\n        return super.previewDeposit(assets);\\n    } else {\\n        Space _space = space;\\n        (uint256 ptReserves, uint256 targetReserves) = _getSpaceReserves();\\n\\n        // Calculate how much Target we'll end up joining the pool with, and use that to preview minted LP shares.\\n        uint256 previewedLPBal = (assets - _getTargetForIssuance(ptReserves, targetReserves, assets, adapter.scaleStored()))\\n            .mulDivDown(_space.adjustedTotalSupply(), targetReserves);\\n\\n        // Shares represent proportional ownership of LP shares the vault holds.\\n        return previewedLPBal.mulDivDown(totalSupply, _space.balanceOf(address(this)));\\n    }\\n}\\n```\\n\\nIf (previewedLPBal * total) / space balance is truncated to 0, transaction revert. _space.balanceOf can certainly be inflated if malicious actor send the space token to the address manually. Or previewedLPBal * total could just be small and the division is truncated to 0.
We recommend the project not deposit a such small amount, or there could be a function that let admin gradually control how many tokens should we put in the first deposit.
calling roll would revert and the new sponsored series cannot be started properly.
```\\n  /// @notice Roll into the next Series if there isn't an active series and the cooldown period has elapsed.\\n  function roll() external {\\n      if (maturity != MATURITY_NOT_SET) revert RollWindowNotOpen();\\n\\n      if (lastSettle == 0) {\\n          // If this is the first roll, lock some shares in by minting them for the zero address.\\n          // This prevents the contract from reaching an empty state during future active periods.\\n          deposit(firstDeposit, address(0));\\n      } else if (lastSettle + cooldown > block.timestamp) {\\n          revert RollWindowNotOpen();\\n      }\\n\\n      lastRoller = msg.sender;\\n      adapter.openSponsorWindow();\\n  }\\n```\\n