No Validation Check Against Decimal Of Secondary Token
There is no validation check against the decimal of the secondary token due to a typo. Thus, this will cause the vault to be broken entirely or the value of the shares to be stuck if a secondary token with more than 18 decimals is added.\\nThere is a typo in Line 65 within the `TwoTokenPoolMixin` contract. The validation at Line 65 should perform a check against the `secondaryDecimals` instead of the `primaryDecimals`. As such, no validation was performed against the secondary token.\\n```\\nFile: TwoTokenPoolMixin.sol\\n    constructor(\\n        NotionalProxy notional_, \\n        AuraVaultDeploymentParams memory params\\n    ) PoolMixin(notional_, params) {\\n..SNIP..\\n        // If the underlying is ETH, primaryBorrowToken will be rewritten as WETH\\n        uint256 primaryDecimals = IERC20(primaryAddress).decimals();\\n        // Do not allow decimal places greater than 18\\n        require(primaryDecimals <= 18);\\n        PRIMARY_DECIMALS = uint8(primaryDecimals);\\n\\n        uint256 secondaryDecimals = address(SECONDARY_TOKEN) ==\\n            Deployments.ETH_ADDRESS\\n            ? 18\\n            : SECONDARY_TOKEN.decimals();\\n        require(primaryDecimals <= 18);\\n        SECONDARY_DECIMALS = uint8(secondaryDecimals);\\n    }\\n```\\n\\nIf the decimal of the secondary tokens is more than 18, the `Stable2TokenOracleMath._getSpotPrice` will stop working as the code will revert in Line 24 below because the decimal of secondary tokens is more than 18.\\nWhen the `Stable2TokenOracleMath._getSpotPrice` function stop working, the vaults will be broken entirely because the settle vault and reinvest rewards functions will stop working too. This is because the settle vault and reinvest rewards functions will call the `Stable2TokenOracleMath._getSpotPrice` function internally, resulting in a revert.\\n```\\nFile: Stable2TokenOracleMath.sol\\n    function _getSpotPrice(\\n        StableOracleContext memory oracleContext, \\n        TwoTokenPoolContext memory poolContext, \\n        uint256 tokenIndex\\n    ) internal view returns (uint256 spotPrice) {\\n        // Prevents overflows, we don't expect tokens to be greater than 18 decimals, don't use\\n        // equal sign for minor gas optimization\\n        require(poolContext.primaryDecimals < 19); /// @dev primaryDecimals overflow\\n        require(poolContext.secondaryDecimals < 19); /// @dev secondaryDecimals overflow\\n        require(tokenIndex < 2); /// @dev invalid token index\\n```\\n
Update the code to perform the validation against the `secondaryDecimals` state variable.\\n```\\nconstructor(\\n    NotionalProxy notional_, \\n    AuraVaultDeploymentParams memory params\\n) PoolMixin(notional_, params) {\\n    ..SNIP..\\n    // If the underlying is ETH, primaryBorrowToken will be rewritten as WETH\\n    uint256 primaryDecimals = IERC20(primaryAddress).decimals();\\n    // Do not allow decimal places greater than 18\\n    require(primaryDecimals <= 18);\\n    PRIMARY_DECIMALS = uint8(primaryDecimals);\\n\\n    uint256 secondaryDecimals = address(SECONDARY_TOKEN) ==\\n        Deployments.ETH_ADDRESS\\n        ? 18\\n        : SECONDARY_TOKEN.decimals();\\n// Remove the line below\\n   require(primaryDecimals <= 18);\\n// Add the line below\\n   require(secondaryDecimals <= 18);\\n    SECONDARY_DECIMALS = uint8(secondaryDecimals);\\n}\\n```\\n
The `Stable2TokenOracleMath._getSpotPrice` will stop working, which will in turn cause the settle vault and reinvest rewards functions to stop working too. Since a vault cannot be settled, the vault is considered broken. If the reinvest rewards function cannot work, the value of users' shares will be stuck as the vault relies on reinvesting rewards to buy more BPT tokens from the market.\\nIn addition, there might be some issues when calculating the price of the tokens since the vault assumes that both primary and secondary tokens have a decimal equal to or less than 18 OR some overflow might occur when processing the token value.
```\\nFile: TwoTokenPoolMixin.sol\\n    constructor(\\n        NotionalProxy notional_, \\n        AuraVaultDeploymentParams memory params\\n    ) PoolMixin(notional_, params) {\\n..SNIP..\\n        // If the underlying is ETH, primaryBorrowToken will be rewritten as WETH\\n        uint256 primaryDecimals = IERC20(primaryAddress).decimals();\\n        // Do not allow decimal places greater than 18\\n        require(primaryDecimals <= 18);\\n        PRIMARY_DECIMALS = uint8(primaryDecimals);\\n\\n        uint256 secondaryDecimals = address(SECONDARY_TOKEN) ==\\n            Deployments.ETH_ADDRESS\\n            ? 18\\n            : SECONDARY_TOKEN.decimals();\\n        require(primaryDecimals <= 18);\\n        SECONDARY_DECIMALS = uint8(secondaryDecimals);\\n    }\\n```\\n