// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title RWATaxonomy * @notice On-chain validation helpers for M00 Li* index instruments (not M1 c* eMoney). */ library RWATaxonomy { bytes32 public constant GRU_LAYER_M00 = keccak256("M00"); bytes32 public constant ASSET_CLASS_COMMODITIES = keccak256("Commodities"); bytes32 public constant TICKER_LIXAU = keccak256("LiXAU"); bytes32 public constant TICKER_LIPMG = keccak256("LiPMG"); bytes32 public constant TICKER_LIBMG1 = keccak256("LiBMG1"); bytes32 public constant TICKER_LIBMG2 = keccak256("LiBMG2"); bytes32 public constant TICKER_LIBMG3 = keccak256("LiBMG3"); error InvalidIndexTicker(); error InvalidAssetClass(); error InvalidGruLayer(); error EmptyString(); function hashString(string memory value) internal pure returns (bytes32) { return keccak256(bytes(value)); } function isAllowedIndexTicker(bytes32 tickerHash) internal pure returns (bool) { return tickerHash == TICKER_LIXAU || tickerHash == TICKER_LIPMG || tickerHash == TICKER_LIBMG1 || tickerHash == TICKER_LIBMG2 || tickerHash == TICKER_LIBMG3; } function validateProduct( string memory indexTicker, string memory assetClass, string memory gruLayer ) internal pure returns (bytes32 tickerHash) { if (bytes(indexTicker).length == 0 || bytes(assetClass).length == 0) { revert EmptyString(); } tickerHash = hashString(indexTicker); if (!isAllowedIndexTicker(tickerHash)) { revert InvalidIndexTicker(); } if (hashString(assetClass) != ASSET_CLASS_COMMODITIES) { revert InvalidAssetClass(); } if (hashString(gruLayer) != GRU_LAYER_M00) { revert InvalidGruLayer(); } } }