// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {Test, console} from "forge-std/Test.sol"; import "../../../../contracts/bridge/trustless/integration/ISOCurrencyManager.sol"; import "../../../../contracts/reserve/ReserveSystem.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract MockERC20 is ERC20 { constructor(string memory name, string memory symbol) ERC20(name, symbol) { _mint(msg.sender, 1000000 ether); } } contract ISOCurrencyManagerTest is Test { ISOCurrencyManager public isoCurrencyManager; ReserveSystem public reserveSystem; MockERC20 public xau; MockERC20 public usdt; MockERC20 public eurToken; address public deployer = address(0xDE0001); function setUp() public { vm.startPrank(deployer); // Deploy mock tokens xau = new MockERC20("Gold", "XAU"); usdt = new MockERC20("Tether USD", "USDT"); eurToken = new MockERC20("Euro", "EUR"); // Deploy ReserveSystem reserveSystem = new ReserveSystem(deployer); // Grant PRICE_FEED_ROLE to deployer reserveSystem.grantRole(keccak256("PRICE_FEED_ROLE"), deployer); // Set prices reserveSystem.updatePriceFeed(address(xau), 2000e18, block.timestamp); // $2000/oz reserveSystem.updatePriceFeed(address(usdt), 1e18, block.timestamp); // $1.00 // Deploy ISOCurrencyManager isoCurrencyManager = new ISOCurrencyManager(address(reserveSystem)); isoCurrencyManager.setXAUAddress(address(xau)); // Register currencies // 1 oz XAU = 2000 USD isoCurrencyManager.registerCurrency("USD", address(usdt), 2000e18); // 1 oz XAU = 1800 EUR isoCurrencyManager.registerCurrency("EUR", address(eurToken), 1800e18); // 1 oz XAU = 300000 JPY (example) isoCurrencyManager.registerCurrency("JPY", address(0), 300000e18); vm.stopPrank(); } function testRegisterCurrency() public { string[] memory currencies = isoCurrencyManager.getAllSupportedCurrencies(); assertEq(currencies.length, 3); } function testConvertViaXAU() public { // Convert 2000 USD to EUR via XAU // 2000 USD = 1 oz XAU = 1800 EUR uint256 usdAmount = 2000 ether; uint256 eurAmount = isoCurrencyManager.convertViaXAU("USD", "EUR", usdAmount); assertApproxEqRel(eurAmount, 1800e18, 0.01e18); // 1% tolerance } function testGetCurrencyRate() public { // USD to EUR rate // 1 USD = (1800 / 2000) EUR = 0.9 EUR uint256 rate = isoCurrencyManager.getCurrencyRate("USD", "EUR"); assertApproxEqRel(rate, 0.9e18, 0.01e18); } function testGetCurrencyAddress() public { address usdAddress = isoCurrencyManager.getCurrencyAddress("USD"); assertEq(usdAddress, address(usdt)); address eurAddress = isoCurrencyManager.getCurrencyAddress("EUR"); assertEq(eurAddress, address(eurToken)); address jpyAddress = isoCurrencyManager.getCurrencyAddress("JPY"); assertEq(jpyAddress, address(0)); // Not tokenized } function testGetCurrencyInfo() public { (address tokenAddress, uint256 xauRate, bool isActive, bool isTokenized) = isoCurrencyManager.getCurrencyInfo("USD"); assertEq(tokenAddress, address(usdt)); assertEq(xauRate, 2000e18); assertTrue(isActive); assertTrue(isTokenized); } function testUpdateXauRate() public { uint256 newRate = 2100e18; // Update to 2100 USD per oz XAU vm.prank(deployer); isoCurrencyManager.updateXauRate("USD", newRate); // Verify rate was updated (address tokenAddress, uint256 xauRate, , ) = isoCurrencyManager.getCurrencyInfo("USD"); assertEq(xauRate, newRate); } function testBatchRegisterCurrencies() public { string[] memory codes = new string[](2); codes[0] = "GBP"; codes[1] = "CNY"; address[] memory addresses = new address[](2); addresses[0] = address(0); addresses[1] = address(0); uint256[] memory rates = new uint256[](2); rates[0] = 1500e18; // 1 oz XAU = 1500 GBP rates[1] = 14000e18; // 1 oz XAU = 14000 CNY // batchRegisterCurrencies calls registerCurrency which requires owner vm.startPrank(deployer); isoCurrencyManager.batchRegisterCurrencies(codes, addresses, rates); vm.stopPrank(); string[] memory allCurrencies = isoCurrencyManager.getAllSupportedCurrencies(); assertGe(allCurrencies.length, 5); // Should have at least 5 currencies now } }