contract VETH is VTokenBase {
    TokenLike public weth;
    bool internal lockEth;

    constructor(address _controller)
        public
        VTokenBase(
            "VETH Pool",
            "VETH",
            "ETH-A",
            0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2,
            _controller
        )
    {
        weth = TokenLike(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
    }

    /**
     * @dev Handle incoming ETH to the contract address.
     */
    receive() external payable {
        if (!lockEth) {
            deposit();
        }
    }

    /**
     * @dev Burns tokens/shares and retuns the ETH value, after fee, of those.
     */
    function withdrawETH(uint256 shares) external whenNotShutdown nonReentrant {
        require(shares != 0, "Withdraw must be greater than 0");
        uint256 sharesAfterFee = _handleFee(shares);
        uint256 amount = sharesAfterFee.mul(totalValue()).div(totalSupply());
        _burn(_msgSender(), sharesAfterFee);

        _withdrawCollateral(amount);

        // Unwrap WETH to ETH
        lockEth = true;
        weth.withdraw(amount);
        lockEth = false;
        _msgSender().transfer(amount);

        emit Withdraw(_msgSender(), shares, amount);
    }

    function sweepErc20(address erc20) external {
        _sweepErc20(erc20);
    }

    /**
     * @dev Receives ETH and grants new tokens/shares to the sender depending
     * on the value of pool's share.
     */
    function deposit() public payable whenNotPaused nonReentrant {
        // Wraps ETH in WETH
        weth.deposit{value: msg.value}();
        uint256 shares = _calculateShares(msg.value);
        _mint(_msgSender(), shares);
    }

    function _afterBurning(uint256 amount) internal override {
        _withdrawCollateral(amount);
        weth.transfer(_msgSender(), amount);
    }

    function _beforeMinting(uint256 amount) internal override {
        weth.transferFrom(_msgSender(), address(this), amount);
    }
}
function withdrawETH(uint256 shares) external whenNotShutdown nonReentrant {
    require(shares != 0, "Withdraw must be greater than 0");
    uint256 sharesAfterFee = _handleFee(shares);
    uint256 amount = sharesAfterFee.mul(totalValue()).div(totalSupply());
    _burn(_msgSender(), sharesAfterFee);

    _withdrawCollateral(amount);

    // Unwrap WETH to ETH
    lockEth = true;
    weth.withdraw(amount);
    lockEth = false;
    _msgSender().transfer(amount);

    emit Withdraw(_msgSender(), shares, amount);
}

/**
 * @dev Burns tokens/shares and retuns the ETH value, after fee, of those.
 */