S Price: $0.797671 (-3.99%)

Contract Diff Checker

Contract Name:
HEDGEPOT

Contract Source Code:

File 1 of 1 : HEDGEPOT

// File: @openzeppelin/contracts/utils/Context.sol


// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

// File: holder-storage.sol


pragma solidity ^0.8.26;


contract HolderStorage is Ownable {
    address public tokenContract;
    address public devWallet;

    mapping(address => uint256) public balances;
    mapping(address => uint256) private holderIndexes;
    address[] public holders;
    mapping(address => bool) public isHolder;

    uint8 private constant decimals = 18;
    uint256 public minimumBalance = 50000 * 10**decimals;

    struct Payout {
        address recipient;
        uint256 amount;
        string potType;
        uint256 timestamp;
    }

    mapping(address => Payout[]) public holderPayoutHistory;

    uint256 public totalHourlyPayouts;
    uint256 public totalMegaPayouts;
    uint256 public totalHourlyAmountPaid;
    uint256 public totalMegaAmountPaid;

    Payout[] public payoutHistory;

    mapping(address => bool) public excludedFromPot;

    modifier onlyTokenContract() {
        require(msg.sender == tokenContract, "HolderStorage: Not authorized");
        _;
    }

    constructor(address initialOwner) Ownable(initialOwner) {}

    function setTokenContract(address _tokenContract) external onlyOwner {
        require(
            tokenContract == address(0),
            "HolderStorage: Token contract already set"
        );
        tokenContract = _tokenContract;
    }

    function setDevWallet(address _devWallet) external onlyOwner {
        require(
            _devWallet != address(0),
            "HolderStorage: Dev wallet is zero address"
        );
        devWallet = _devWallet;
    }

    function excludeFromPot(address account) external onlyOwner {
        require(
            account != devWallet,
            "HolderStorage: Cannot exclude dev wallet"
        );
        excludedFromPot[account] = true;
    }

    function includeInPot(address account) external onlyOwner {
        excludedFromPot[account] = false;
    }

    function setMinimumBalance(uint256 newMinimumBalance) external onlyOwner {
        minimumBalance = newMinimumBalance;
    }

    function updateHolder(address holder, uint256 newBalance)
        external
        onlyTokenContract
    {
        if (newBalance < minimumBalance) {
            removeHolder(holder);
        } else {
            if (!isHolder[holder]) {
                holders.push(holder);
                holderIndexes[holder] = holders.length - 1;
                isHolder[holder] = true;
            }
            balances[holder] = newBalance;
        }
    }

    function removeHolder(address holder) internal {
        if (isHolder[holder]) {
            uint256 index = holderIndexes[holder];
            uint256 lastIndex = holders.length - 1;
            if (index != lastIndex) {
                address lastHolder = holders[lastIndex];
                holders[index] = lastHolder;
                holderIndexes[lastHolder] = index;
            }
            holders.pop();
            isHolder[holder] = false;
            balances[holder] = 0;
        }
    }

    function getHolderCount() external view returns (uint256) {
        return holders.length;
    }

    function getHolderByIndex(uint256 index) external view returns (address) {
        require(index < holders.length, "HolderStorage: Index out of bounds");
        return holders[index];
    }

    function recordPayout(
        address recipient,
        uint256 amount,
        string memory potType
    ) external onlyTokenContract {
        payoutHistory.push(Payout(recipient, amount, potType, block.timestamp));

        if (keccak256(bytes(potType)) == keccak256(bytes("Hourly Jackpot"))) {
            totalHourlyPayouts++;
            totalHourlyAmountPaid += amount;
        } else if (
            keccak256(bytes(potType)) == keccak256(bytes("Mega Jackpot"))
        ) {
            totalMegaPayouts++;
            totalMegaAmountPaid += amount;
        }

        holderPayoutHistory[recipient].push(
            Payout(recipient, amount, potType, block.timestamp)
        );

        if (recipient != devWallet) {
            removeHolder(recipient);
        }
    }

    function getPayoutHistoryByHolder(address holder)
        external
        view
        returns (Payout[] memory)
    {
        return holderPayoutHistory[holder];
    }

    function getPayoutHistory(uint256 index)
        external
        view
        returns (
            address recipient,
            uint256 amount,
            string memory potType,
            uint256 timestamp
        )
    {
        require(
            index < payoutHistory.length,
            "HolderStorage: Index out of bounds"
        );
        Payout memory payout = payoutHistory[index];
        return (
            payout.recipient,
            payout.amount,
            payout.potType,
            payout.timestamp
        );
    }

    function getAggregateStats()
        external
        view
        returns (
            uint256 totalHourlyPayouts_,
            uint256 totalMegaPayouts_,
            uint256 totalHourlyAmountPaid_,
            uint256 totalMegaAmountPaid_
        )
    {
        return (
            totalHourlyPayouts,
            totalMegaPayouts,
            totalHourlyAmountPaid,
            totalMegaAmountPaid
        );
    }

    function isEligibleForJackpot(address account)
        external
        view
        returns (bool)
    {
        return !excludedFromPot[account];
    }
}

// File: hpot.sol


pragma solidity ^0.8.26;




interface IUniswapV2Router02 {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );
}

interface IUniswapV2Factory {
    function createPair(address tokenA, address tokenB)
        external
        returns (address pair);
}

interface IUniswapV2Pair {
    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function token0() external view returns (address);
}

contract HEDGEPOT is IERC20, Ownable {
    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;
    mapping(address => bool) private _isExcludedFromFee;
    address payable private _devWallet;
    HolderStorage public holderStorage;

    uint8 private constant _decimals = 18;
    uint256 private constant _tTotal = 1_000_000_000 * 10**_decimals;
    string private constant _name = unicode"HedgePot";
    string private constant _symbol = unicode"HPOT";
    uint256 public _maxTxAmount = 21500000000000 * 10**_decimals;
    uint256 public _maxWalletSize = 8413800000000 * 10**_decimals;

    uint256 public hourlyJackpotPool;
    uint256 public megaJackpotPool;
    uint256 public lastHourlyDraw;
    uint256 public lastMegaDraw;
    uint256 public hourlyInterval = 1 hours;
    uint256 public megaInterval = 24 hours;

    IUniswapV2Router02 private uniswapV2Router;
    address private uniswapV2Pair;
    bool private tradingOpen;
    event MaxTxAmountUpdated(uint256 _maxTxAmount);

    event HourlyJackpotWon(address indexed winner, uint256 amount);
    event MegaJackpotWon(address indexed winner, uint256 amount);

    constructor(address _holderStorage) Ownable(_msgSender()) {
        _devWallet = payable(0xFe0a51777d8CB514754b3b19f6dB5389298Fc5F5);
        _balances[_msgSender()] = _tTotal;
        _isExcludedFromFee[owner()] = true;
        _isExcludedFromFee[_msgSender()] = true;
        _isExcludedFromFee[address(this)] = true;
        _isExcludedFromFee[_devWallet] = true;

        holderStorage = HolderStorage(_holderStorage);

        lastHourlyDraw = block.timestamp;
        lastMegaDraw = block.timestamp;

        emit Transfer(address(0), _msgSender(), _tTotal);
    }

    function name() public pure returns (string memory) {
        return _name;
    }

    function symbol() public pure returns (string memory) {
        return _symbol;
    }

    function decimals() public pure returns (uint8) {
        return _decimals;
    }

    function totalSupply() public pure override returns (uint256) {
        return _tTotal;
    }

    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    function excludeFromFee(address account) external onlyOwner {
        _isExcludedFromFee[account] = true;
    }

    function isExcludedFromFee(address account) public view returns (bool) {
        return _isExcludedFromFee[account];
    }

    function transfer(address recipient, uint256 amount)
        public
        override
        returns (bool)
    {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender)
        public
        view
        override
        returns (uint256)
    {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount)
        public
        override
        returns (bool)
    {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(
            sender,
            _msgSender(),
            _allowances[sender][_msgSender()] - amount
        );
        return true;
    }

    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) private {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    function donateToMegaPotOrBurn(address sniper, bool donateToMega)
        external
        onlyOwner
    {
        uint256 balance = balanceOf(sniper);
        require(balance > 0, "Early sniper has no tokens to donate");

        if (donateToMega) {
            _transfer(sniper, address(this), balance);
            megaJackpotPool += balance;
            emit Transfer(sniper, address(this), balance);
        } else {
            _transfer(
                sniper,
                address(0x000000000000000000000000000000000000dEaD),
                balance
            );
        }
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) private {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(amount > 0, "Transfer amount must be greater than zero");

        uint256 feeAmount = 0;

        if (
            from == uniswapV2Pair &&
            to != address(uniswapV2Router) &&
            !_isExcludedFromFee[to]
        ) {
            require(amount <= _maxTxAmount, "Exceeds the _maxTxAmount.");
            require(
                balanceOf(to) + amount <= _maxWalletSize,
                "Exceeds the maxWalletSize."
            );
        }

        if (!_isExcludedFromFee[from]) {
            feeAmount = (amount * 3) / 100;
            uint256 hourlyPotFee = feeAmount / 3;
            uint256 megaPotFee = feeAmount / 3;
            uint256 devFee = feeAmount / 3;

            hourlyJackpotPool += hourlyPotFee;
            megaJackpotPool += megaPotFee;

            _balances[_devWallet] += devFee;
            _balances[address(this)] += hourlyPotFee + megaPotFee;

            emit Transfer(from, _devWallet, devFee);
            emit Transfer(from, address(this), hourlyPotFee + megaPotFee);
        }

        _balances[from] -= amount;
        _balances[to] += (amount - feeAmount);

        emit Transfer(from, to, amount - feeAmount);

        holderStorage.updateHolder(from, _balances[from]);
        holderStorage.updateHolder(to, _balances[to]);

        bool hourlyDue = block.timestamp >= lastHourlyDraw + hourlyInterval;
        bool megaDue = block.timestamp >= lastMegaDraw + megaInterval;

        if (hourlyDue) {
            distributeHourlyJackpot();
        }
        if (megaDue) {
            distributeMegaJackpot();
        }
    }

    function getTimeUntilHourlyPayout() public view returns (uint256) {
        if (block.timestamp >= lastHourlyDraw + hourlyInterval) {
            return 0;
        } else {
            return (lastHourlyDraw + hourlyInterval) - block.timestamp;
        }
    }

    function getTimeUntilMegaPayout() public view returns (uint256) {
        if (block.timestamp >= lastMegaDraw + megaInterval) {
            return 0;
        } else {
            return (lastMegaDraw + megaInterval) - block.timestamp;
        }
    }

    function getCurrentHourlyPot() public view returns (uint256) {
        return hourlyJackpotPool;
    }

    function getCurrentMegaPot() public view returns (uint256) {
        return megaJackpotPool;
    }

    function distributeHourlyJackpot() internal {
        lastHourlyDraw = block.timestamp;

        uint256 holderCount = holderStorage.getHolderCount();
        if (holderCount == 0 || hourlyJackpotPool == 0) {
            return;
        }

        address winner;
        uint256 randomIndex;

        do {
            randomIndex =
                uint256(
                    keccak256(
                        abi.encodePacked(block.timestamp, block.prevrandao)
                    )
                ) %
                holderCount;
            winner = holderStorage.getHolderByIndex(randomIndex);
        } while (!holderStorage.isEligibleForJackpot(winner));

        uint256 reward = hourlyJackpotPool;
        hourlyJackpotPool = 0;

        _transfer(address(this), winner, reward);
        holderStorage.recordPayout(winner, reward, "Hourly Jackpot");

        emit HourlyJackpotWon(winner, reward);
    }

    function distributeMegaJackpot() internal {
        lastMegaDraw = block.timestamp;

        uint256 holderCount = holderStorage.getHolderCount();
        if (holderCount == 0 || megaJackpotPool == 0) {
            return;
        }

        address winner;
        uint256 randomIndex;

        do {
            randomIndex =
                uint256(
                    keccak256(
                        abi.encodePacked(block.timestamp, block.prevrandao)
                    )
                ) %
                holderCount;
            winner = holderStorage.getHolderByIndex(randomIndex);
        } while (!holderStorage.isEligibleForJackpot(winner));

        uint256 reward = megaJackpotPool;
        megaJackpotPool = 0;

        _transfer(address(this), winner, reward);
        holderStorage.recordPayout(winner, reward, "Mega Jackpot");

        emit MegaJackpotWon(winner, reward);
    }

    function distributeHourlyPot() external {
        if (block.timestamp >= lastHourlyDraw + hourlyInterval) {
            distributeHourlyJackpot();
        }
    }

    function distributeMegaPot() external {
        if (block.timestamp >= lastMegaDraw + megaInterval) {
            distributeMegaJackpot();
        }
    }

    function donateToHourlyPot(uint256 amount) external {
        require(amount > 0, "Amount must be greater than zero");
        require(_balances[_msgSender()] >= amount, "Insufficient balance");

        _balances[_msgSender()] -= amount;
        _balances[address(this)] += amount;

        hourlyJackpotPool += amount;

        emit Transfer(_msgSender(), address(this), amount);
    }

    function donateToMegaPot(uint256 amount) external {
        require(amount > 0, "Amount must be greater than zero");
        require(_balances[_msgSender()] >= amount, "Insufficient balance");

        _balances[_msgSender()] -= amount;
        _balances[address(this)] += amount;

        megaJackpotPool += amount;

        emit Transfer(_msgSender(), address(this), amount);
    }

    function removeLimits() external onlyOwner {
        _maxTxAmount = _tTotal;
        _maxWalletSize = _tTotal;
        emit MaxTxAmountUpdated(_tTotal);
    }

    function getTokenPrice() public view returns (uint256) {
        IUniswapV2Pair pair = IUniswapV2Pair(uniswapV2Pair);
        (uint112 reserve0, uint112 reserve1, ) = pair.getReserves();

        address token0 = pair.token0();

        uint256 tokenReserve;
        uint256 wethReserve;

        if (token0 == address(this)) {
            tokenReserve = reserve0;
            wethReserve = reserve1;
        } else {
            tokenReserve = reserve1;
            wethReserve = reserve0;
        }

        if (tokenReserve == 0) {
            return 0;
        } else {
            return (wethReserve * 1e18) / tokenReserve;
        }
    }

    function openTrading() external onlyOwner {
        require(!tradingOpen, "Trading is already open");
        uniswapV2Router = IUniswapV2Router02(
            0x591cf6942c422fA53E8D81c62a9692D7BeA72F61
        );
        _approve(address(this), address(uniswapV2Router), _tTotal);
        uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()).createPair(
            address(this),
            uniswapV2Router.WETH()
        );
        uniswapV2Router.addLiquidityETH{value: address(this).balance}(
            address(this),
            balanceOf(address(this)),
            0,
            0,
            owner(),
            block.timestamp
        );
        IERC20(uniswapV2Pair).approve(
            address(uniswapV2Router),
            type(uint256).max
        );
        tradingOpen = true;
    }

    receive() external payable {}

    function rescueStuckSonic() public {
        uint256 contractETHBalance = address(this).balance;
        require(contractETHBalance > 0, "No Sonic to rescue");

        _devWallet.transfer(contractETHBalance);
    }
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):