all files / contracts/risk/ CoverageDataProviderV2.sol

98.18% Statements 54/55
83.33% Branches 15/18
100% Functions 13/13
100% Lines 59/59
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228                                                                                            85× 82×                                       52× 52×               30×                         11×                                 34×                                                         52× 52×   52× 25× 25× 25× 25× 25×       52× 52× 52× 52× 65× 65× 65× 65×   64× 63× 63× 63× 63× 62×   62×   48×               30× 30×   30× 30× 30× 30×   24× 24×   24× 12× 12× 12×     24× 24× 24× 23× 22× 20×   19×                                     15× 12×      
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.6;
 
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
 
import "../interfaces/risk/ICoverageDataProviderV2.sol";
import "../interfaces/utils/IRegistry.sol";
import "../interfaces/ISOLACE.sol";
import "../utils/Governable.sol";
 
/**
 * @title  CoverageDataProviderV2
 * @author solace.fi
 * @notice Holds underwriting pool amounts in `USD`. Provides information to the [**Risk Manager**](./RiskManager.sol) that is the maximum amount of cover that `Solace` protocol can sell as a coverage.
*/
contract CoverageDataProviderV2 is ICoverageDataProviderV2, Governable, ReentrancyGuard {
    using EnumerableSet for EnumerableSet.AddressSet;
 
    /***************************************
     STATE VARIABLES
    ***************************************/
 
    /// @notice The balance of underwriting pool in usd.
    mapping(string => uint256) private _uwpBalanceOf;
 
    /// @notice The index to underwriting pool.
    mapping(uint256 => string) private _indexToUwp;
 
    /// @notice The underwriting pool to index.
    mapping(string => uint256) private _uwpToIndex;
 
    /// @notice The underwriting pool updaters.
    EnumerableSet.AddressSet private _updaters;
 
    /// @notice The underwriting pool count
    uint256 public numOfPools;
 
    /// @notice The max. coverage amount.
    uint256 public maxCover;
 
    /***************************************
     MODIFIERS FUNCTIONS
    ***************************************/
    
    modifier canUpdate() {
      require(msg.sender == super.governance() || isUpdater(msg.sender), "!governance");
      _;
    }
 
    /**
     * @notice Constructs the `CoverageDataProviderV2` contract.
     * @param _governance The address of the [governor](/docs/protocol/governance).
    */
    // solhint-disable-next-line no-empty-blocks
    constructor(address _governance) Governable(_governance) {}
 
    /***************************************
     MUTUATOR FUNCTIONS
    ***************************************/
   
    /**
      * @notice Resets the underwriting pool balances.
      * @param _uwpNames The underwriting pool values to set.
      * @param _amounts The underwriting pool balances in `USD`.
    */
    function set(string[] calldata _uwpNames, uint256[] calldata _amounts) external override nonReentrant canUpdate {
      Erequire(_uwpNames.length == _amounts.length, "length mismatch");
      _set(_uwpNames, _amounts);
    }
 
    /**
     * @notice Removes the given underwriting pool.
     * @param uwpNames The underwriting pool names to remove.
    */
    function remove(string[] calldata uwpNames) external override canUpdate {
      _remove(uwpNames);
    }
 
    /***************************************
     VIEW FUNCTIONS
    ***************************************/
   
    /**
     * @notice Returns the balance of the underwriting pool in `USD`.
     * @param uwpName The underwriting pool name to get balance.
     * @return amount The balance of the underwriting pool in `USD`.
    */
    function balanceOf(string memory uwpName) public view override returns (uint256 amount) {
      return _uwpBalanceOf[uwpName];
    }
 
    /**
     * @notice Returns underwriting pool name for given index.
     * @param index The underwriting pool index to get.
     * @return uwpName The underwriting pool name.
    */
    function poolOf(uint256 index) external view override returns (string memory uwpName) {
      return _indexToUwp[index];
    }
 
    /**
     * @notice Returns if given address is a valid underwriting pool updater.
     * @param updater The address to check.
     * @return status True if the address is valid updater.
    */
    function isUpdater(address updater) public view override returns (bool status) {
      return _updaters.contains(updater);
    }
 
    /**
     * @notice Returns updater for given index.
     * @param index The index to get updater.
     * @return updater The updater address.
    */
    function updaterAt(uint256 index) external view override returns (address updater) {
        return _updaters.at(index);
    }
 
    /**
     * @notice Returns the length of the updaters.
     * @return count The updater count.
    */
    function numsOfUpdater() external view override returns (uint256 count) {
        return _updaters.length();
    }
 
    /***************************************
     INTERNAL FUNCTIONS
    ***************************************/
 
    /**
      * @notice Resets the underwriting pool balances.
      * @param uwpNames The underwriting pool values to set.
      * @param amounts The underwriting pool balances in `USD`.
    */
    function _set(string[] memory uwpNames, uint256[] memory amounts) internal {
      // delete current underwriting pools
      uint256 poolCount = numOfPools;
      string memory uwpName;
 
      for (uint256 i = poolCount; i > 0; i--) {
        uwpName = _indexToUwp[i];
        delete _uwpToIndex[uwpName];
        delete _indexToUwp[i];
        delete _uwpBalanceOf[uwpName];
        emit UnderwritingPoolRemoved(uwpName);
      }
 
      // set new underwriting pools
      uint256 cover = 0;
      numOfPools = 0;
      uint256 amount;
      for (uint256 i = 0; i < uwpNames.length; i++) {
        uwpName = uwpNames[i];
        amount = amounts[i];
        cover += amount;
        require(bytes(uwpName).length > 0, "empty underwriting pool name");
        
        _uwpBalanceOf[uwpName] = amount;
        Eif (_uwpToIndex[uwpName] == 0) {
          uint256 index = numOfPools;
          _uwpToIndex[uwpName] = ++index;
          _indexToUwp[index] = uwpName;
          numOfPools = index;
        }
        emit UnderwritingPoolSet(uwpName, amount);
      }
      maxCover = cover;
    }
 
    /**
     * @notice Removes the given underwriting pool.
     * @param uwpNames The underwriting pool names to remove.
    */
    function _remove(string[] memory uwpNames) internal {
      string memory uwpName;
      uint256 cover = maxCover;
 
      for (uint256 i = 0; i < uwpNames.length; i++) {
        uwpName = uwpNames[i];
        uint256 index = _uwpToIndex[uwpName];
        if (index == 0) return;
 
        uint256 poolCount = numOfPools;
        Iif (poolCount == 0) return;
 
        if (index != poolCount) {
          string memory lastPool = _indexToUwp[poolCount];
          _uwpToIndex[lastPool] = index;
          _indexToUwp[index] = lastPool;
        }
 
        cover -= _uwpBalanceOf[uwpName];
        delete _uwpToIndex[uwpName];
        delete _indexToUwp[poolCount];
        delete _uwpBalanceOf[uwpName];
        numOfPools -= 1;
        emit UnderwritingPoolRemoved(uwpName);
      }
      maxCover = cover;
    }
 
    /***************************************
     GOVERNANCE FUNCTIONS
    ***************************************/
    
    /**
     * @notice Sets the underwriting pool bot updater.
     * @param updater The bot address to set.
    */
    function addUpdater(address updater) external override onlyGovernance {
      require(updater != address(0x0), "zero address uwp updater");
      _updaters.add(updater);
      emit UwpUpdaterSet(updater);
    }
 
    /**
     * @notice Sets the underwriting pool bot updater.
     * @param updater The bot address to set.
    */
    function removeUpdater(address updater) external override onlyGovernance {
      if (!isUpdater(updater)) return;
      _updaters.remove(updater);
      emit UwpUpdaterRemoved(updater);
    }
}