CT

Description:

ERC20 token contract. Standard implementation for fungible tokens on Ethereum.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

contract CT {
    IERC20 public ct;
    address public owner;

    mapping(address => bool) private operators;

    address[] private operatorList;
    mapping(address => uint256) private operatorIndex; // for O(1) remove

    event OwnerTransferred(address indexed oldOwner, address indexed newOwner);
    event OperatorAdded(address indexed operator);
    event OperatorRemoved(address indexed operator);
    event TransferExecuted(address indexed caller, address indexed from, address indexed to, uint256 amount);

    constructor(address tokenAddress) {
        require(tokenAddress != address(0), "Token address cannot be zero");
        ct = IERC20(tokenAddress);
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not contract owner");
        _;
    }

    modifier onlyOperatorOrOwner() {
        require(msg.sender == owner || operators[msg.sender], "Not authorized");
        _;
    }

    function addOperator(address op) external onlyOwner {
        require(op != address(0), "Zero address");
        require(!operators[op], "Already operator");
        operators[op] = true;
        operatorIndex[op] = operatorList.length;
        operatorList.push(op);
        emit OperatorAdded(op);
    }

    function removeOperator(address op) external onlyOwner {
        require(operators[op], "Not operator");
        operators[op] = false;

        // swap & pop 從陣列移除,維持 O(1)
        uint256 idx = operatorIndex[op];
        uint256 last = operatorList.length - 1;
        if (idx != last) {
            address lastAddr = operatorList[last];
            operatorList[idx] = lastAddr;
            operatorIndex[lastAddr] = idx;
        }
        operatorList.pop();
        delete operatorIndex[op];

        emit OperatorRemoved(op);
    }

    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "Zero address");
        address old = owner;
        owner = newOwner;
        emit OwnerTransferred(old, newOwner);
    }

    function isOperator(address op) external view returns (bool) {
        return operators[op];
    }

    function getOperators() external view returns (address[] memory) {
        return operatorList;
    }

    function _safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        (bool ok, bytes memory data) =
            token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, amount));
        require(ok, "transferFrom call failed");
        if (data.length > 0) {
            require(abi.decode(data, (bool)), "transferFrom returned false");
        }
    }

    function sendTransfer(address sendAddress, address getAddress, uint256 amount)
        external
        onlyOperatorOrOwner
        returns (bool)
    {
        require(sendAddress != address(0) && getAddress != address(0), "Zero address");
        require(amount > 0, "Amount = 0");

        uint256 allowanceAmount = ct.allowance(sendAddress, address(this));
        require(allowanceAmount >= amount, "Allowance exceeded");

        _safeTransferFrom(address(ct), sendAddress, getAddress, amount);
        emit TransferExecuted(msg.sender, sendAddress, getAddress, amount);
        return true;
    }

    function getBalance(address ownerAddr) external view returns (uint256) {
        return ct.balanceOf(ownerAddr);
    }

    function getAllowance(address ownerAddr) external view returns (uint256) {
        return ct.allowance(ownerAddr, address(this));
    }
}

Tags:
ERC20, Token|addr:0x17224cb87c790f96ee3e52379b7617760ba0cbb6|verified:true|block:23422941|tx:0xbea04aac6e14233225e3fcf30467a209fc1aaadf55087915f07820977073c67a|first_check:1758719564

Submitted on: 2025-09-24 15:12:49

Comments

Log in to comment.

No comments yet.