Forkchoice Ethereum Mainnet

Address Contract Partially Verified

Address 0x0c70a006a393D078B97a6Ee5358CD6aEC976b33b
Balance 0 ETH
Nonce 1
Code Size 3372 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

3372 bytes
0x608060405234801561000f575f80fd5b50600436106101a1575f3560e01c806391b7f5ed116100f3578063d18d944b11610093578063efbe1c1c1161006e578063efbe1c1c146103a4578063f6a03ebf146103ad578063fb86a404146103c0578063ff6e6792146103c9575f80fd5b8063d18d944b1461036b578063d96a094a1461037e578063e8307d0014610391575f80fd5b8063ae1133de116100ce578063ae1133de14610331578063be9a655514610350578063bedac10014610359578063c07f773a14610362575f80fd5b806391b7f5ed146102ed578063977b055b14610300578063a275999c14610309575f80fd5b8063711897421161015e578063813d6c9a11610139578063813d6c9a146102ab578063842a77d3146102b45780638b2ec761146102d35780638da5cb5b146102db575f80fd5b8063711897421461027c5780637b1b1de61461028f5780637f498ffc14610298575f80fd5b80630b98f975146101a55780630da39942146101ba57806322f3e2d4146101f557806333b5b62e1461020d5780633e413bee1461021657806361d027b314610255575b5f80fd5b6101b86101b3366004610c09565b6103d1565b005b6101e26101c8366004610c20565b6001600160a01b03165f908152600b602052604090205490565b6040519081526020015b60405180910390f35b6101fd610490565b60405190151581526020016101ec565b6101e260015481565b61023d7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b6040516001600160a01b0390911681526020016101ec565b61023d7f0000000000000000000000001d1102132ca6966e9b8c5c7207ac8f154275c33181565b6101b861028a366004610c09565b6104aa565b6101e260065481565b6101b86102a6366004610c09565b61054c565b6101e260075481565b6101e26102c2366004610c20565b600a6020525f908152604090205481565b6009546101e2565b5f5461023d906001600160a01b031681565b6101b86102fb366004610c09565b6105fb565b6101e260025481565b6101e2610317366004610c20565b6001600160a01b03165f908152600a602052604090205490565b6101e261033f366004610c20565b600b6020525f908152604090205481565b6101e260035481565b6101e260085481565b6101e260095481565b6101b8610379366004610c09565b61069c565b6101b861038c366004610c09565b61073e565b6101b861039f366004610c09565b610a77565b6101e260045481565b6101b86103bb366004610c09565b610b5a565b6101e260055481565b6008546101e2565b5f546001600160a01b031633146104035760405162461bcd60e51b81526004016103fa90610c4d565b60405180910390fd5b60648111156104545760405162461bcd60e51b815260206004820152601860248201527f426f6e75732063616e6e6f74206578636565642031303025000000000000000060448201526064016103fa565b60078190556040518181527f04a7ca0e55f887a637b560614f621b92b79423e20152fea70bc4be66edaee3d6906020015b60405180910390a150565b5f60035442101580156104a557506004544211155b905090565b5f546001600160a01b031633146104d35760405162461bcd60e51b81526004016103fa90610c4d565b6001548110156105175760405162461bcd60e51b815260206004820152600f60248201526e26b0bc1036bab9ba101f1e9026b4b760891b60448201526064016103fa565b60028190556040518181527ff76421b7cb62dbc2958e2d434df25962fed8095d20fd189005042e7b9a435cc090602001610485565b5f546001600160a01b031633146105755760405162461bcd60e51b81526004016103fa90610c4d565b60035481116105c65760405162461bcd60e51b815260206004820152601760248201527f456e64206d75737420626520616674657220737461727400000000000000000060448201526064016103fa565b60048190556040518181527fa1da8d6fd955f8f6184cb54767db7046c0ed6dd113c7d5ab3a228008aa4f173c90602001610485565b5f546001600160a01b031633146106245760405162461bcd60e51b81526004016103fa90610c4d565b5f81116106675760405162461bcd60e51b815260206004820152601160248201527005072696365206d757374206265203e203607c1b60448201526064016103fa565b60068190556040518181527f66cbca4f3c64fecf1dcb9ce094abcf7f68c3450a1d4e3a8e917dd621edb4ebe090602001610485565b5f546001600160a01b031633146106c55760405162461bcd60e51b81526004016103fa90610c4d565b6008548110156107095760405162461bcd60e51b815260206004820152600f60248201526e4861726443617020746f6f206c6f7760881b60448201526064016103fa565b60058190556040518181527f898844af0a81a679f78c4e9bcc92363a6d161c41eb2398e0cf0196c156d05e8d90602001610485565b610746610490565b6107845760405162461bcd60e51b815260206004820152600f60248201526e53616c65206e6f742061637469766560881b60448201526064016103fa565b6001548110156107cb5760405162461bcd60e51b815260206004820152601260248201527142656c6f77206d696e20707572636861736560701b60448201526064016103fa565b600254335f908152600a60205260409020546107e8908390610c88565b111561082b5760405162461bcd60e51b815260206004820152601260248201527141626f7665206d617820707572636861736560701b60448201526064016103fa565b6005548160085461083c9190610c88565b111561087c5760405162461bcd60e51b815260206004820152600f60248201526e12185c9910d85c081c995858da1959608a1b60448201526064016103fa565b6006545f9061088e83620f4240610ca1565b6108989190610cb8565b90505f6064600754836108ab9190610ca1565b6108b59190610cb8565b90505f6108c28284610c88565b6040516323b872dd60e01b81523360048201526001600160a01b037f0000000000000000000000001d1102132ca6966e9b8c5c7207ac8f154275c33181166024830152604482018790529192507f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48909116906323b872dd906064016020604051808303815f875af1158015610959573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097d9190610cd7565b6109c05760405162461bcd60e51b81526020600482015260146024820152731554d110c81d1c985b9cd9995c8819985a5b195960621b60448201526064016103fa565b335f908152600a6020526040812080548692906109de908490610c88565b9091555050335f908152600b602052604081208054839290610a01908490610c88565b925050819055508360085f828254610a199190610c88565b925050819055508060095f828254610a319190610c88565b9091555050604080518581526020810183905233917ff761777482b4b40d2bcc0d050cfba6829900a2d8b3484bd0244ec0feeb3db504910160405180910390a250505050565b5f546001600160a01b03163314610aa05760405162461bcd60e51b81526004016103fa90610c4d565b5f8111610ae15760405162461bcd60e51b815260206004820152600f60248201526e04d696e206d757374206265203e203608c1b60448201526064016103fa565b600254811115610b255760405162461bcd60e51b815260206004820152600f60248201526e09ad2dc40daeae6e840787a409ac2f608b1b60448201526064016103fa565b60018190556040518181527faa5cd4951ddd9c7655806cf5372041af8c3d11d707ee625a1493401a51feb80190602001610485565b5f546001600160a01b03163314610b835760405162461bcd60e51b81526004016103fa90610c4d565b6004548110610bd45760405162461bcd60e51b815260206004820152601860248201527f5374617274206d757374206265206265666f726520656e64000000000000000060448201526064016103fa565b60038190556040518181527f57689995628349ffbf5256b0e5818d96d28e925bcff7b497801995596618f30490602001610485565b5f60208284031215610c19575f80fd5b5035919050565b5f60208284031215610c30575f80fd5b81356001600160a01b0381168114610c46575f80fd5b9392505050565b6020808252600d908201526c2737ba103a34329037bbb732b960991b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610c9b57610c9b610c74565b92915050565b8082028115828204841417610c9b57610c9b610c74565b5f82610cd257634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215610ce7575f80fd5b81518015158114610c46575f80fdfea264697066735822122086a4e9792440c8482175a4a2bc3aebf53c1d104793191c570e923d6ac9c73b8c64736f6c63430008140033

Verified Source Code Partial Match

Compiler: v0.8.20+commit.a1b79de6 EVM: shanghai Optimization: Yes (200 runs)
PrivateSale.sol 163 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

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

interface ISale {
    function getPurchase(address user) external view returns (uint256);
    function getAllocatedTokens(address user) external view returns (uint256);
    function getTotalPurchasedAmount() external view returns (uint256);
    function getTotalTokensAllocated() external view returns (uint256);
}

contract PrivateSale is ISale {
    address public owner;
    IERC20 public immutable usdc;
    address public immutable treasury;

    uint256 public minPurchase;
    uint256 public maxPurchase;
    uint256 public start;
    uint256 public end;
    uint256 public hardCap;
    uint256 public pricePerToken;
    uint256 public bonusPercentage;

    uint256 public totalPurchasedAmount;
    uint256 public totalTokensAllocated;

    mapping(address => uint256) public purchases;
    mapping(address => uint256) public tokensAllocated;

    event Purchased(address indexed buyer, uint256 usdcAmount, uint256 tokensReceived);
    event StartUpdated(uint256 newStart);
    event EndUpdated(uint256 newEnd);
    event MinPurchaseUpdated(uint256 newMin);
    event MaxPurchaseUpdated(uint256 newMax);
    event HardCapUpdated(uint256 newHardCap);
    event PriceUpdated(uint256 newPrice);
    event BonusUpdated(uint256 newBonus);

    constructor(
        address _usdc,
        address _treasury,
        uint256 _minPurchase,
        uint256 _maxPurchase,
        uint256 _start,
        uint256 _end,
        uint256 _hardCap,
        uint256 _pricePerToken,
        uint256 _bonusPercentage
    ) {
        require(_usdc != address(0), "Invalid USDC address");
        require(_treasury != address(0), "Invalid treasury address");
        require(_minPurchase > 0, "Min must be > 0");
        require(_maxPurchase >= _minPurchase, "Max must >= Min");
        require(_end > _start, "End must be after start");
        require(_hardCap > 0, "HardCap must be > 0");
        require(_pricePerToken > 0, "Price must be > 0");
        require(_bonusPercentage <= 100, "Bonus cannot exceed 100%");

        owner = msg.sender;
        usdc = IERC20(_usdc);
        treasury = _treasury;

        minPurchase = _minPurchase;
        maxPurchase = _maxPurchase;
        start = _start;
        end = _end;
        hardCap = _hardCap;
        pricePerToken = _pricePerToken;
        bonusPercentage = _bonusPercentage;
    }

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

    function buy(uint256 amount) external {
        require(isActive(), "Sale not active");
        require(amount >= minPurchase, "Below min purchase");
        require(purchases[msg.sender] + amount <= maxPurchase, "Above max purchase");
        require(totalPurchasedAmount + amount <= hardCap, "HardCap reached");

        uint256 baseTokens = (amount * 1e6) / pricePerToken;
        uint256 bonusTokens = (baseTokens * bonusPercentage) / 100;
        uint256 totalTokens = baseTokens + bonusTokens;

       require(usdc.transferFrom(msg.sender, treasury, amount), "USDC transfer failed");

        purchases[msg.sender] += amount;
        tokensAllocated[msg.sender] += totalTokens;
        totalPurchasedAmount += amount;
        totalTokensAllocated += totalTokens;

        emit Purchased(msg.sender, amount, totalTokens);
    }

    function getPurchase(address user) external view returns (uint256) {
        return purchases[user];
    }

    function getAllocatedTokens(address user) external view returns (uint256) {
        return tokensAllocated[user];
    }

    function getTotalPurchasedAmount() external view returns (uint256) {
        return totalPurchasedAmount;
    }

    function getTotalTokensAllocated() external view returns (uint256) {
        return totalTokensAllocated;
    }

    function isActive() public view returns (bool) {
        return block.timestamp >= start && block.timestamp <= end;
    }

    function setStart(uint256 newStart) external onlyOwner {
        require(newStart < end, "Start must be before end");
        start = newStart;
        emit StartUpdated(newStart);
    }

    function setEnd(uint256 newEnd) external onlyOwner {
        require(newEnd > start, "End must be after start");
        end = newEnd;
        emit EndUpdated(newEnd);
    }

    function setMinPurchase(uint256 newMin) external onlyOwner {
        require(newMin > 0, "Min must be > 0");
        require(newMin <= maxPurchase, "Min must <= Max");
        minPurchase = newMin;
        emit MinPurchaseUpdated(newMin);
    }

    function setMaxPurchase(uint256 newMax) external onlyOwner {
        require(newMax >= minPurchase, "Max must >= Min");
        maxPurchase = newMax;
        emit MaxPurchaseUpdated(newMax);
    }

    function setHardCap(uint256 newHardCap) external onlyOwner {
        require(newHardCap >= totalPurchasedAmount, "HardCap too low");
        hardCap = newHardCap;
        emit HardCapUpdated(newHardCap);
    }

    function setPrice(uint256 newPrice) external onlyOwner {
        require(newPrice > 0, "Price must be > 0");
        pricePerToken = newPrice;
        emit PriceUpdated(newPrice);
    }

    function setBonus(uint256 newBonus) external onlyOwner {
        require(newBonus <= 100, "Bonus cannot exceed 100%");
        bonusPercentage = newBonus;
        emit BonusUpdated(newBonus);
    }
}

Read Contract

bonusPercentage 0x813d6c9a → uint256
end 0xefbe1c1c → uint256
getAllocatedTokens 0x0da39942 → uint256
getPurchase 0xa275999c → uint256
getTotalPurchasedAmount 0xff6e6792 → uint256
getTotalTokensAllocated 0x8b2ec761 → uint256
hardCap 0xfb86a404 → uint256
isActive 0x22f3e2d4 → bool
maxPurchase 0x977b055b → uint256
minPurchase 0x33b5b62e → uint256
owner 0x8da5cb5b → address
pricePerToken 0x7b1b1de6 → uint256
purchases 0x842a77d3 → uint256
start 0xbe9a6555 → uint256
tokensAllocated 0xae1133de → uint256
totalPurchasedAmount 0xbedac100 → uint256
totalTokensAllocated 0xc07f773a → uint256
treasury 0x61d027b3 → address
usdc 0x3e413bee → address

Write Contract 8 functions

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

buy 0xd96a094a
uint256 amount
setBonus 0x0b98f975
uint256 newBonus
setEnd 0x7f498ffc
uint256 newEnd
setHardCap 0xd18d944b
uint256 newHardCap
setMaxPurchase 0x71189742
uint256 newMax
setMinPurchase 0xe8307d00
uint256 newMin
setPrice 0x91b7f5ed
uint256 newPrice
setStart 0xf6a03ebf
uint256 newStart

Recent Transactions

No transactions found for this address