contract ERC20Mine is BaseMine {
    using SafeERC20 for IERC20;
    using SafeMath for uint256;

    // ============ Storage ============

    bool public whitelistActive = true;

    mapping(address=>bool) public whitelist;

    address public _TOKEN_;

    function init(address owner, address token) external {
        super.initOwner(owner);
        _TOKEN_ = token;
    }

    // ============ Event  ============

    event Deposit(address indexed user, uint256 amount);
    event Withdraw(address indexed user, uint256 amount);

    // ============ Deposit && Withdraw && Exit ============

    function addToWhitelist(address[] calldata users) external onlyOwner {
        for (uint i = 0; i < users.length; i++) {
            whitelist[users[i]] = true;
        }
    }

    function removeFromWhitelist(address[] calldata users) external onlyOwner {
        for (uint i = 0; i < users.length; i++) {
            whitelist[users[i]] = false;
        }
    }

    function toggleWhitelistActive() external onlyOwner {
        whitelistActive = !whitelistActive;
    }

    function deposit(uint256 amount) external {
        require(amount > 0, "DODOMineV2: CANNOT_DEPOSIT_ZERO");
        require(!whitelistActive || whitelist[msg.sender], "Not in whitelist");

        _updateAllReward(msg.sender);

        uint256 erc20OriginBalance = IERC20(_TOKEN_).balanceOf(address(this));
        IERC20(_TOKEN_).safeTransferFrom(msg.sender, address(this), amount);
        uint256 actualStakeAmount = IERC20(_TOKEN_).balanceOf(address(this)).sub(erc20OriginBalance);
        
        _totalSupply = _totalSupply.add(actualStakeAmount);
        _balances[msg.sender] = _balances[msg.sender].add(actualStakeAmount);

        emit Deposit(msg.sender, actualStakeAmount);
    }

    function withdraw(uint256 amount) external {
        require(amount > 0, "DODOMineV2: CANNOT_WITHDRAW_ZERO");

        _updateAllReward(msg.sender);
        _totalSupply = _totalSupply.sub(amount);
        _balances[msg.sender] = _balances[msg.sender].sub(amount);
        IERC20(_TOKEN_).safeTransfer(msg.sender, amount);

        emit Withdraw(msg.sender, amount);
    }
}
function addToWhitelist(address[] calldata users) external onlyOwner {
    for (uint i = 0; i < users.length; i++) {
        whitelist[users[i]] = true;
    }
}

// ============ Deposit && Withdraw && Exit ============