// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title USDC.e — Bridged USDC on AERE Network (Phase 1, Hyperlane Warp Route)
 * @notice ERC-20 wrapper representing locked USDC on Ethereum mainnet,
 *         minted on AERE Chain ID 2800 by AereHypERC20Synthetic when a
 *         Hyperlane Warp Route deposit message arrives. Burned when a user
 *         withdraws back to mainnet.
 *
 * @dev    PHASE 1 design intentionally:
 *         - Uses a clean OpenZeppelin ERC-20 implementation (NOT the
 *           Circle FiatToken vendored bytecode). This is the
 *           independent "bridged" form; Circle's USDC native on-AERE
 *           graduation requires the Circle Blockchain Due Diligence
 *           Process (estimated 18-24 months) and a bytecode-identical
 *           FiatTokenV2_2 re-deploy.
 *         - Mint and burn are restricted to the canonical
 *           AereHypERC20Synthetic contract on AERE (set immutably at
 *           deploy). The synthetic is the *only* bridge endpoint that
 *           can produce or destroy USDC.e — no admin can mint.
 *
 *         Compatibility:
 *         - 6 decimals to match Circle native USDC (not the 18 default).
 *         - Standard transfer / approve / transferFrom.
 *         - No blacklist / pauser surfaces in this Phase 1 version. The
 *           Foundation publishes a clear "USDC.e is bridged, not native
 *           Circle USDC" disclosure on the /cross-chain page.
 *
 *         Reserve attestation:
 *         - Locked Ethereum-side USDC backing USDC.e supply is
 *           verifiable on-chain: the AereHypERC20Collateral on mainnet
 *           holds exactly totalSupply * 1e-12 units of native USDC (the
 *           decimal-mismatch divisor). A nightly snapshot is committed
 *           by AereNavOracle (Q3 2026 ship).
 */
contract USDCe is ERC20 {
    /// @notice The one and only contract that can mint or burn USDC.e.
    address public immutable BRIDGE;

    error OnlyBridge();

    modifier onlyBridge() {
        if (msg.sender != BRIDGE) revert OnlyBridge();
        _;
    }

    constructor(address bridge) ERC20("Bridged USD Coin", "USDC.e") {
        require(bridge != address(0), "USDCe: zero bridge");
        BRIDGE = bridge;
    }

    /// @notice Match Circle USDC's 6 decimals (not OZ default 18).
    function decimals() public pure override returns (uint8) {
        return 6;
    }

    /// @notice Mint by the bridge when a Hyperlane Warp Route message
    ///         arrives confirming a corresponding deposit on Ethereum.
    function mint(address to, uint256 amount) external onlyBridge {
        _mint(to, amount);
    }

    /// @notice Burn by the bridge when a user requests withdrawal back to
    ///         Ethereum.
    function burnFrom(address from, uint256 amount) external onlyBridge {
        _burn(from, amount);
    }
}
