UbuntuPresale

Description:

ERC20 token contract with Factory capabilities. Standard implementation for fungible tokens on Ethereum.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/Context.sol": {
      "content": "// SPDX-License-Identifier: MIT\r
\r
pragma solidity ^0.8.19;\r
\r
/**\r
 * @dev Provides information about the current execution context.\r
 */\r
abstract contract Context {\r
    function _msgSender() internal view virtual returns (address) {\r
        return msg.sender;\r
    }\r
\r
    function _msgData() internal view virtual returns (bytes calldata) {\r
        return msg.data;\r
    }\r
}"
    },
    "contracts/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT\r
\r
pragma solidity ^0.8.19;\r
\r
/**\r
 * @dev Interface of the ERC20 standard as defined in the EIP.\r
 */\r
interface IERC20 {\r
    function totalSupply() external view returns (uint256);\r
    function balanceOf(address account) external view returns (uint256);\r
    function transfer(address recipient, uint256 amount) external returns (bool);\r
    function allowance(address owner, address spender) external view returns (uint256);\r
    function approve(address spender, uint256 amount) external returns (bool);\r
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\r
\r
    event Transfer(address indexed from, address indexed to, uint256 value);\r
    event Approval(address indexed owner, address indexed spender, uint256 value);\r
}"
    },
    "contracts/IPriceFeed.sol": {
      "content": "// SPDX-License-Identifier: MIT\r
\r
pragma solidity ^0.8.19;\r
\r
interface IPriceFeed {\r
    function latestAnswer() external view returns (int256 answer);\r
}"
    },
    "contracts/Ownable.sol": {
      "content": "// SPDX-License-Identifier: MIT\r
\r
pragma solidity ^0.8.19;\r
\r
import "./Context.sol";\r
\r
/**\r
 * @dev Contract module which provides a basic access control mechanism, where\r
 * there is an account (an owner) that can be granted exclusive access to\r
 * specific functions.\r
 *\r
 * By default, the owner account will be the one that deploys the contract. This\r
 * can later be changed with {transferOwnership}.\r
 *\r
 * This module is used through inheritance. It will make available the modifier\r
 * `onlyOwner`, which can be applied to your functions to restrict their use to\r
 * the owner.\r
 */\r
abstract contract Ownable is Context {\r
    address private _owner;\r
\r
    event OwnershipTransferred(\r
        address indexed previousOwner,\r
        address indexed newOwner\r
    );\r
\r
    /**\r
     * @dev Initializes the contract setting the deployer as the initial owner.\r
     */\r
    constructor() {\r
        _transferOwnership(_msgSender());\r
    }\r
\r
    /**\r
     * @dev Throws if called by any account other than the owner.\r
     */\r
    modifier onlyOwner() {\r
        _checkOwner();\r
        _;\r
    }\r
\r
    /**\r
     * @dev Returns the address of the current owner.\r
     */\r
    function owner() public view virtual returns (address) {\r
        return _owner;\r
    }\r
\r
    /**\r
     * @dev Throws if the sender is not the owner.\r
     */\r
    function _checkOwner() internal view virtual {\r
        require(owner() == _msgSender(), "Ownable: caller is not the owner");\r
    }\r
\r
    /**\r
     * @dev Leaves the contract without owner. It will not be possible to call\r
     * `onlyOwner` functions. Can only be called by the current owner.\r
     *\r
     * NOTE: Renouncing ownership will leave the contract without an owner,\r
     * thereby disabling any functionality that is only available to the owner.\r
     */\r
    function renounceOwnership() public virtual onlyOwner {\r
        _transferOwnership(address(0));\r
    }\r
\r
    /**\r
     * @dev Transfers ownership of the contract to a new account (`newOwner`).\r
     * Can only be called by the current owner.\r
     */\r
    function transferOwnership(address newOwner) public virtual onlyOwner {\r
        require(\r
            newOwner != address(0),\r
            "Ownable: new owner is the zero address"\r
        );\r
        _transferOwnership(newOwner);\r
    }\r
\r
    /**\r
     * @dev Transfers ownership of the contract to a new account (`newOwner`).\r
     * Internal function without access restriction.\r
     */\r
    function _transferOwnership(address newOwner) internal virtual {\r
        address oldOwner = _owner;\r
        _owner = newOwner;\r
        emit OwnershipTransferred(oldOwner, newOwner);\r
    }\r
}"
    },
    "contracts/UbuntuPresale.sol": {
      "content": "// SPDX-License-Identifier: MIT\r
\r
pragma solidity ^0.8.19;\r
\r
import "./Ownable.sol";\r
import "./IERC20.sol";\r
import "./IPriceFeed.sol";\r
\r
contract UbuntuPresale is Ownable {\r
    address public token; // presale token\r
    uint256 public tokenDenom; // token denom\r
    \r
    address public usdt; // payment token\r
    uint256 public usdtDenom = 1_000_000 ; // token price denom\r
    uint256 public priceInUSDT = 90; // token price : 0.00009 USDT\r
\r
    address public priceFeed; // ETH/USD price feed\r
    uint256 public feedDenom = 100_000_000; // ETH/USD price feed denom\r
    \r
    uint256 public startTime = 1761760800; // presale start time\r
    uint256 public endTime = 1764439200; // presale end time\r
    \r
    uint256 public totalSAmount; // total sold token amount\r
    uint256 public totalCAmount; // total claimed token amount\r
    uint256 public totalETHAmount; // total deposited ETH amount\r
    uint256 public totalUSDTAmount; // total deposited USDT amount\r
\r
    uint256 public maxPurchasePerWallet; // max purchase limit per wallet\r
\r
    mapping(address => uint256) public sAmount; // user => sold amount\r
    mapping(address => uint256) public cAmount; // user => claimed amount\r
    mapping(address => uint256) public dETH; // user => deposited ETH amount\r
    mapping(address => uint256) public dUSDT; // user => deposited USDT amount\r
\r
    event Purchase(address indexed buyer, uint256 amount);\r
    event Claim(address indexed buyer, uint256 amount);\r
    event MaxPurchasePerWalletUpdated(uint256 oldLimit, uint256 newLimit);\r
\r
    constructor(address _token) Ownable() {\r
        token = _token;\r
        tokenDenom = 1_000_000; // 6 decimals\r
        maxPurchasePerWallet = 1_000_000_000 * 10 ** 6; // 1% of 10 billion\r
\r
        if (block.chainid == 1) {\r
            usdt = 0xdAC17F958D2ee523a2206206994597C13D831ec7; // payment token\r
            priceFeed = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; // ETH/USD price feed\r
        } else if (block.chainid == 11155111) {\r
            usdt = 0xeEF8e0E7838B44C6Ec4258B7988Bb17551325048; // payment token\r
            priceFeed = 0x694AA1769357215DE4FAC081bf1f309aDC325306; // ETH/USD price feed\r
        }\r
    }\r
\r
    receive() external payable {}\r
\r
    function buyWithETH() external payable {\r
        require(block.timestamp >= startTime, "Presale is not started yet");\r
        require(block.timestamp <= endTime, "Presale is ended");\r
\r
        require(msg.value > 0, "Insufficient ETH amount");\r
\r
        uint256 ethPrice = uint256(IPriceFeed(priceFeed).latestAnswer());\r
        uint256 usdtAmount = (msg.value * ethPrice * usdtDenom) / (10 ** 18) / feedDenom;\r
\r
        uint256 tokenAmount = (usdtAmount * tokenDenom) / priceInUSDT;\r
        \r
        // Check purchase limit\r
        require(sAmount[msg.sender] + tokenAmount <= maxPurchasePerWallet, "Exceeds max purchase limit per wallet");\r
\r
        totalSAmount += tokenAmount;\r
        totalETHAmount += msg.value;\r
\r
        sAmount[msg.sender] += tokenAmount;\r
        dETH[msg.sender] += msg.value;\r
\r
        emit Purchase(msg.sender, tokenAmount);\r
    }\r
\r
    function buyWithUSDT(uint256 usdtAmount) external {\r
        require(block.timestamp >= startTime, "Presale is not started yet");\r
        require(block.timestamp <= endTime, "Presale is ended");\r
\r
        require(usdtAmount > 0, "Insufficient USDT amount");\r
        IERC20(usdt).transferFrom(msg.sender, address(this), usdtAmount);\r
\r
        uint256 tokenAmount = (usdtAmount * tokenDenom) / priceInUSDT;\r
        \r
        // Check purchase limit\r
        require(sAmount[msg.sender] + tokenAmount <= maxPurchasePerWallet, "Exceeds max purchase limit per wallet");\r
\r
        totalSAmount += tokenAmount;\r
        totalUSDTAmount += usdtAmount;\r
\r
        sAmount[msg.sender] += tokenAmount;\r
        dUSDT[msg.sender] += usdtAmount;\r
\r
        emit Purchase(msg.sender, tokenAmount);\r
    }\r
\r
    function claimToken(uint256 tokenAmount) external {\r
        require(block.timestamp >= endTime, "Claim is not started yet");\r
\r
        uint256 claimableAmount = sAmount[msg.sender] - cAmount[msg.sender];\r
        require(claimableAmount >= tokenAmount, "Insufficient token to claim");\r
\r
        totalCAmount += tokenAmount;\r
\r
        cAmount[msg.sender] += tokenAmount;\r
\r
        IERC20(token).transfer(msg.sender, tokenAmount);\r
\r
        emit Claim(msg.sender, tokenAmount);\r
    }\r
\r
    function setToken(address _token, uint256 _tokenDenom) public onlyOwner {\r
        token = _token;\r
        tokenDenom = _tokenDenom;\r
    }\r
\r
    function setUSDT(\r
        address _usdt,\r
        uint256 _usdtDenom\r
    ) public onlyOwner {\r
        usdt = _usdt;\r
        usdtDenom = _usdtDenom;\r
    }\r
\r
    function setPrice(uint256 _priceInUSDT) public onlyOwner {\r
        priceInUSDT = _priceInUSDT;\r
    }\r
\r
    function setPriceFeed(\r
        address _priceFeed,\r
        uint256 _feedDenom\r
    ) public onlyOwner {\r
        priceFeed = _priceFeed;\r
        feedDenom = _feedDenom;\r
    }\r
\r
    function setStartTime(uint256 _startTime) public onlyOwner {\r
        startTime = _startTime;\r
    }\r
\r
    function setEndTime(uint256 _endTime) public onlyOwner {\r
        endTime = _endTime;\r
    }\r
    \r
    function setMaxPurchasePerWallet(uint256 _maxPurchase) public onlyOwner {\r
        maxPurchasePerWallet = _maxPurchase;\r
    }\r
\r
    function safeTransferETH(address to, uint256 value) internal {\r
        (bool success, ) = to.call{value: value}(new bytes(0));\r
        require(success, "ETH transfer failed");\r
    }\r
\r
    function withdrawETH(address _to, uint256 _amount) external onlyOwner {\r
        require(block.timestamp > endTime, "Presale is not ended");\r
\r
        safeTransferETH(_to, _amount);\r
    }\r
\r
    function withdrawToken(\r
        address _token,\r
        address _to,\r
        uint256 _amount\r
    ) external onlyOwner {\r
        require(block.timestamp > endTime, "Presale is not ended");\r
\r
        IERC20(_token).transfer(_to, _amount);\r
    }\r
}\r
"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    }
  }
}}

Tags:
ERC20, Token, Factory|addr:0x74e815c130fd71d285ddaf9747dab9952fdf0b5d|verified:true|block:23684182|tx:0xc93c6a19f15c4519bea94c0cb4e97999964c1b8e08cbbdc177e25be3e742cff7|first_check:1761761806

Submitted on: 2025-10-29 19:16:47

Comments

Log in to comment.

No comments yet.