账户
0x8f...09a7
0x8f...09A7

0x8f...09A7

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.8.20+commit.a1b79de6
语言
Solidity
合同源代码
文件 1 的 1:JUMPBonusPool.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor() {}

    function _msgSender() internal view returns (address) {
        return msg.sender;
    }

    function _msgData() internal view returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(_owner == _msgSender(), 'Ownable: caller is not the owner');
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = 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 onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), 'Ownable: new owner is the zero address');
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

contract JUMPBonusPool is Ownable {
    uint256 public  bonusCircleTime;
    uint256 public  delayTime = 30;

    uint256 public mintLimit;

    mapping(address=>bool) public bonusClaimed;
    uint256 public tickId;
    uint256 public startTime;
    uint256 private endBonusTimestamp;

    uint256 public totalBonus;
    bool public mintLimitFlag = false;

    mapping(address => bool) public callerMap;

    address[5] public bonusUsers;
    uint256 public index;
    address public marketMakerAddr = 0xFE49c3D7b7EF988233FAddeD69f7B624A392E017;


    event AddTick(uint256 tickId,address user,uint256 amountETH);
    event Claim(address sender,uint256 totalBonus);
    event SetCaller(address sender,address addr,bool active);

    modifier onlyCaller() {
        require(isCaller(msg.sender), "Not caller");
        _;
    }

    constructor(uint256 _startTime) {
        startTime = _startTime;
        bonusCircleTime = 96 hours;
        mintLimit = 101287e17;
        endBonusTimestamp = startTime + bonusCircleTime;

    }

    function addTick(address user,uint256 mintTotal) public payable onlyCaller {
        require(block.timestamp >= startTime,'Not start');
        uint256 amountETH = msg.value;
        require(mintTotal <= mintLimit,'Exceed bonusLimit');
        tickId++;
        totalBonus += amountETH;

        //add delay time
        endBonusTimestamp = endBonusTimestamp + delayTime;
        if (endBonusTimestamp - block.timestamp > bonusCircleTime) {
            endBonusTimestamp = block.timestamp + bonusCircleTime;
        }
        if(index == 5){
            index =0;
        }
        bonusUsers[index] = user;
        index++;

        if(mintTotal == mintLimit ){
            startCycleETH();//start Refund ETH
            endBonusTimestamp = block.timestamp;
            mintLimitFlag = true;
        }

        emit AddTick(tickId,user,amountETH);
    }

    function startCycleETH() internal{
        uint256 ethBalance = address(this).balance;
        if(ethBalance > 0){
            (bool success, ) = marketMakerAddr.call{value: ethBalance}("");
            require(success, "Fail to claim bonus");
        }
    }

    function claimETH() public {
        require(block.timestamp > endBonusTimestamp,'Pool Not end');
        require(!bonusClaimed[msg.sender] && !mintLimitFlag,'Bonus claimed');
        bool isWinnerFlag = isWinner(msg.sender);
        require(isWinnerFlag, 'RebirthETHBonusPool: not winner');
        uint256 bonus = getWinnerBonus(msg.sender);
        bonusClaimed[msg.sender] = true;
        (bool success, ) = msg.sender.call{value: bonus}("");
        require(success, "Fail to claim bonus");
        emit Claim(msg.sender,bonus);
    }

    function isWinner(address user) public view returns (bool) {
        if (block.timestamp <= endBonusTimestamp || mintLimitFlag) {
            return false;
        }
        address[] memory winners = getWinners();
        uint winnerNum = winners.length;
        for(uint256 i = 0;i < winnerNum;i++ ){
            if(winners[i] == user){
                return true;
            }
        }
        return false;
    }

    function getWinnerBonus(address user) public view returns(uint256 bonus){
        if (block.timestamp <= endBonusTimestamp) {
            return 0;
        }
        address[] memory winners = getWinners();
        uint256 winnerNum = winners.length;
        uint256 averageBonus = totalBonus / winnerNum;
        for(uint256 i = 0;i < winnerNum;i++ ){
            if(winners[i] == user){
                bonus += averageBonus;
            }
        }
    }

    function getWinners() public view returns (address[] memory winners) {
        if (block.timestamp <= endBonusTimestamp) {
            return winners;
        }

        winners = new address[](5);
        uint256 cnt = 0;
        for(uint256 i = 0;i < 5;i++ ){
            if(bonusUsers[i] != address(0)){
                winners[cnt] = bonusUsers[i];
                cnt++;
            }
        }
        // Downsize the array to fit.
        assembly {
            mstore(winners, cnt)
        }
        return winners;
    }


    function getEndBonusTime() public view returns(uint256){
        return endBonusTimestamp;
    }

    function getCurrBlockAndTime() public view returns(uint256 blockNum,uint256 blockTime){
        blockNum = block.number;
        blockTime = block.timestamp;
    }

    function setCaller(address addr, bool active) public onlyOwner {
        callerMap[addr] = active;
        emit SetCaller(msg.sender,addr,active);
    }
    function isCaller(address addr) public view returns (bool) {
        return callerMap[addr];
    }


    receive() external payable {}

}
设置
{
  "compilationTarget": {
    "contracts/JUMP/JUMPBonusPool.sol": "JUMPBonusPool"
  },
  "evmVersion": "paris",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[{"internalType":"uint256","name":"_startTime","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tickId","type":"uint256"},{"indexed":false,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountETH","type":"uint256"}],"name":"AddTick","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"totalBonus","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"SetCaller","type":"event"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"mintTotal","type":"uint256"}],"name":"addTick","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"bonusCircleTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"bonusClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"bonusUsers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"callerMap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"delayTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrBlockAndTime","outputs":[{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"uint256","name":"blockTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEndBonusTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getWinnerBonus","outputs":[{"internalType":"uint256","name":"bonus","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWinners","outputs":[{"internalType":"address[]","name":"winners","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"index","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isCaller","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"isWinner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketMakerAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mintLimitFlag","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"active","type":"bool"}],"name":"setCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tickId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]