Skip to main content
Glama
PrivateERC20.sol3.88 kB
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title Private ERC20 Token for COTI Blockchain * @notice This is a base template for COTI private ERC20 tokens * @dev Uses COTI's confidential types (ctUint64) for encrypted balances */ contract PrivateERC20 { string private _name; string private _symbol; uint8 private _decimals; // Note: In actual COTI contracts, balances use ctUint64 (confidential uint64) // This is handled by COTI's compiler and runtime mapping(address => uint256) private _balances; // In practice, this is ctUint64 mapping(address => mapping(address => uint256)) private _allowances; // In practice, encrypted uint256 private _totalSupply; address public owner; event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); event Mint(address indexed to, uint256 amount); modifier onlyOwner() { require(msg.sender == owner, "Only owner can call this function"); _; } constructor(string memory name_, string memory symbol_, uint8 decimals_) { require(decimals_ >= 0 && decimals_ <= 6, "Decimals must be between 0 and 6 for COTI private tokens"); _name = name_; _symbol = symbol_; _decimals = decimals_; owner = msg.sender; } function name() public view returns (string memory) { return _name; } function symbol() public view returns (string memory) { return _symbol; } function decimals() public view returns (uint8) { return _decimals; } function totalSupply() public view returns (uint256) { return _totalSupply; } function balanceOf(address account) public view returns (uint256) { return _balances[account]; } function transfer(address to, uint256 amount) public returns (bool) { _transfer(msg.sender, to, amount); return true; } function allowance(address owner_, address spender) public view returns (uint256) { return _allowances[owner_][spender]; } function approve(address spender, uint256 amount) public returns (bool) { _approve(msg.sender, spender, amount); return true; } function transferFrom(address from, address to, uint256 amount) public returns (bool) { _spendAllowance(from, msg.sender, amount); _transfer(from, to, amount); return true; } function mint(address to, uint256 amount) public onlyOwner { require(to != address(0), "Cannot mint to zero address"); require(amount <= type(uint64).max, "Amount exceeds uint64 maximum for COTI"); _totalSupply += amount; _balances[to] += amount; emit Mint(to, amount); emit Transfer(address(0), to, amount); } function _transfer(address from, address to, uint256 amount) internal { require(from != address(0), "Transfer from zero address"); require(to != address(0), "Transfer to zero address"); require(_balances[from] >= amount, "Insufficient balance"); _balances[from] -= amount; _balances[to] += amount; emit Transfer(from, to, amount); } function _approve(address owner_, address spender, uint256 amount) internal { require(owner_ != address(0), "Approve from zero address"); require(spender != address(0), "Approve to zero address"); _allowances[owner_][spender] = amount; emit Approval(owner_, spender, amount); } function _spendAllowance(address owner_, address spender, uint256 amount) internal { uint256 currentAllowance = _allowances[owner_][spender]; require(currentAllowance >= amount, "Insufficient allowance"); _approve(owner_, spender, currentAllowance - amount); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/davibauer/coti-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server