contract VaultBaseUpgradeable is VaultControlUpgradeable {
  // Internal functions

  /**
   * @dev Executes deposit operation with delegatecall.
   * @param _amount: amount to be deposited
   * @param _provider: address of provider to be used
   */
  function _deposit(uint256 _amount, address _provider) internal {
    bytes memory data = abi.encodeWithSignature(
      "deposit(address,uint256)",
      vAssets.collateralAsset,
      _amount
    );
    _execute(_provider, data);
  }

  /**
   * @dev Executes withdraw operation with delegatecall.
   * @param _amount: amount to be withdrawn
   * @param _provider: address of provider to be used
   */
  function _withdraw(uint256 _amount, address _provider) internal {
    bytes memory data = abi.encodeWithSignature(
      "withdraw(address,uint256)",
      vAssets.collateralAsset,
      _amount
    );
    _execute(_provider, data);
  }

  /**
   * @dev Executes borrow operation with delegatecall.
   * @param _amount: amount to be borrowed
   * @param _provider: address of provider to be used
   */
  function _borrow(uint256 _amount, address _provider) internal {
    bytes memory data = abi.encodeWithSignature(
      "borrow(address,uint256)",
      vAssets.borrowAsset,
      _amount
    );
    _execute(_provider, data);
  }

  /**
   * @dev Executes payback operation with delegatecall.
   * @param _amount: amount to be paid back
   * @param _provider: address of provider to be used
   */
  function _payback(uint256 _amount, address _provider) internal {
    bytes memory data = abi.encodeWithSignature(
      "payback(address,uint256)",
      vAssets.borrowAsset,
      _amount
    );
    _execute(_provider, data);
  }

  /**
   * @dev Returns byte response of delegatcalls
   */
  function _execute(address _target, bytes memory _data)
    internal
    whenNotPaused
    returns (bytes memory response)
  {
    /* solhint-disable */
    assembly {
      let succeeded := delegatecall(sub(gas(), 5000), _target, add(_data, 0x20), mload(_data), 0, 0)
      let size := returndatasize()

      response := mload(0x40)
      mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))
      mstore(response, size)
      returndatacopy(add(response, 0x20), 0, size)

      switch iszero(succeeded)
      case 1 {
        // throw if delegatecall failed
        revert(add(response, 0x20), size)
      }
    }
    /* solhint-disable */
  }
}
function _deposit(uint256 _amount, address _provider) internal {
  bytes memory data = abi.encodeWithSignature(
    "deposit(address,uint256)",
    vAssets.collateralAsset,
    _amount
  );
  _execute(_provider, data);
}

/**
 * @dev Executes deposit operation with delegatecall.
 * @param _amount: amount to be deposited
 * @param _provider: address of provider to be used
 */