GithubHelp home page GithubHelp logo

mudgen / diamond-1-hardhat Goto Github PK

View Code? Open in Web Editor NEW
125.0 125.0 83.0 451 KB

EIP-2535 Diamond reference implementation using Hardhat and Solidity 0.8.*

License: MIT License

Solidity 62.37% JavaScript 37.63%

diamond-1-hardhat's People

Contributors

mudgen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

diamond-1-hardhat's Issues

Purpose of `DiamondInit` contract?

I don't quite follow how the DiamondInit contract fits into this example project.

  • It's like a facet of the diamond (since it uses the diamond's storage) but it's never registered as a facet?
  • It's not necessary for setting the diamond's state/calling functions during deployment since we can just as well do that in the diamond's constructor?
    // Code can be added here to perform actions and set state variables.
  • It's also not necessary for setting the state/calling functions during upgrades since we can just as well do that when calling diamondCutβ€”most likely by using the address of the facet that was just upgraded as the _init address?
    /// @param _init The address of the contract or facet to execute _calldata

So then what is the purpose of DiamondInit exactly? Is there a use case that cannot be accomplished without it?

DiamondLoupeFacet required, yet not added in constructor?

Hi @mudgen, this is mostly just a question for you, and may not be a big issue.

I noticed the following language in this and the other reference implementations:

Note: The loupe functions in DiamondLoupeFacet.sol MUST be added to a diamond and are required by the EIP-2535 Diamonds standard.

If this is the case, why is the DiamondLoupeFacet not being added in the constructor, as is done with the DiamondCut facet?

I am a grad student and researcher working on a survey of current upgradeability patterns, so it would be great to connect with you!

-Bill

IDiamond.sol defined but never used

I noticed that IDiamond.sol is included in the interfaces folder but the Diamond contract does not inherit from it. Is that an oversight or a conscious decision to have it like that?

encodeFunctionData for `multiInit` function inside `DiamondMultiInit` library fails

Hi @mudgen !

First of all thanks a lot for this implementation example πŸ™

I'm hitting a very strange error when trying to deploy & initialise my Diamond along with multiple facets in one transaction.

The function encodeFunctionData used to create the calldata passed into the diamondArgs initCalldata field returns the following error: Error: no matching function (argument="name", value="multiInit", code=INVALID_ARGUMENT, version=abi/5.7.0)

Here is a part of the deploy flow:

  // Just above I deploy my facets & add them to the facetCuts array like in your script 
  // I also use encodeFunctionData to create the calldata needed to create initializeErc20Call, initializeFacetBCall & initializeFacetCCall and it works fine

  const diamondMultiInitFactory = await ethers.getContractFactory("DiamondMultiInit");
    const diamondMultiInit = await diamondMultiInitFactory.deploy();
  await diamondMultiInit.deployed()
  let multiInitCallData = diamondMultiInit.interface.encodeFunctionData('multiInit', [
    [erc20.address, facetB.address, facetC.address],
    [initializeErc20Call, initializeFacetBCall, initializeFacetCCall]
  ])

  const diamondArgs = {
    owner: myOwner.address,
    init: diamondMultiInit.address,
    initCalldata: multiInitCallData
  }

  const diamond = await diamondFactory.deploy(facetCuts, diamondArgs)
  await diamond.deployed()
  console.log('Diamond deployed:', diamond.address)

And when I look into the interface of the deployed DiamondMultiInit library I get:

 interface: Interface {
    fragments: [ [ErrorFragment], [ErrorFragment], [ErrorFragment] ],
    _abiCoder: AbiCoder { coerceFunc: null },
    functions: {}, // Empty is weird
    errors: {
      'AddressAndCalldataLengthDoNotMatch(uint256,uint256)': [ErrorFragment],
      'InitializationFunctionReverted(address,bytes)': [ErrorFragment],
      'NoBytecodeAtAddress(address,string)': [ErrorFragment]
    },
    events: {},
    structs: {},
    deploy: ConstructorFragment {
      name: null,
      type: 'constructor',
      inputs: [],
      payable: false,
      stateMutability: 'nonpayable',
      gas: null,
      _isFragment: true
    },
    _isInterface: true
  }

Now I've tried to play around a bit with the multiInit function to investigate if there was a problem with the arguments I was passing etc and I ended up realising that when I change this multiInit function to a pure or view function (so commenting out the LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]); code) then I no longer get this no matching function error. And the interface looks correct this time:

interface: Interface {
    fragments: [ [ErrorFragment], [FunctionFragment] ],
    _abiCoder: AbiCoder { coerceFunc: null },
    functions: { 'multiInit(address[],bytes[])': [FunctionFragment] }, // Now I see the multiInit
    errors: {
      'AddressAndCalldataLengthDoNotMatch(uint256,uint256)': [ErrorFragment] // Here I weirdly no longer see InitializationFunctionReverted & NoBytecodeAtAddress errors now, they were present above..
    },
    events: {},
    structs: {},
    deploy: ConstructorFragment {
      name: null,
      type: 'constructor',
      inputs: [],
      payable: false,
      stateMutability: 'nonpayable',
      gas: null,
      _isFragment: true
    },
    _isInterface: true
  }

Also worth noting it behaves correctly when I turn the library into a normal contract, so maybe it's related ?

I can provide the full deploy flow script & facets code if that helps πŸ‘

Thanks a lot in advance for your help :))

Optimization fallback() function

In Diamond.sol fallback function

 LibDiamond.DiamondStorage storage ds;
        bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
        // get diamond storage
        assembly {
            ds.slot := position
        }

why not use LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();?

Comments are flagged as invalid doc tags

Importing some of these contracts results in an invalid doc tag solidity compiler error when using this repo as a submodule, importing them, and compiling the contracts with foundry.
image

How to upgrade a Library

Considering supportive Libraries aren't deployed on their own I wonder how the DiamondCut can broadcast an updated library to all facets. Would be great if this was added to the examples in the /test/ directory. Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.