Description:
Smart contract deployed on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/// @title The Digital Dollar (USD) - ERC20 compliant token for DEX use
/// @notice Standard ERC20 with admin mint/burn and address freeze for compliance
contract TheDigitalDollar {
string public constant name = "The Digital Dollar";
string public constant symbol = "USD";
uint8 public constant decimals = 18;
uint256 public totalSupply;
address public owner;
address public compliance;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
mapping(address => bool) public frozen;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed ownerAddr, address indexed spender, uint256 value);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event ComplianceTransferred(address indexed previousCompliance, address indexed newCompliance);
event AddressFrozen(address indexed account, bool frozen);
event Mint(address indexed to, uint256 amount);
event Burn(address indexed from, uint256 amount);
error NotOwner();
error NotCompliance();
error FrozenAddress();
error InsufficientBalance();
error AllowanceExceeded();
error ZeroAddress();
uint256 public constant INITIAL_SUPPLY = 100_000_000_000_000 * 1e18;
constructor() {
owner = msg.sender;
compliance = msg.sender;
totalSupply = INITIAL_SUPPLY;
balanceOf[msg.sender] = INITIAL_SUPPLY;
emit Transfer(address(0), msg.sender, INITIAL_SUPPLY);
}
modifier onlyOwner() {
if (msg.sender != owner) revert NotOwner();
_;
}
modifier onlyCompliance() {
if (msg.sender != compliance) revert NotCompliance();
_;
}
modifier notFrozen(address account) {
if (frozen[account]) revert FrozenAddress();
_;
}
function transfer(address to, uint256 value)
external
notFrozen(msg.sender)
notFrozen(to)
returns (bool)
{
uint256 senderBalance = balanceOf[msg.sender];
if (senderBalance < value) revert InsufficientBalance();
unchecked {
balanceOf[msg.sender] = senderBalance - value;
balanceOf[to] += value;
}
emit Transfer(msg.sender, to, value);
return true;
}
function approve(address spender, uint256 value)
external
notFrozen(msg.sender)
notFrozen(spender)
returns (bool)
{
allowance[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
function transferFrom(address from, address to, uint256 value)
external
notFrozen(msg.sender)
notFrozen(from)
notFrozen(to)
returns (bool)
{
uint256 fromBalance = balanceOf[from];
if (fromBalance < value) revert InsufficientBalance();
uint256 allowed = allowance[from][msg.sender];
if (allowed < value) revert AllowanceExceeded();
if (allowed != type(uint256).max) {
unchecked {
allowance[from][msg.sender] = allowed - value;
}
emit Approval(from, msg.sender, allowance[from][msg.sender]);
}
unchecked {
balanceOf[from] = fromBalance - value;
balanceOf[to] += value;
}
emit Transfer(from, to, value);
return true;
}
function increaseAllowance(address spender, uint256 addedValue)
external
notFrozen(msg.sender)
notFrozen(spender)
returns (bool)
{
uint256 newAllowance = allowance[msg.sender][spender] + addedValue;
allowance[msg.sender][spender] = newAllowance;
emit Approval(msg.sender, spender, newAllowance);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue)
external
notFrozen(msg.sender)
notFrozen(spender)
returns (bool)
{
uint256 current = allowance[msg.sender][spender];
uint256 newAllowance = (subtractedValue >= current) ? 0 : current - subtractedValue;
allowance[msg.sender][spender] = newAllowance;
emit Approval(msg.sender, spender, newAllowance);
return true;
}
function mint(address to, uint256 amount) external onlyOwner {
if (to == address(0)) revert ZeroAddress();
totalSupply += amount;
balanceOf[to] += amount;
emit Mint(to, amount);
emit Transfer(address(0), to, amount);
}
function burn(address from, uint256 amount) external onlyOwner {
if (from == address(0)) revert ZeroAddress();
uint256 bal = balanceOf[from];
if (bal < amount) revert InsufficientBalance();
unchecked {
balanceOf[from] = bal - amount;
totalSupply -= amount;
}
emit Burn(from, amount);
emit Transfer(from, address(0), amount);
}
function burnFrom(address from, uint256 amount)
external
notFrozen(msg.sender)
notFrozen(from)
{
uint256 allowed = allowance[from][msg.sender];
if (allowed < amount) revert AllowanceExceeded();
if (allowed != type(uint256).max) {
unchecked {
allowance[from][msg.sender] = allowed - amount;
}
emit Approval(from, msg.sender, allowance[from][msg.sender]);
}
uint256 bal = balanceOf[from];
if (bal < amount) revert InsufficientBalance();
unchecked {
balanceOf[from] = bal - amount;
totalSupply -= amount;
}
emit Burn(from, amount);
emit Transfer(from, address(0), amount);
}
function setCompliance(address newCompliance) external onlyOwner {
if (newCompliance == address(0)) revert ZeroAddress();
emit ComplianceTransferred(compliance, newCompliance);
compliance = newCompliance;
}
function transferOwnership(address newOwner) external onlyOwner {
if (newOwner == address(0)) revert ZeroAddress();
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
function setFrozen(address account, bool isFrozen) external onlyCompliance {
frozen[account] = isFrozen;
emit AddressFrozen(account, isFrozen);
}
}
Submitted on: 2025-10-09 09:56:31
Comments
Log in to comment.
No comments yet.