Forkchoice Ethereum Mainnet

Address Contract Verified

Address 0x3Acf962Efa3288b0f7dEE33f8060BE53cF6e817F
Balance 0 ETH
Nonce 1
Code Size 3409 bytes
Indexed Transactions 0 (1 on-chain, 0.7% indexed)
External Etherscan · Sourcify

Contract Bytecode

3409 bytes
0x608060405234801561001057600080fd5b506004361061009e5760003560e01c806383482a8d1161006657806383482a8d146101415780638da5cb5b14610154578063925d35b714610167578063aede36931461017a578063f2fde38b1461018d57600080fd5b806306b091f9146100a35780630a547f4e146100b857806341f66d47146100cb578063727f191b146100fb5780638037b4ce1461012e575b600080fd5b6100b66100b1366004610ad2565b6101a0565b005b6100b66100c6366004610b0d565b610385565b6002546100de906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61011e610109366004610bc3565b60036020526000908152604090205460ff1681565b60405190151581526020016100f2565b6001546100de906001600160a01b031681565b6100b661014f366004610bdc565b610545565b6000546100de906001600160a01b031681565b6100b6610175366004610c11565b610669565b6100b6610188366004610bc3565b61073b565b6100b661019b366004610c11565b610815565b6000546001600160a01b031633146101d35760405162461bcd60e51b81526004016101ca90610c33565b60405180910390fd5b600081116101f35760405162461bcd60e51b81526004016101ca90610c74565b6040516370a0823160e01b815230600482015282906000906001600160a01b038316906370a0823190602401602060405180830381865afa15801561023c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102609190610ca9565b9050828110156102825760405162461bcd60e51b81526004016101ca90610cc2565b60005460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018590529083169063a9059cbb906044016020604051808303816000875af11580156102d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f99190610cf9565b61033d5760405162461bcd60e51b8152602060048201526015602482015274151bdad95b881d1c985b9cd9995c8819985a5b1959605a1b60448201526064016101ca565b604080516001600160a01b0386168152602081018590527f6352c5382c4a4578e712449ca65e83cdb392d045dfcf1cad9615189db2da244b910160405180910390a150505050565b600082116103a55760405162461bcd60e51b81526004016101ca90610c74565b6103b284843385856108c3565b6001546040516370a0823160e01b81523060048201526001600160a01b039091169060009082906370a0823190602401602060405180830381865afa1580156103ff573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104239190610ca9565b9050838110156104455760405162461bcd60e51b81526004016101ca90610cc2565b60405163a9059cbb60e01b8152336004820152602481018590526001600160a01b0383169063a9059cbb906044016020604051808303816000875af1158015610492573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b69190610cf9565b6104f85760405162461bcd60e51b815260206004820152601360248201527210d0d6081d1c985b9cd9995c8819985a5b1959606a1b60448201526064016101ca565b336001600160a01b031685877f191a58d19a6a9b76e2e91bdc04ecbe7553dc094a5ad7af78175a0d9f884e264a8760405161053591815260200190565b60405180910390a4505050505050565b600082116105655760405162461bcd60e51b81526004016101ca90610c74565b6001546040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b039091169081906323b872dd906064016020604051808303816000875af11580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e29190610cf9565b6106245760405162461bcd60e51b815260206004820152601360248201527210d0d6081d1c985b9cd9995c8819985a5b1959606a1b60448201526064016101ca565b6040805184815260ff84166020820152339186917f736c0ee359ba81a238883c3cf53dd9d45b58772b0c373d4b5e791bf27f5b2fec910160405180910390a350505050565b6000546001600160a01b031633146106935760405162461bcd60e51b81526004016101ca90610c33565b6001600160a01b0381166106e95760405162461bcd60e51b815260206004820152601f60248201527f496e76616c6964207369676e20636f6e74726f6c6c657220616464726573730060448201526064016101ca565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fe55ff8b860ac9cd12ae4b842c9428be606765a14e4c98fe53220850af3ebe99f90600090a35050565b6000546001600160a01b031633146107655760405162461bcd60e51b81526004016101ca90610c33565b600081116107855760405162461bcd60e51b81526004016101ca90610c74565b478111156107a55760405162461bcd60e51b81526004016101ca90610cc2565b600080546040516001600160a01b039091169183156108fc02918491818181858888f193505050501580156107de573d6000803e3d6000fd5b506040518181527fb40306741fb85f10308fbfc05bfd5daf07328c3a71ba82a45670c04733ef30809060200160405180910390a150565b6000546001600160a01b0316331461083f5760405162461bcd60e51b81526004016101ca90610c33565b6001600160a01b0381166108a15760405162461bcd60e51b8152602060048201526024808201527f4e6577206f776e65722063616e6e6f7420626520746865207a65726f206164646044820152637265737360e01b60648201526084016101ca565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b606081810151608083015160408051602081018a90529081018890526bffffffffffffffffffffffff1987851b81168286015260748201879052609482019390935260b48101919091523090921b1660d482015260009060e80160408051601f1981840301815291815281516020928301206000898152600390935291205490915060ff161561098b5760405162461bcd60e51b81526020600482015260136024820152724475706c6963617465207369676e617475726560681b60448201526064016101ca565b600086815260036020908152604091829020805460ff1916600190811790915591516109e5918491017f19457468657265756d205369676e6564204d6573736167653a0a3332000000008152601c810191909152603c0190565b60408051601f19818403018152828252805160209182012086518783015188850151600087529386018086529290925260ff16928401929092526060830191909152608082015260a0016020604051602081039080840390855afa158015610a51573d6000803e3d6000fd5b5050604051601f1901516002546001600160a01b039081169116149050610aae5760405162461bcd60e51b8152602060048201526011602482015270496e76616c6964207369676e617475726560781b60448201526064016101ca565b505050505050565b80356001600160a01b0381168114610acd57600080fd5b919050565b60008060408385031215610ae557600080fd5b610aee83610ab6565b946020939093013593505050565b803560ff81168114610acd57600080fd5b600080600080848603610100811215610b2557600080fd5b85359450602086013593506040860135925060a0605f1982011215610b4957600080fd5b5060405160a0810181811067ffffffffffffffff82111715610b7b57634e487b7160e01b600052604160045260246000fd5b604052610b8a60608701610afc565b8152608086810135602083015260a0870135604083015260c0870135606083015260e09096013595810195909552509194909350909190565b600060208284031215610bd557600080fd5b5035919050565b600080600060608486031215610bf157600080fd5b8335925060208401359150610c0860408501610afc565b90509250925092565b600060208284031215610c2357600080fd5b610c2c82610ab6565b9392505050565b60208082526021908201527f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6040820152603760f91b606082015260800190565b6020808252818101527f416d6f756e74206d7573742062652067726561746572207468616e207a65726f604082015260600190565b600060208284031215610cbb57600080fd5b5051919050565b6020808252601d908201527f496e73756666696369656e7420636f6e74726163742062616c616e6365000000604082015260600190565b600060208284031215610d0b57600080fd5b81518015158114610c2c57600080fdfea2646970667358221220c9262527c09ffd95977cbcf231a46afbe32692aa377e89c06ab108d85c3ce11664736f6c634300081a0033

Verified Source Code Full Match

Compiler: v0.8.26+commit.8a97fa7a EVM: paris Optimization: Yes (200 runs)
CCXInvest.sol 221 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);

    function decimals() external view returns (uint8);

    function transfer(
        address recipient,
        uint256 amount
    ) external returns (bool);

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);
}

contract CCXInvest  {
    address public owner;
    address public ccxToken;
    address public signController;

    mapping(uint256 => bool) public isValidSign;


    struct Sign {
        uint8 v;
        bytes32 r;
        bytes32 s;
        uint256 nonce;
        uint256 time;
    }

    event Withdraw(
        uint256 indexed uniqueId,
        uint256 indexed userId,
        address indexed user,
        uint256 ccxAmount
    );

    event InvestDetails(
        uint256 indexed userId,
        address indexed user,
        uint256 ccxAmount,
        uint8 planId
    );

    event TokensWithdrawn(address token, uint256 amount);
    event SignControllerUpdated(
        address indexed oldController,
        address indexed newController
    );
    event NativeRecovered(uint256 amount);

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner can call this function");
        _;
    }

    constructor(
        address _owner,
        address _ccxToken,
        address _signController
    ) {
        owner = _owner;
        ccxToken = _ccxToken;
        signController = _signController;
    }


    /**
     * @dev Swaps USDT to CCX
     * @param userId The user id of user
     * @param ccxAmount The amount of CCX to swap
     */
    function Invest(uint256 userId, uint256 ccxAmount,uint8 _planId) external {
        require(ccxAmount > 0, "Amount must be greater than zero");

        IERC20 usdt = IERC20(ccxToken);

        // Transfer USDT from user to this contract
        require(
            usdt.transferFrom(msg.sender, address(this), ccxAmount),
            "CCX transfer failed"
        );

        emit InvestDetails(userId, msg.sender, ccxAmount,_planId);
    }

    /**
     * @dev Allows users to withdraw their CCX tokens with signature verification
     * @param uniqueId A unique identifier for this withdrawal transaction
     * @param userId The user ID associated with this withdrawal
     * @param ccxAmount The amount of CCX to withdraw
     * @param sign The signature data for verification
     */
    function withdraw(
        uint256 uniqueId,
        uint256 userId,
        uint256 ccxAmount,
        Sign memory sign
    ) external {
        require(ccxAmount > 0, "Amount must be greater than zero");

        // Verify the signature
        verifySign(uniqueId, userId, msg.sender, ccxAmount, sign);

        // Transfer CCX tokens to the user
        IERC20 ccx = IERC20(ccxToken);
        uint256 contractBalance = ccx.balanceOf(address(this));
        require(contractBalance >= ccxAmount, "Insufficient contract balance");

        require(ccx.transfer(msg.sender, ccxAmount), "CCX transfer failed");

        emit Withdraw(uniqueId, userId, msg.sender, ccxAmount);
    }

    /**
     * @dev Allows the owner to withdraw tokens from the contract
     * @param token The address of the token to withdraw
     * @param amount The amount of tokens to withdraw
     */
    function withdrawTokens(address token, uint256 amount) external onlyOwner {
        require(amount > 0, "Amount must be greater than zero");

        IERC20 tokenContract = IERC20(token);
        uint256 contractBalance = tokenContract.balanceOf(address(this));
        require(contractBalance >= amount, "Insufficient contract balance");

        require(tokenContract.transfer(owner, amount), "Token transfer failed");

        emit TokensWithdrawn(token, amount);
    }

    /**
     * @dev Verifies the signature for withdrawal requests
     * @param uniqueId A unique identifier for the transaction
     * @param userId The user ID associated with this transaction
     * @param user The address of the user requesting withdrawal
     * @param amount The amount to withdraw
     * @param sign The signature data to verify
     */
    function verifySign(
        uint256 uniqueId,
        uint256 userId,
        address user,
        uint256 amount,
        Sign memory sign
    ) internal {
        bytes32 hash = keccak256(
            abi.encodePacked(
                uniqueId,
                userId,
                user,
                amount,
                sign.nonce,
                sign.time,
                address(this)
            )
        );

        require(!isValidSign[uniqueId], "Duplicate signature");
        isValidSign[uniqueId] = true;
        require(
            signController ==
                ecrecover(
                    keccak256(
                        abi.encodePacked(
                            "\x19Ethereum Signed Message:\n32",
                            hash
                        )
                    ),
                    sign.v,
                    sign.r,
                    sign.s
                ),
            "Invalid signature"
        );
    }

    /**
     * @dev Updates the signature controller address
     * @param _signController The address of the new signature controller
     */
    function setSignController(address _signController) external onlyOwner {
        require(
            _signController != address(0),
            "Invalid sign controller address"
        );

        address oldController = signController;
        signController = _signController;
        emit SignControllerUpdated(oldController, _signController);
    }

    /**
     * @dev Allows the owner to recover native cryptocurrency (ETH) sent to the contract
     * @param amount The amount of native currency to recover
     */
    function recoverNative(uint256 amount) external onlyOwner {
        require(amount > 0, "Amount must be greater than zero");
        require(
            amount <= address(this).balance,
            "Insufficient contract balance"
        );
        payable(owner).transfer(amount);
        emit NativeRecovered(amount);
    }

    /**
     * @dev Allows the owner to transfer ownership of the contract
     * @param newOwner The address of the new owner
     */
    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "New owner cannot be the zero address");
        owner = newOwner;
    }
}

Read Contract

ccxToken 0x8037b4ce → address
isValidSign 0x727f191b → bool
owner 0x8da5cb5b → address
signController 0x41f66d47 → address

Write Contract 6 functions

These functions modify contract state and require a wallet transaction to execute.

Invest 0x83482a8d
uint256 userId
uint256 ccxAmount
uint8 _planId
recoverNative 0xaede3693
uint256 amount
setSignController 0x925d35b7
address _signController
transferOwnership 0xf2fde38b
address newOwner
withdraw 0xb13af2f4
uint256 uniqueId
uint256 userId
uint256 ccxAmount
tuple sign
withdrawTokens 0x06b091f9
address token
uint256 amount

Recent Transactions

This address has 1 on-chain transactions, but only 0.7% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →