HIGH severity: Pickle Finance — Insufficient validation. It doesn't check the validity of the Jars. Attacker can create fake token to withdraw all DAIs from StrategyCmpdDaiV2 to Jar.. it doesn't check the validity of the Jars. Attacker can create fake token to withdraw all DAIs from StrategyCmpdDaiV2 to Jar.

Vulnerable code:
function swapExactJarForJar(
        address _fromJar, // From which Jar
        address _toJar, // To which Jar
        uint256 _fromJarAmount, // How much jar tokens to swap
        uint256 _toJarMinAmount, // How much jar tokens you'd like at a minimum
        address payable[] calldata _targets,
        bytes[] calldata _data
    ) external returns (uint256) {
        require(_targets.length == _data.length, "!length");

        // Only return last response
        for (uint256 i = 0; i < _targets.length; i++) {
            require(_targets[i] != address(0), "!converter");
            require(approvedJarConverters[_targets[i]], "!converter");
        }

        address _fromJarToken = IJar(_fromJar).token();
        address _toJarToken = IJar(_toJar).token();

        // Get pTokens from msg.sender
        IERC20(_fromJar).safeTransferFrom(
            msg.sender,
            address(this),
            _fromJarAmount
        );

        // Calculate how much underlying
        // is the amount of pTokens worth
        uint256 _fromJarUnderlyingAmount = _fromJarAmount
            .mul(IJar(_fromJar).getRatio())
            .div(10**uint256(IJar(_fromJar).decimals()));

        // Call 'withdrawForSwap' on Jar's current strategy if Jar
        // doesn't have enough initial capital.
        // This has moves the funds from the strategy to the Jar's
        // 'earnable' amount. Enabling 'free' withdrawals
        uint256 _fromJarAvailUnderlying = IERC20(_fromJarToken).balanceOf(
            _fromJar
        );
        if (_fromJarAvailUnderlying < _fromJarUnderlyingAmount) {
            IStrategy(strategies[_fromJarToken]).withdrawForSwap(
                _fromJarUnderlyingAmount.sub(_fromJarAvailUnderlying)
            );
        }

        // Withdraw from Jar
        // Note: this is free since its still within the "earnable" amount
        //       as we transferred the access
        IERC20(_fromJar).safeApprove(_fromJar, 0);
        IERC20(_fromJar).safeApprove(_fromJar, _fromJarAmount);
        IJar(_fromJar).withdraw(_fromJarAmount); //vulnerable point

        // Calculate fee
        uint256 _fromUnderlyingBalance = IERC20(_fromJarToken).balanceOf(
            address(this)
        );
        uint256 _convenienceFee = _fromUnderlyingBalance.mul(convenienceFee).div(
            convenienceFeeMax
        );

        if (_convenienceFee > 1) {
            IERC20(_fromJarToken).safeTransfer(devfund, _convenienceFee.div(2));
            IERC20(_fromJarToken).safeTransfer(treasury, _convenienceFee.div(2));
        }

        // Executes sequence of logic
        for (uint256 i = 0; i < _targets.length; i++) {
            _execute(_targets[i], _data[i]);
        }

        // Deposit into new Jar
        uint256 _toBal = IERC20(_toJarToken).balanceOf(address(this));
        IERC20(_toJarToken).safeApprove(_toJar, 0);
        IERC20(_toJarToken).safeApprove(_toJar, _toBal);
        IJar(_toJar).deposit(_toBal);

        // Send Jar Tokens to user
        uint256 _toJarBal = IJar(_toJar).balanceOf(address(this));
        if (_toJarBal < _toJarMinAmount) {
            revert("!min-jar-amount");
        }

        IJar(_toJar).transfer(msg.sender, _toJarBal);

        return _toJarBal;
    }

Vulnerability type: Insufficient validation, Yield