// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "../interfaces/IeMoneyJoin.sol"; import "../../emoney/interfaces/IeMoneyToken.sol"; /** * @title eMoneyJoin * @notice Adapter for minting and burning eMoney tokens * @dev Mint/burn restricted to this adapter, transfer restricted via Compliance Registry */ contract eMoneyJoin is IeMoneyJoin, AccessControl, ReentrancyGuard { bytes32 public constant VAULT_ROLE = keccak256("VAULT_ROLE"); mapping(address => bool) public approvedCurrencies; constructor(address admin) { _grantRole(DEFAULT_ADMIN_ROLE, admin); } /** * @notice Mint eMoney to a borrower * @param currency eMoney currency address * @param to Recipient address * @param amount Amount to mint */ function mint(address currency, address to, uint256 amount) external override nonReentrant onlyRole(VAULT_ROLE) { require(approvedCurrencies[currency], "eMoneyJoin: currency not approved"); require(to != address(0), "eMoneyJoin: zero address"); require(amount > 0, "eMoneyJoin: zero amount"); IeMoneyToken token = IeMoneyToken(currency); token.mint(to, amount, keccak256("VAULT_BORROW")); emit eMoneyMinted(currency, to, amount); } /** * @notice Burn eMoney from a repayer * @param currency eMoney currency address * @param from Source address * @param amount Amount to burn */ function burn(address currency, address from, uint256 amount) external override nonReentrant onlyRole(VAULT_ROLE) { require(approvedCurrencies[currency], "eMoneyJoin: currency not approved"); require(amount > 0, "eMoneyJoin: zero amount"); IeMoneyToken token = IeMoneyToken(currency); token.burn(from, amount, keccak256("VAULT_REPAY")); emit eMoneyBurned(currency, from, amount); } /** * @notice Approve a currency for eMoney operations * @param currency Currency address */ function approveCurrency(address currency) external onlyRole(DEFAULT_ADMIN_ROLE) { approvedCurrencies[currency] = true; } /** * @notice Revoke currency approval * @param currency Currency address */ function revokeCurrency(address currency) external onlyRole(DEFAULT_ADMIN_ROLE) { approvedCurrencies[currency] = false; } }