Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
PRIVATE_KEY=
ARBISCAN_API_KEY=
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

## vNEXT

- Migrate contracts to Diamond pattern - Part1 (#222)
- Migrate proxy to Diamond pattern (ERC-2535):
- Fix `fallback` and `receive` (#223)
- Migrate contracts (#222)
- Add Github Action CI in order to publish NPM package

### Updated contracts
Expand Down
92 changes: 92 additions & 0 deletions contracts/Diamond.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

//*************************************************************************************\
//* Adapted from Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)
//* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535
//*
//* Implementation of a diamond.
//*************************************************************************************/

// Diamond proxy implementation adapted from Mudgen's to re-direct
// `receive` and `fallback` calls to the implementations in facets.

import { LibDiamond } from "@mudgen/diamond-1/contracts/libraries/LibDiamond.sol";
import { IDiamondCut } from "@mudgen/diamond-1/contracts/interfaces/IDiamondCut.sol";
import { IDiamondLoupe } from "@mudgen/diamond-1/contracts/interfaces/IDiamondLoupe.sol";
import { IERC173 } from "@mudgen/diamond-1/contracts/interfaces/IERC173.sol";
import { IERC165} from "@mudgen/diamond-1/contracts/interfaces/IERC165.sol";

// When no function exists for function called
error FunctionNotFound(bytes4 _functionSelector);

// This is used in diamond constructor
// more arguments are added to this struct
// this avoids stack too deep errors
struct DiamondArgs {
address owner;
address init;
bytes initCalldata;
}

contract Diamond {

constructor(IDiamondCut.FacetCut[] memory _diamondCut, DiamondArgs memory _args) payable {
LibDiamond.setContractOwner(_args.owner);
LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata);

// Code can be added here to perform actions and set state variables.
}

/**
* `fallback` function must be added to the diamond with selector `0xffffffff`.
* The function is defined in IexecEscrow(Native/Token) facet.
*/
fallback() external payable{
_fallback();
}

/**
* `receive` function must be added to the diamond with selector `0x00000000`.
* The function is defined in IexecEscrow(Native/Token) facet.
*/
receive() external payable {
_fallback();
}

// Find facet for function that is called and execute the
// function if a facet is found and return any value.
function _fallback() internal {
LibDiamond.DiamondStorage storage ds;
bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
// get diamond storage
assembly {
ds.slot := position
}
// get facet from function selector
address facet = ds.facetAddressAndSelectorPosition[msg.sig].facetAddress;
if (facet == address(0)) {
facet = ds.facetAddressAndSelectorPosition[0xffffffff].facetAddress;
}
if(facet == address(0)) {
revert FunctionNotFound(msg.sig);
}
// Execute external function from facet using delegatecall and return any value.
assembly {
// copy function selector and any arguments
calldatacopy(0, 0, calldatasize())
// execute function call using the facet
let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
// get any return value
returndatacopy(0, 0, returndatasize())
// return any return value or error back to the caller
switch result
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
}
41 changes: 17 additions & 24 deletions deploy/0_deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers';
import { ZeroAddress, ZeroHash } from 'ethers';
import { deployments, ethers } from 'hardhat';
import hre, { deployments, ethers } from 'hardhat';
import { FacetCut, FacetCutAction } from 'hardhat-deploy/dist/types';
import {
AppRegistry__factory,
Expand Down Expand Up @@ -32,6 +32,7 @@ import {
IexecPocoBoostAccessorsDelegate__factory,
IexecPocoBoostDelegate__factory,
IexecRelayDelegate__factory,
LibDiamond__factory,
OwnershipFacet__factory,
RLC__factory,
WorkerpoolRegistry__factory,
Expand All @@ -41,25 +42,16 @@ import { FactoryDeployer } from '../utils/FactoryDeployer';
import config from '../utils/config';
import { getFunctionSelectors, linkContractToProxy } from '../utils/proxy-tools';
import { DiamondArgsStruct } from '../typechain/@mudgen/diamond-1/contracts/Diamond';
import { getBaseNameFromContractFactory } from '../utils/deploy-tools';

/**
* @dev Deploying contracts with `npx hardhat deploy` task brought by
* `hardhat-deploy` plugin.
* Previous deployments made with `npx hardhat run scripts/deploy.ts` used to
* hang at the end of deployments (terminal did not return at the end).
*
* Note:
* The`hardhat-deploy` plugin is currently being under used compared to all
* features available in it.
*/
let factoryDeployer: FactoryDeployer;

export default async function deploy() {
console.log('Deploying PoCo..');
const network = await ethers.provider.getNetwork();
const chainId = network.chainId;
const [owner] = await ethers.getSigners();
const deploymentOptions = config.getChainConfigOrDefault(chainId);
const factoryDeployer = new FactoryDeployer(owner, chainId);
factoryDeployer = new FactoryDeployer(owner, chainId);
// Deploy RLC
const isTokenMode = !config.isNativeChain(deploymentOptions);
let rlcInstanceAddress = isTokenMode
Expand All @@ -79,14 +71,9 @@ export default async function deploy() {
.catch(() => {
throw new Error('Failed to prepare transferOwnership data');
});
const initAddress = await factoryDeployer.deployContract(new DiamondInit__factory());
const initCalldata = DiamondInit__factory.createInterface().encodeFunctionData('init');
const erc1538ProxyAddress = await deployDiamondProxyWithDefaultFacets(
factoryDeployer,
owner.address,
// transferOwnershipCall, //TODO
initAddress,
initCalldata,
);
const erc1538 = DiamondCutFacet__factory.connect(erc1538ProxyAddress, owner);
console.log(`IexecInstance found at address: ${await erc1538.getAddress()}`);
Expand Down Expand Up @@ -261,17 +248,23 @@ async function getOrDeployRlc(token: string, owner: SignerWithAddress) {
* @returns The address of the deployed Diamond proxy contract.
*/
async function deployDiamondProxyWithDefaultFacets(
factoryDeployer: FactoryDeployer,
ownerAddress: string,
// transferOwnershipCall: string, // TODO
initAddress: string,
initCalldata: string,
): Promise<string> {
const initAddress = await factoryDeployer.deployContract(new DiamondInit__factory());
const initCalldata = DiamondInit__factory.createInterface().encodeFunctionData('init');
// Deploy LibDiamond and link it to fix coverage task issue.
const libDiamondAddress =
(hre as any).__SOLIDITY_COVERAGE_RUNNING &&
(await factoryDeployer.deployContract(new LibDiamond__factory()));
const libDiamondConfig = (hre as any).__SOLIDITY_COVERAGE_RUNNING && {
['@mudgen/diamond-1/contracts/libraries/LibDiamond.sol:LibDiamond']: libDiamondAddress,
};
// Deploy required proxy facets.
const facetFactories = [
new DiamondCutFacet__factory(),
new DiamondCutFacet__factory(libDiamondConfig),
new DiamondLoupeFacet__factory(),
new OwnershipFacet__factory(),
new OwnershipFacet__factory(libDiamondConfig),
];
const facetCuts: FacetCut[] = [];
for (let i = 0; i < facetFactories.length; i++) {
Expand All @@ -290,7 +283,7 @@ async function deployDiamondProxyWithDefaultFacets(
initCalldata: initCalldata,
};
return await factoryDeployer.deployContract(
new Diamond__factory(),
new Diamond__factory(libDiamondConfig),
[facetCuts, diamondArgs],
// transferOwnershipCall, // TODO
);
Expand Down
81 changes: 0 additions & 81 deletions deployment.log

This file was deleted.

8 changes: 4 additions & 4 deletions deployments/arbitrumSepolia/AppRegistry.json

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions deployments/arbitrumSepolia/DatasetRegistry.json

Large diffs are not rendered by default.

Loading