Files
smom-dbis-138/contracts/wrapped-lp-public/PublicChainMintController.sol

47 lines
1.8 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "./WLPReceiptToken.sol";
import "./interfaces/IWLPProgramEvents.sol";
/**
* @title PublicChainMintController
* @notice Destination-chain controller: mints `wLP` once per `lockRef` (replay protection).
* @dev Relayer must verify Chain 138 `LPLocked` event / attestation off-chain or via future ZK proof.
*/
contract PublicChainMintController is AccessControl, IWLPProgramEvents {
bytes32 public constant RELAYER_ROLE = keccak256("RELAYER_ROLE");
WLPReceiptToken public immutable wlp;
/// @notice Optional Chain 138 locker address for documentation / future cross-verify hooks.
address public immutable chain138Locker;
mapping(bytes32 => bool) public mintedForLock;
bool public mintPaused;
constructor(address wlp_, address chain138Locker_, address admin) {
require(wlp_ != address(0) && admin != address(0), "MintCtl: zero");
wlp = WLPReceiptToken(wlp_);
chain138Locker = chain138Locker_;
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}
/**
* @notice Idempotent mint keyed by `lockRef` (must match Chain 138 locker emission).
*/
function mintForLock(bytes32 lockRef, address recipient, uint256 amount) external onlyRole(RELAYER_ROLE) {
require(!mintPaused, "MintCtl: paused");
require(lockRef != bytes32(0), "MintCtl: zero lockRef");
require(recipient != address(0) && amount > 0, "MintCtl: bad args");
require(!mintedForLock[lockRef], "MintCtl: replay");
mintedForLock[lockRef] = true;
wlp.mint(recipient, amount);
emit WLPMinted(lockRef, recipient, amount);
}
function setMintPaused(bool paused) external onlyRole(DEFAULT_ADMIN_ROLE) {
mintPaused = paused;
}
}