// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.29; import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol"; import "../interfaces/IMintableBurnable.sol"; /** * @title Omnichain Token * @author USD.AI Foundation */ contract OToken is IMintableBurnable, ERC20Upgradeable, ERC20PermitUpgradeable, ReentrancyGuardUpgradeable, AccessControlUpgradeable, MulticallUpgradeable, PausableUpgradeable { /*------------------------------------------------------------------------*/ /* Constants */ /*------------------------------------------------------------------------*/ /** * @notice Implementation version */ string public constant IMPLEMENTATION_VERSION = "1.1"; /** * @notice Pause admin role */ bytes32 public constant PAUSE_ADMIN_ROLE = keccak256("PAUSE_ADMIN_ROLE"); /*------------------------------------------------------------------------*/ /* Immutable State */ /*------------------------------------------------------------------------*/ /** * @notice OAdapter address */ address private immutable _oAdapter; /*------------------------------------------------------------------------*/ /* Constructor */ /*------------------------------------------------------------------------*/ /** * @notice Omnichain Token Constructor * @param oAdapter_ OAdapter address */ constructor( address oAdapter_ ) { _disableInitializers(); _oAdapter = oAdapter_; } /*------------------------------------------------------------------------*/ /* Initializer */ /*------------------------------------------------------------------------*/ /** * @notice Initialize the contract * @param name_ Token name * @param symbol_ Token symbol * @param admin Default admin address */ function initialize(string memory name_, string memory symbol_, address admin) external initializer { __ERC20_init(name_, symbol_); __ERC20Permit_init(name_); __ReentrancyGuard_init(); __AccessControl_init(); __Multicall_init(); __Pausable_init(); /* Grant roles */ _grantRole(DEFAULT_ADMIN_ROLE, admin); } /*------------------------------------------------------------------------*/ /* Modifiers */ /*------------------------------------------------------------------------*/ /** * @notice Modifier to check if the caller is the OAdapter */ modifier onlyOAdapter() { require(msg.sender == _oAdapter, "Not authorized"); _; } /*------------------------------------------------------------------------*/ /* Minter API */ /*------------------------------------------------------------------------*/ /** * @inheritdoc IMintableBurnable */ function mint(address to, uint256 amount) external whenNotPaused onlyOAdapter nonReentrant { _mint(to, amount); } /** * @inheritdoc IMintableBurnable */ function burn(address from, uint256 amount) external whenNotPaused onlyOAdapter nonReentrant { _burn(from, amount); } /*------------------------------------------------------------------------*/ /* Pause Admin API */ /*------------------------------------------------------------------------*/ /** * @notice Pause the contract */ function pause() external onlyRole(PAUSE_ADMIN_ROLE) { _pause(); } /** * @notice Unpause the contract */ function unpause() external onlyRole(PAUSE_ADMIN_ROLE) { _unpause(); } }