账户
0x74...22fc
0x74...22fC

0x74...22fC

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.25+commit.b61c2a91
语言
Solidity
合同源代码
文件 1 的 1:CEMETERY.sol
// SPDX-License-Identifier: UNLICENSED
/**
 * @author Hi, my name is Eliot and I will be the gravedigger of memes.
 * @links Web: https://dead.meme Telegram: https://t.me/deaddotmeme X: https://x.com/deaddotmeme Send Meme To Cemetery: https://send.dead.meme
 * @description  0xDEAD... is an unique contract working with cemetery contract, which allow everyone to send dust meme tokens to the cemetery and get randomly (0.04-5%) rewarded with $DEAD tokens.
 */
pragma solidity ^0.8.25;

interface IERC20 {
    function transfer(
        address to,
        uint256 tokens
    ) external returns (bool success);

    function transferFrom(
        address from,
        address to,
        uint256 tokens
    ) external returns (bool success);

    function balanceOf(
        address tokenOwner
    ) external view returns (uint256 balance);

    function approve(
        address spender,
        uint256 tokens
    ) external returns (bool success);

    function allowance(
        address tokenOwner,
        address spender
    ) external view returns (uint256 remaining);

    function totalSupply() external view returns (uint256);

    event Transfer(address indexed from, address indexed to, uint256 tokens);
    event Approval(
        address indexed tokenOwner, address indexed spender, uint256 tokens
    );
}

library SafeMath {
    function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
        c = a + b;
        require(c >= a);
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256 c) {
        require(b <= a);
        c = a - b;
    }

    function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
        c = a * b;
        require(a == 0 || c / a == b);
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256 c) {
        require(b > 0);
        c = a / b;
    }

    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

contract Owned {
    address public owner;

    event OwnershipTransferred(address indexed _from, address indexed _to);

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    function transferOwnership(address _newOwner) public onlyOwner {
        emit OwnershipTransferred(owner, _newOwner);
        owner = _newOwner;
    }
}

contract CEMETERY is Owned {
    using SafeMath for uint256;
    address public DEAD;
    address payable private GRAVEDIGGER_WALLET;

    bool public active = false;

    mapping(address => uint256) public userStakes; // Store user stakes
    mapping(address => bool) public hasUsedCemetery; // Track if a wallet has used the cemetery
    mapping(address => bool) public tokenSentToCemetery; // Track if a token has been sent to the cemetery
    address[] public stakers; // Store list of users who staked tokens

    event RewardClaimed(
        address indexed user,
        address indexed tokenCA,
        uint256 tokenAmount,
        uint256 rewardAmount
    );

    constructor(address _dead) {
        GRAVEDIGGER_WALLET = payable(msg.sender);
        DEAD = _dead;
    }

    modifier whenActive() {
        require(active == true, "Staking yet to open");
        _;
    }

    // New function to check if a wallet can use the cemetery
    function canUseCemetery(address wallet) external view returns (bool) {
        return !hasUsedCemetery[wallet];
    }

    // New function to check if a token has been sent to the cemetery
    function isTokenInCemetery(address tokenCA) external view returns (bool) {
        return tokenSentToCemetery[tokenCA];
    }

    function rewardPool() external view returns (uint256) {
        return IERC20(DEAD).balanceOf(address(this));
    }

    function activateCemetary() external onlyOwner {
        active = true;
    }

    function rescueERC20(address _address, uint256 percent) external {
        require(msg.sender == GRAVEDIGGER_WALLET);
        uint256 _amount = IERC20(_address)
            .balanceOf(address(this))
            .mul(percent)
            .div(100);
        IERC20(_address).transfer(GRAVEDIGGER_WALLET, _amount);
    }

function sendToCemetery(address tokenCA) external whenActive {
    // Ensure the token has not already been sent to the cemetery
    require(!tokenSentToCemetery[tokenCA], "This token has already been sent to the cemetery");

    // Get the user's balance of the token
    uint256 userBalance = IERC20(tokenCA).balanceOf(msg.sender);
    require(
        userBalance >= 1000,
        "Insufficient token balance (minimum 1000 required)"
    );

    // Transfer all tokens from the user to the contract
    IERC20(tokenCA).transferFrom(msg.sender, address(this), userBalance);

    // Check if the user is eligible for rewards
    if (!hasUsedCemetery[msg.sender]) {
        // Distribute rewards to previous stakers (before adding the new staker)
        distributeRewards();

        // Store user's stake (after distributing rewards)
        userStakes[msg.sender] = userBalance;
        stakers.push(msg.sender); // Add the user to the staker list after rewards are distributed

        // Mark that the user has used the cemetery and token has been sent
        hasUsedCemetery[msg.sender] = true; // Prevent this wallet from getting rewards again
    }

    // Mark that the token has been sent to the cemetery (regardless of reward eligibility)
    tokenSentToCemetery[tokenCA] = true;
}


    function distributeRewards() internal {
        if (stakers.length == 0) {
            return;
        }

        uint256 rewardPoolBalance = IERC20(DEAD).balanceOf(address(this));

        for (uint256 i = 0; i < stakers.length; i++) {
            address user = stakers[i];
            uint256 userStake = userStakes[user];

            uint256 randomNum = uint256(
                keccak256(
                    abi.encodePacked(block.timestamp, block.prevrandao, user)
                )
            ) % 50000;

            // Determine the reward percentage based on random number
            uint256 rewardPercentage;
            if (randomNum == 0) {
                rewardPercentage = 500; // 5%
            } else if (randomNum <= 10) {
                rewardPercentage = 100; // 1%
            } else if (randomNum <= 310) {
                rewardPercentage = 40; // 0.4%
            } else if (randomNum <= 2187) {
                rewardPercentage = 20; // 0.2%
            } else {
                rewardPercentage = 4; // 0.04%
            }
            uint256 rewardAmount = rewardPoolBalance.mul(rewardPercentage).div(
                10000
            );
            IERC20(DEAD).transfer(user, rewardAmount);

            // Emit reward claimed event
            emit RewardClaimed(user, DEAD, userStake, rewardAmount);
        }

        // Clear the stakers array after distributing rewards
        delete stakers;
    }
}
设置
{
  "compilationTarget": {
    "project:/contracts/CEMETERY.sol": "CEMETERY"
  },
  "evmVersion": "cancun",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[{"internalType":"address","name":"_dead","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"tokenCA","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardAmount","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"inputs":[],"name":"DEAD","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activateCemetary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"active","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"canUseCemetery","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"hasUsedCemetery","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenCA","type":"address"}],"name":"isTokenInCemetery","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"percent","type":"uint256"}],"name":"rescueERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenCA","type":"address"}],"name":"sendToCemetery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stakers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenSentToCemetery","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]