How to upgrade any number of beacon proxies in a single operation

Hi OpenZeppelin community,

This is my first post here. Excited to be building using OZ tools.

I have an Artist contract that can have multiple instances deployed.

    const Artist = await hre.ethers.getContractFactory("Artist");
    const beacon = await hre.upgrades.deployBeacon(Artist);

    const bobProxy = await hre.upgrades.deployBeaconProxy(beacon, Artist, [
      "Bob",
    ]);

    const janeProxy = await hre.upgrades.deployBeaconProxy(beacon, Artist, [
      "Jane",
    ]);

    await janeProxy.deployed();
    await bobProxy.deployed();

    expect(await janeProxy.artistName()).to.equal("Jane");
    expect(await bobProxy.artistName()).to.equal("Bob");

    // Start upgrade
    const ArtistV2 = await hre.ethers.getContractFactory("ArtistV2");

    await hre.upgrades.upgradeBeacon(beacon, ArtistV2);

    const upgradedJane = ArtistV2.attach(janeProxy.address);
    const upgradedBob = ArtistV2.attach(bobProxy.address);

    expect(await upgradedJane.version()).to.equal("v2");
    expect(await upgradedBob.version()).to.equal("v2");

This works as expected but I'm a little confused as to why the attach function is needed. If I remove it my test fails. My understanding was that using beacon proxies allows multiple proxies to be upgraded to a different implementation in a single upgradeBeacon operation. However, it seems that if I have n proxy instances then I will need to call ArtistV2.attach(proxyAddress) n times. I was hoping that the beacon proxies would automatically attach to and start to use the new implementation. Is this not the case? Any insight on this would be greatly appreciated! Thanks!

When you called upgradeBeacon, it already upgraded the beacon on chain, and the beacon proxies therefore use the new implementation when you call them.

But in your script, attach is needed to update the variable locally so that you can use the new implementation's ABI directly. For example, if your v2 contract has a new function, that function would only be accessible in your script after you use attach.