all files / plugins/assets/convex/ CvxVolatileCollateral.sol

81.25% Statements 13/16
66.67% Branches 4/6
100% Functions 2/2
88.24% Lines 15/17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64                                                    57×         14× 14× 14×     14× 42×   42×     42× 42×                 14× 14× 38× 38× 25×       11×      
// SPDX-License-Identifier: ISC
pragma solidity 0.8.17;
import "./CvxStableCollateral.sol";
 
/**
 * @title CvxVolatileCollateral
 *  This plugin contract extends CvxCurveStableCollateral to work for
 *  volatile pools like TriCrypto.
 *
 * tok = ConvexStakingWrapper(cvxVolatilePlainPool)
 * ref = cvxVolatilePlainPool pool invariant
 * tar = cvxVolatilePlainPool pool invariant
 * UoA = USD
 */
contract CvxVolatileCollateral is CvxStableCollateral {
    using FixLib for uint192;
 
    // this isn't saved by our parent classes, but we'll need to track it
    uint192 internal immutable _defaultThreshold; // {1}
 
    /// @dev config Unused members: chainlinkFeed, oracleError, oracleTimeout
    constructor(
        CollateralConfig memory config,
        uint192 revenueHiding,
        PTConfiguration memory ptConfig
    ) CvxStableCollateral(config, revenueHiding, ptConfig) {
        _defaultThreshold = config.defaultThreshold;
    }
 
    // Override this later to implement non-stable pools
    function _anyDepeggedInPool() internal view override returns (bool) {
        uint192[] memory balances = getBalances(); // [{tok}]
        uint192[] memory vals = new uint192[](balances.length); // {UoA}
        uint192 valSum; // {UoA}
 
        // Calculate vals
        for (uint8 i = 0; i < nTokens; i++) {
            try this.tokenPrice(i) returns (uint192 low, uint192 high) {
                // {UoA/tok} = {UoA/tok} + {UoA/tok}
                uint192 mid = (low + high) / 2;
 
                // {UoA} = {tok} * {UoA/tok}
                vals[i] = balances[i].mul(mid);
                valSum += vals[i];
            } catch (bytes memory errData) {
                // see: docs/solidity-style.md#Catching-Empty-Data
                if (errData.length == 0) revert(); // solhint-disable-line reason-string
                return true;
            }
        }
 
        // Check distribution of capital
        uint192 expected = FIX_ONE.divu(nTokens); // {1}
        for (uint8 i = 0; i < nTokens; i++) {
            uint192 observed = divuu(vals[i], valSum); // {1}
            if (observed > expected) {
                if (observed - expected > _defaultThreshold) return true;
            }
        }
 
        return false;
    }
}