New ProxyAdmin deployed then "Proxy admin is not the one registered in the network manifest"

I deployed an upgradable contract to mainnet some time ago. Now I'm trying to run a new migration that deploys a new upgradable contract and upgrades the old one.

After the new contract is deployed, the migration deploys a ProxyAdmin contract. Is my understanding correct that this shouldn't be happening? Isn't there just supposed to be one ProxyAdmin contract per project?

Finally when the original contract is being upgraded, i get the error Error: Proxy admin is not the one registered in the network manifest despite deploying using the same address I originally used: 0x67368f4c89DDa2a82D12D3a703c32C35ff343bF6

Any help is very much appreciated.
Thank you

:1234: Code to reproduce

Here is my migration file:

module.exports = async function (deployer, network, accounts) {
    //Deploy PropToken0
    propTokenInstance = await deployProxy(propToken0, ["PropToken", "Prop", deployedPool0.address, "0xa42f6FB68607048dDe54FCd53D2195cc8ca5F486"],  { deployer });
    console.log('Deployed Proptoken to', propTokenInstance.address);

  //Upgrade pool from 0->1
  console.log("about to update pool0 to pool1. Pool0 address is: " + deployedPool0.address)
  await upgradeProxy(deployedPool0.address, Pool1, { deployer });

and my mainnet.json network file:

  "manifestVersion": "3.2",
  "admin": {
    "address": "0x5729890f78c07Bc2d1C09345001F6C1f0c9D7D6F",
    "txHash": "0x5b9a8afc3a3842ddff7a285fe8162b55f5fb6614da1a20408b4512344b5c99fb"
  "proxies": [
      "address": "0xb8919522331C59f5C16bDfAA6A121a6E03A91F62",
      "txHash": "0xa26f1506913086d6cc64921f61ba6ab3d65d6f7040aba2ed22182fd893c4383c",
      "kind": "transparent"
  "impls": {
    "659e70960339ccfb7cc3cf541ac3a0abbeacdb1c10823e7c8530071d3872b8ed": {
      "address": "0xe92D07270433DC6DD9ff1ED637AcD792D15d761c",
      "txHash": "0xcc1ab8d608b0e71a91e02ec34564679c61786ce9d3afd7b6eb79ff42116d5bc7",
      "layout": {}

:computer: Environment

Truffle v5.4.11 (core: 5.4.11)
Solidity - 0.8.0 (solc-js)
Node v14.17.6
Web3.js v1.5.2

I'm just learning all this myself, but as far as I understand each upgradeable contract has its own ProxyAdmin. If not, it is my intuition that you would have had to point to the original proxy somehow anyways, which it doesn't seem like you are doing. Maybe there's a pattern that has one proxy for all contracts, if so would like to be pointed to this info.

As far as your second point I have no clue :sweat_smile: I have yet to have deployed an upgradeable contract, can't get the upgradeable plugins working. So not sure how this mainnet.json file works, but I notice the address you listed above isn't the same one you have in the proxies array. Maybe try using that address instead?

But like I said, extreme beginner so don't believe a word I say

I want to ask that we've deployed an up-gradable contract yesterday on polygon by hardhat plugin and it was deployed in one single transaction and now today we're deploying the same up-gradable contract now from same hardhat it's deploying in 3 transactions can you tell me why it's taking 2 extra transactions?

contract address deployed in one single transaction:0x6a4581fffdeaC8246B2DC3662F1035B6F5E8e618

Hi @Shahbaz_Ali, there are up to 3 contracts that are deployed for a transparent proxy:

  1. The implementation contract
  2. The proxy admin contract
  3. The transparent proxy contract

If either items 1 or 2 above were previously deployed on the same network, the plugin would reuse those as long as you keep the .openzeppelin folder which contains the network files tracking those deployments. See

does openzeppelin verify these upgradeable contracts for us except implementation ?

Regarding the items above:

  1. Before deploying an implementation contract, the plugins validate that your contract is upgrade safe and, if upgrading, compatible with the previous version. After that validation occurs, the plugins look up the network files to see if any previously deployed implementation contract matches in bytecode, and if there is a match, that one will be used.

  2. The proxy admin contract (if previously deployed) is also looked up from the network files. If not found, it will be deployed.

  3. The transparent proxy contract is then deployed.