// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/**
 * @title XAUTriangulation
 * @notice Library for enforcing XAU triangulation for all currency conversions
 * @dev MANDATORY: All currency conversions MUST go through XAU (gold)
 * 
 * Triangulation formula:
 * CurrencyA → XAU → CurrencyB
 * 
 * Steps:
 * 1. Convert CurrencyA to XAU: xauAmount = currencyAAmount / xauRateA
 * 2. Convert XAU to CurrencyB: currencyBAmount = xauAmount * xauRateB
 */
library XAUTriangulation {
    /**
     * @notice Triangulate from Currency A to Currency B via XAU
     * @dev All conversions MUST go through XAU - this is mandatory
     * @param currencyAAmount Amount in Currency A (18 decimals)
     * @param xauRateA Rate: 1 oz XAU = xauRateA units of Currency A (18 decimals)
     * @param xauRateB Rate: 1 oz XAU = xauRateB units of Currency B (18 decimals)
     * @return currencyBAmount Amount in Currency B (18 decimals)
     */
    function triangulate(
        uint256 currencyAAmount,
        uint256 xauRateA,
        uint256 xauRateB
    ) internal pure returns (uint256 currencyBAmount) {
        require(xauRateA > 0, "XAUTriangulation: invalid XAU rate A");
        require(xauRateB > 0, "XAUTriangulation: invalid XAU rate B");
        
        // Step 1: Convert Currency A to XAU
        // xauAmount = currencyAAmount / xauRateA
        uint256 xauAmount = (currencyAAmount * 1e18) / xauRateA;
        
        // Step 2: Convert XAU to Currency B
        // currencyBAmount = xauAmount * xauRateB / 1e18
        currencyBAmount = (xauAmount * xauRateB) / 1e18;
    }
    
    /**
     * @notice Convert amount to XAU
     * @param amount Amount to convert (18 decimals)
     * @param xauRate Rate: 1 oz XAU = xauRate units (18 decimals)
     * @return xauAmount Amount in XAU (18 decimals)
     */
    function toXAU(uint256 amount, uint256 xauRate) internal pure returns (uint256 xauAmount) {
        require(xauRate > 0, "XAUTriangulation: invalid XAU rate");
        xauAmount = (amount * 1e18) / xauRate;
    }
    
    /**
     * @notice Convert XAU amount to currency
     * @param xauAmount Amount in XAU (18 decimals)
     * @param xauRate Rate: 1 oz XAU = xauRate units (18 decimals)
     * @return currencyAmount Amount in currency (18 decimals)
     */
    function fromXAU(uint256 xauAmount, uint256 xauRate) internal pure returns (uint256 currencyAmount) {
        require(xauRate > 0, "XAUTriangulation: invalid XAU rate");
        currencyAmount = (xauAmount * xauRate) / 1e18;
    }
}
