Files
smom-dbis-138/contracts/tokens/CompliantMonetaryUnitToken.sol
defiQUG 76aa419320 feat: bridges, PMM, flash workflow, token-aggregation, and deployment docs
- CCIP/trustless bridge contracts, GRU tokens, DEX/PMM tests, reserve vault.
- Token-aggregation service routes, planner, chain config, relay env templates.
- Config snapshots and multi-chain deployment markdown updates.
- gitignore services/btc-intake/dist/ (tsc output); do not track dist.

Run forge build && forge test before deploy (large solc graph).

Made-with: Cursor
2026-04-07 23:40:52 -07:00

87 lines
2.4 KiB
Solidity

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "../compliance/LegallyCompliantBase.sol";
/**
* @title CompliantMonetaryUnitToken
* @notice Generic GRU monetary-unit token for non-ISO units such as BTC.
* @dev Mirrors the compliant fiat token controls while keeping monetary-unit metadata separate
* from ISO-4217 and commodity classifications.
*/
contract CompliantMonetaryUnitToken is ERC20, Pausable, Ownable, LegallyCompliantBase {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
uint8 private immutable _decimalsStorage;
string private _unitCode;
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_,
string memory unitCode_,
address initialOwner,
address admin,
uint256 initialSupply
)
ERC20(name_, symbol_)
Ownable(initialOwner)
LegallyCompliantBase(admin)
{
_decimalsStorage = decimals_;
_unitCode = unitCode_;
_grantRole(MINTER_ROLE, initialOwner);
if (initialSupply > 0) {
_mint(msg.sender, initialSupply);
}
}
function decimals() public view override returns (uint8) {
return _decimalsStorage;
}
function unitCode() external view returns (string memory) {
return _unitCode;
}
function isMonetaryUnit() external pure returns (bool) {
return true;
}
function _update(
address from,
address to,
uint256 amount
) internal override whenNotPaused {
super._update(from, to, amount);
if (from != address(0) && to != address(0)) {
bytes32 legalRefHash = _generateLegalReferenceHash(
from,
to,
amount,
abi.encodePacked(symbol(), " Transfer")
);
emit ValueTransferDeclared(from, to, amount, legalRefHash);
}
}
function pause() public onlyOwner {
_pause();
}
function unpause() public onlyOwner {
_unpause();
}
function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
_mint(to, amount);
}
function burn(uint256 amount) public {
_burn(msg.sender, amount);
}
}