// 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); } }