ETH Price: $2,475.92 (-1.79%)

Contract Diff Checker

Contract Name:
LockAndEarn

Contract Source Code:

File 1 of 1 : LockAndEarn

pragma solidity ^0.5.0;

/*
 * @title: SafeMath
 * @dev: Helper contract functions to arithmatic operations safely.
 */
contract SafeMath {
    function Sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;

        return c;
    }

    function Add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    function Mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }
}

/*
 * @title: Token
 * @dev: Interface contract for ERC20 tokens
 */
contract Token {
    function totalSupply() public view returns (uint256 supply);

    function balanceOf(address _owner) public view returns (uint256 balance);

    function transfer(address _to, uint256 _value)
        public
        returns (bool success);

    function transferFrom(
        address _from,
        address _to,
        uint256 _value
    ) public returns (bool success);

    function approve(address _spender, uint256 _value)
        public
        returns (bool success);

    function allowance(address _owner, address _spender)
        public
        view
        returns (uint256 remaining);

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(
        address indexed _owner,
        address indexed _spender,
        uint256 _value
    );
}


contract ERC20Basic {
    uint public _totalSupply;
    function totalSupply() public view returns (uint256);
    function balanceOf(address who) public view returns (uint256);
    function transfer(address to, uint256 value) public;
    event Transfer(address indexed from, address indexed to, uint256 value);
}

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract USDT is ERC20Basic {
    function allowance(address owner, address spender) public view returns (uint256);
    function transferFrom(address from, address to, uint256 value) public;
    function approve(address spender, uint256 value) public;
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

/*
 * @title: Lock and Earn
 */
contract LockAndEarn is SafeMath {
    // _kaiAddress: KAI ERC20 contract address
    // msg.sender: owner && operator
    constructor(uint256 _lockStartTime, uint256 _lockDays) public {
        owner = msg.sender;
        lockDays = _lockDays;
        lockStartTime = _lockStartTime;
        isEnded = false;
    }

    address public owner;
    uint256 public hardCap = 2000000000000000000000000; // 2000000 KAI
    uint256 public totalBonusUSDT;
    uint256 public minDeposit = 1000000000000000000000; // 1000 KAI
    uint256 public maxDeposit = 250000000000000000000000; // 250000 KAI
    address public kaiAddress = 0xD9Ec3ff1f8be459Bb9369b4E79e9Ebcf7141C093;
    address constant public usdtAddress = 0xdAC17F958D2ee523a2206206994597C13D831ec7;
    uint256 public lockDays;
    uint256 public lockStartTime;
    uint8 public winPool;
    bool public isEnded;

    mapping(address => mapping(uint256 => uint256)) public balance;
    mapping(uint256 => uint256) public currentCapPool;
    mapping(address => bool) public isWithdrawBonus;
    mapping(address => mapping(uint256 => bool)) isWithdrawKAI;

    // Functions with this modifier can only be executed by the owner
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    // Deposit ERC20's for saving
    function depositKAI(uint256 amount, uint256 poolIndex) public {
        require(isEnded != true);
        require(lockStartTime < now, 'Event has not been started yet');
        require(balance[msg.sender][poolIndex] == 0, "Can only deposit once");
        require (amount >= minDeposit, 'Amount must be equal or greater than 1000 KAI');
        require (amount <= maxDeposit, 'Amount must be equal or less than 250000 KAI');
        require(Add(currentCapPool[poolIndex], amount) <= hardCap, 'Exceed limit total cap');

        require(Token(kaiAddress).transferFrom(msg.sender, address(this), amount));

        balance[msg.sender][poolIndex] = amount;
        uint256 currentCap = currentCapPool[poolIndex];
        currentCapPool[poolIndex] = Add(currentCap, amount);
    }

    // Withdraw ERC20's to personal address
    function withdrawKAI(uint256 poolIndex) public {
        require(lockStartTime + lockDays * 1 days < now, "In locking period");
        require(isWithdrawKAI[msg.sender][poolIndex] != true, "Can only withdraw once");
        uint256 amount = balance[msg.sender][poolIndex];
        require(Token(kaiAddress).transfer(msg.sender, amount));
        isWithdrawKAI[msg.sender][poolIndex] = true;
    }
    
    function withdrawBonus() public {
        require(lockStartTime + lockDays * 1 days < now, "In locking period");
        require(balance[msg.sender][winPool] > 0, "Address has not deposited");
        require(isWithdrawBonus[msg.sender] != true, "Can only withdraw once");
        
        _withdrawBonus(msg.sender, winPool);
    }
    
    function _withdrawBonus(address addr, uint256 poolIndex) private {
        uint256 amount = balance[addr][poolIndex];
        uint256 currentCap = currentCapPool[winPool];

        uint256 bonus = Mul(amount, totalBonusUSDT) / currentCap;
        USDT(usdtAddress).transfer(msg.sender, bonus);
        isWithdrawBonus[msg.sender] = true;
    }
   
    function setWinningPoolAndBonus(uint256 _totalBonusUSDT, uint8 poolIndex) public onlyOwner {
        require(USDT(usdtAddress).balanceOf(address(this)) >= _totalBonusUSDT);

        totalBonusUSDT = _totalBonusUSDT;
        winPool = poolIndex;
    }
   
    // owner sets global variables the campaign ends
    function setEndedDeposit() public onlyOwner {
        isEnded = true;
    }
    
    // Below two emergency functions will be never used in normal situations.
    // These function is only prepared for emergency case such as smart contract hacking Vulnerability or smart contract abolishment
    // Withdrawn fund by these function cannot belong to any operators or owners.
    // Withdrawn fund should be distributed to individual accounts having original ownership of withdrawn fund.

    function emergencyWithdrawalETH(uint256 amount) public onlyOwner {
        require(msg.sender.send(amount));
    }
    
    function emergencyWithdrawalKAI(uint256 amount) public onlyOwner {
        Token(kaiAddress).transfer(msg.sender, amount);
    }
    
    function emergencyWithdrawalUSDT(uint256 amount) public onlyOwner {
        USDT(usdtAddress).transfer(msg.sender, amount);
    }
    
    function getMyBalance(uint256 poolIndex) public view returns (uint256) {
        return balance[msg.sender][poolIndex];
    }

    function getTimeStamp() public view returns (uint256) {
        return now;
    }
    
    // @notice Will receive any eth sent to the contract
    function () external payable {}
}

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

Context size (optional):