Lack of extra validations when using `Chainlink::latestRoundData` in `AuraVault::_chainlinkSpot` and `AuraVault::_getAuraSpot` will allow for stale or incorrect results to be used
Audit: 2024-07-loopfi-findings
Severity: MEDIUM

# Lines of code

https://github.com/code-423n4/2024-07-loopfi/blob/57871f64bdea450c1f04c9a53dc1a78223719164/src/vendor/AuraVault.sol#L365-L391


# Vulnerability details

## Impact
The `AuraVault::_chainlinkSpot` is used to return the `BAL/USD` price in 8 decimals. However, the only validation done on the returned price, `answer`, is a `bool isValid` to check that the calculated `price > 0`. 

The `AuraVault::_getAuraSpot` is used to get the price of `AURA` reward tokens. However, there is no validation whatsoever on the returned `answer` used to calculate the `ethPrice`.



## Proof of Concept

https://github.com/code-423n4/2024-07-loopfi/blob/57871f64bdea450c1f04c9a53dc1a78223719164/src/vendor/AuraVault.sol#L365-L379

```
//src/vendor/AuraVault.sol
//ln#365-379

 function _chainlinkSpot() private view returns (uint256 price) { 
        bool isValid;
        try AggregatorV3Interface(BAL_CHAINLINK_FEED).latestRoundData() returns ( 
            uint80 /*roundId*/,
            int256 answer, /**@audit Returned BAL/USD price
            uint256 /*startedAt*/,
            uint256 /*updatedAt*/,
            uint80 /*answeredInRound*/
        ) {
            price = wdiv(uint256(answer), BAL_CHAINLINK_DECIMALS); //@audit Calculated Price
            isValid = (price > 0); //@audit bool check
        } catch {}

        if (!isValid) revert AuraVault__chainlinkSpot_invalidPrice();
    }
```

https://github.com/code-423n4/2024-07-loopfi/blob/57871f64bdea450c1f04c9a53dc1a78223719164/src/vendor/AuraVault.sol#L381-L391

```
//src/vendor/AuraVault.sol
//ln#382-392

function _getAuraSpot() internal view returns (uint256 price) {
        uint256 ethPrice; // @audit SHOULD BE e8
        (, int256 answer, , , ) = AggregatorV3Interface(ETH_CHAINLINK_FEED).latestRoundData(); //@audit .latestRoundData MIGHT RETURN STALE PRICE (LACK OF EXTRA answer VALIDATIONS)
        ethPrice = wdiv(uint256(answer), ETH_CHAINLINK_DECIMALS); //@audit answer used here.

        IPriceOracle.OracleAverageQuery[] memory queries = new IPriceOracle.OracleAverageQuery[](1);
        queries[0] = IPriceOracle.OracleAverageQuery(IPriceOracle.Variable.PAIR_PRICE, 1800, 0);
        uint256[] memory results = IPriceOracle(auraPriceOracle).getTimeWeightedAverage(queries); 
        price = wmul(results[0], ethPrice); 
    }
```

If there is a problem with Chainlink starting a new round and finding consensus on the new value for the oracle (e.g. Chainlink nodes abandon the oracle, chain congestion, vulnerability/attacks on the chainlink system) consumers of this contract may continue using outdated stale or incorrect data (if oracles are unable to submit no answer in a new round).



## Tools Used

Manual Review.

## Recommended Mitigation Steps


* Consider making the following changes to the functions

```diff
function _chainlinkSpot() private view returns (uint256 price) { //@audit NO TEST
        bool isValid;
        try AggregatorV3Interface(BAL_CHAINLINK_FEED).latestRoundData() returns (