Skip to content

Instantly share code, notes, and snippets.

@marcocastignoli
Last active January 24, 2022 19:50
Show Gist options
  • Select an option

  • Save marcocastignoli/18bb0344eafeaa8fd49349cfb5bdebe9 to your computer and use it in GitHub Desktop.

Select an option

Save marcocastignoli/18bb0344eafeaa8fd49349cfb5bdebe9 to your computer and use it in GitHub Desktop.
diamond framework
  1. fetch diamond infos and creates the example.diamond file
$ npx hardhat diamond loupe --address "0x123123..." -o "example.diamond"
  1. the command creates the file example.diamond
<Diamond
    address="0x123123123...."
    test1Func1="Test1Facet"
/>

<contract
    name="Test1Facet"
    type="remote"
    address="0x22222222222..."
/>
  1. Now I add a new function from a new facet
<Diamond
    address="0x123123123...."
    test1Func1="Test1Facet"
    test2Func1="Test2Facet"
/>

<contract
    name="Test1Facet"
    type="remote"
    address="0x22222222222..."
/>

<!-- ADD test2Func1 FROM NEW FACET -->
<contract 
    name="Test2Facet"
    type="local"
    path="facets/Test2Facet.sol"
/>
  1. now I cut the diamond with the new config
$ npx hardhat diamond cut example.diamond
  1. the command

    4.1) deploys the new facet

    6.2) update the diamond

    8.3) update the local example.diamond file with new address of Test2Facet

<Diamond
    address="0x123123123...."
    test1Func1="Test1Facet"
    test2Func1="Test2Facet"
/>

<contract 
    name="Test2Facet"
    type="remote"
    address="0x1111111111111"
/>

<contract
    name="Test3Facet"
    type="remote"
    address="0x22222222222..."
/>

diamond:loupe

passing the address of the diamond (--address) and the file to save the informations of the diamond (--o) it creates the diamond.json file that rappresent the remote diamond

$ npx hardhat diamond:loupe --address 0x10e138877df69Ca44Fdc68655f86c88CDe142D7F --o example.diamond.json

creates json file

{
  "diamond": {
    "diamondCut": "DiamondCutFacet",
    "facetAddress": "DiamondLoupeFacet",
    "facetAddresses": "DiamondLoupeFacet",
    /* ... */
  },
  "contracts": {
    "DiamondCutFacet": {
      "name": "DiamondCutFacet",
      "address": "0x767f7d9E655161C9E6D8a3Dbb565666FCAa2BDf4",
      "type": "remote"
    },
    "DiamondLoupeFacet": {
      "name": "DiamondLoupeFacet",
      "address": "0x04499B879F6A7E75802cd09354eF2B788BF4Cf26",
      "type": "remote"
    },
    /* ... */
  }
}

diamond:status

passing the address of the diamond (--address) and the file to use for comparison (--o) it prints all the functionsSelectors to update and the new contracts to deploy

$ npx hardhat diamond:status --address 0x10e138877df69Ca44Fdc68655f86c88CDe142D7F --o example.diamond.json

Diamonds:
        Add:  [ { newFunc: 'NewFacet' } ]
        Remove:  [ { changeRewardsAddress: 'ChangeRewardsFacet' } ]
        Replace:  [
            { owner: 'OwnershipFacetCustom' },
            { transferOwnership: 'OwnershipFacetCustom' }
        ]

Contracts to deploy:
    [
      {
        NewFacet: { name: 'NewFacet', type: 'local', path: 'facets/NewFacet.sol' }
      },
      {
        BarnFacet: { name: 'BarnFacet', type: 'local', path: 'facets/BarnFacet.sol' }
      }
    ]

1) loupe diamond the get all facets/fns

const diamondLoupeFacet = await ethers.getContractAt('DiamondLoupeFacet', diamondAddress)
const result = await diamondLoupeFacet.facets()
[
  [
    '0x5FbDB2315678afecb367f032d93F642f64180aa3',
    [ '0x1f931c1c' ],
    facetAddress: '0x5FbDB2315678afecb367f032d93F642f64180aa3',
    functionSelectors: [ '0x1f931c1c' ]
  ],
  [
    '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9',
    [
      '0xcdffacc6',
      '0x52ef6b2c',
      '0xadfca15e',
      '0x7a0ed627',
      '0x01ffc9a7'
    ],
    facetAddress: '0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9',
    functionSelectors: [
      '0xcdffacc6',
      '0x52ef6b2c',
      '0xadfca15e',
      '0x7a0ed627',
      '0x01ffc9a7'
    ]
  ],
  [
    '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9',
    [ '0x8da5cb5b', '0xf2fde38b' ],
    facetAddress: '0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9',
    functionSelectors: [ '0x8da5cb5b', '0xf2fde38b' ]
  ],
  [
    '0x0165878A594ca255338adfa4d48449f69242Eb8F',
    [ '0x19e3b533', '0x87952d22' ],
    facetAddress: '0x0165878A594ca255338adfa4d48449f69242Eb8F',
    functionSelectors: [ '0x19e3b533', '0x87952d22' ]
  ],
  [
    '0x8A791620dd6260079BF849Dc5567aDC3F2FdC318',
    [
      '0xcaae8f23', '0xea36b558',
      '0x8ee8be30', '0x884280a6',
      '0xca5fa5c0', '0x6dc16b01',
      '0x91d0396b', '0x03feeeae',
      '0x2e463958', '0x14884309',
      '0x0c103a93', '0x5fd6312b',
      '0xe7de23a4', '0x792a8e2e',
      '0x0e4cd7fc', '0xc670641d',
      '0xd2f0c73e', '0x17fd06e7',
      '0xef3f4d78', '0xe5f687b2'
    ],
    facetAddress: '0x8A791620dd6260079BF849Dc5567aDC3F2FdC318',
    functionSelectors: [
      '0xcaae8f23', 
    ]
  ]
]

2) for each facet cal the etherscan API (passing facetAddress)

const API_KEY = '...'
const address = '0x5FbDB2315678afecb367f032d93F642f64180aa3'
fetch(`https://api.etherscan.io/api?module=contract&action=getsourcecode&address=${address}&apikey=${API_KEY}`)

3) build the diamond's json

{
        "diamond": {
            "test1Func1": "Test1Facet", // or "0xcaae8f23": "Test1Facet"
            "test3Func1": "Test1Facet"
        },
        "contracts": {
            "Test1Facet": {
                "name": "Test1Facet",
                "type": "remote",
                "address": "0x12301230912309..."
            },
            "Test3Facet": {
                "name": "Test3Facet",
                "type": "remote",
                "address": "0x12301230912309..."
            },
        }
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment