You are creating a vector of n*n empty vectors, not a 2D matrix.
One way I got around this is making it a vector of pointers to vectors, and then creating vectors for the pointers to point to, like this:
#include<bits/stdc++.h>
using namespace std;
void fun(vector <vector<int>*> &arr)
{
    (*arr[2])[2]=100;
    cout<<"DOne";
}
int main()
{
    int n=8;
   vector < vector<int>*  > arr(n);
   for(auto i = arr.begin(); i != arr.end(); i++){
       *i = new vector<int>(n); //Fill the vector with vectors, which will be added to the heap.
   }
    
    fun(arr);
    cout<< (*arr[2])[2];
    return 0;
}
This worked for me as expected, printing DOne100.
You may notice, however, that I needed to access the elements in a special way. arr[i][j] would not work in this case, since a vector and an array are not really the same. Instead, you have to use (*arr[i])[j].
If you want to make it a vector to vectors, rather than a vector of pointers to vectors, you will need to give each of the vectors in your vector the desired size, which would look something like this:
std::vector<std::vector<int>> arr(n);
for(auto i = arr.begin(); i != arr.end(); i++){
        i->resize(n); //Give each vector a size of n
}
Accessing each element is as easy as arr[i][j].
I tested this out with your implementation of fun(arr) and it gave the expected result.