// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/utils/Pausable.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "./IDBISTypes.sol"; interface IERC20Mintable { function mint(address to, uint256 amount) external; } contract DBIS_GRU_MintController is AccessControl, Pausable, ReentrancyGuard { bytes32 public constant ROUTER_ADMIN_ROLE = keccak256("ROUTER_ADMIN"); address public settlementRouter; address public gruToken; event MintFromAuthorization(bytes32 indexed messageId, address indexed recipient, uint256 amount, uint8 assetClass); constructor(address admin, address _settlementRouter) { _grantRole(DEFAULT_ADMIN_ROLE, admin); _grantRole(ROUTER_ADMIN_ROLE, admin); settlementRouter = _settlementRouter; } function setSettlementRouter(address _router) external onlyRole(ROUTER_ADMIN_ROLE) { settlementRouter = _router; } function setGruToken(address _token) external onlyRole(ROUTER_ADMIN_ROLE) { gruToken = _token; } function pause() external onlyRole(ROUTER_ADMIN_ROLE) { _pause(); } function unpause() external onlyRole(ROUTER_ADMIN_ROLE) { _unpause(); } function mintFromAuthorization(IDBISTypes.MintAuth calldata auth) external nonReentrant whenNotPaused { require(msg.sender == settlementRouter, "DBIS: only router"); require(gruToken != address(0), "DBIS: token not set"); require(auth.recipients.length == auth.amounts.length, "DBIS: length mismatch"); _mintToRecipients(auth); } function _mintToRecipients(IDBISTypes.MintAuth calldata auth) private { IERC20Mintable t = IERC20Mintable(gruToken); uint256 n = auth.recipients.length; bytes32 mid = auth.messageId; uint8 ac = uint8(auth.assetClass); for (uint256 i; i < n; i++) { address to = auth.recipients[i]; require(to != address(0), "DBIS: zero recipient"); t.mint(to, auth.amounts[i]); emit MintFromAuthorization(mid, to, auth.amounts[i], ac); } } }