Skip to content

Commit

Permalink
refactor: added script to create a diamond cut- params for facets
Browse files Browse the repository at this point in the history
  • Loading branch information
Debugger022 committed May 18, 2023
1 parent 8a2cb76 commit cff7477
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 74 deletions.
82 changes: 82 additions & 0 deletions simulations/vip-diamond-comptroller-testnet/scripts/diamond.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { ethers } from "hardhat";

const FacetCutAction = { Add: 0, Replace: 1, Remove: 2 };

// get function selectors from ABI
function getSelectors(contract: any) {
const signatures = Object.keys(contract.interface.functions);
const selectors: any = signatures.reduce((acc: any, val) => {
if (val !== "init(bytes)") {
acc.push(contract.interface.getSighash(val));
}
return acc;
}, []);
selectors.contract = contract;
selectors.remove = remove;
selectors.get = get;
return selectors;
}

// get function selector from function signature
function getSelector(func: any) {
const abiInterface = new ethers.utils.Interface([func]);
return abiInterface.getSighash(ethers.utils.Fragment.from(func));
}

// used with getSelectors to remove selectors from an array of selectors
// functionNames argument is an array of function signatures
function remove(functionNames: any) {
const selectors = this.filter(v => {
for (const functionName of functionNames) {
if (v === this.contract.interface.getSighash(functionName)) {
return false;
}
}
return true;
});
selectors.contract = this.contract;
selectors.remove = this.remove;
selectors.get = this.get;
return selectors;
}

// used with getSelectors to get selectors from an array of selectors
// functionNames argument is an array of function signatures
function get(functionNames) {
const selectors = this.filter(v => {
for (const functionName of functionNames) {
if (v === this.contract.interface.getSighash(functionName)) {
return true;
}
}
return false;
});
selectors.contract = this.contract;
selectors.remove = this.remove;
selectors.get = this.get;
return selectors;
}

// remove selectors using an array of signatures
function removeSelectors(selectors, signatures) {
const iface = new ethers.utils.Interface(signatures.map(v => "function " + v));
const removeSelectors = signatures.map(v => iface.getSighash(v));
selectors = selectors.filter(v => !removeSelectors.includes(v));
return selectors;
}

// find a particular address position in the return value of diamondLoupeFacet.facets()
function findAddressPositionInFacets(facetAddress, facets) {
for (let i = 0; i < facets.length; i++) {
if (facets[i].facetAddress === facetAddress) {
return i;
}
}
}

exports.getSelectors = getSelectors;
exports.getSelector = getSelector;
exports.FacetCutAction = FacetCutAction;
exports.remove = remove;
exports.removeSelectors = removeSelectors;
exports.findAddressPositionInFacets = findAddressPositionInFacets;
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import fs from "fs";
import { ethers } from "hardhat";

import { FacetCutAction, getSelectors } from "./diamond";

/**
* This script is used to generate the cut-params which will be used in diamond proxy vip
* to add diamond facets
*/

// Insert the addresses of the deployed facets to generate thecut params according for the same.
const facetsAddresses: any = {
MarketFacet: "",
PolicyFacet: "",
RewardFacet: "",
SetterFacet: "",
};

// Set actions to the cut params to perform
// i.e. Add, Remove, Replace function selectors in the mapping.
const facetsActions: any = {
MarketFacet: FacetCutAction.Add,
PolicyFacet: FacetCutAction.Add,
RewardFacet: FacetCutAction.Add,
SetterFacet: FacetCutAction.Add,
};

// Set interfaces for the setters to generate function selectors from
const FacetsInterfaces: any = {
MarketFacet: "IMarketFacet",
PolicyFacet: "IPolicyFacet",
RewardFacet: "IRewardFacet",
SetterFacet: "ISetterFacet",
};

// Facets for which cute params need to generate
const FacetNames = ["MarketFacet", "PolicyFacet", "RewardFacet", "SetterFacet"];

// Name of the file to write the cut-params
const jsonFileName = "cur-params-test";

async function generateCutParams() {
const cut: any = [];

for (const FacetName of FacetNames) {
const FacetInterface = await ethers.getContractAt(FacetsInterfaces[FacetName], facetsAddresses[FacetName]);

switch (facetsActions[FacetName]) {
case FacetCutAction.Add:
cut.push({
facetAddress: facetsAddresses[FacetName],
action: FacetCutAction.Add,
functionSelectors: getSelectors(FacetInterface),
});
break;
case FacetCutAction.Remove:
cut.push({
facetAddress: ethers.constants.AddressZero,
action: FacetCutAction.Remove,
functionSelectors: getSelectors(FacetInterface),
});
break;
case FacetCutAction.Replace:
cut.push({
facetAddress: facetsAddresses[FacetName],
action: FacetCutAction.Replace,
functionSelectors: getSelectors(FacetInterface),
});
break;
default:
break;
}
}

function getFunctionSelector(selectors: any) {
const functionSelector: any = [];
for (let i = 0; i < selectors.length; i++) {
if (selectors[i][0] == "0") {
functionSelector.push(selectors[i]);
} else {
break;
}
}
return functionSelector;
}

function makeCutParam(cut: any) {
const cutParams = [];
for (let i = 0; i < cut.length; i++) {
const arr: any = new Array(3);
arr[0] = cut[i].facetAddress;
arr[1] = cut[i].action;
arr[2] = getFunctionSelector(cut[i].functionSelectors);
cutParams.push(arr);
}
return cutParams;
}
const cutParams = { cutParams: makeCutParam(cut) };

fs.writeFileSync(`./${jsonFileName}.json`, JSON.stringify(cutParams, null, 4));
return cutParams;
}

generateCutParams()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
Original file line number Diff line number Diff line change
@@ -1,80 +1,72 @@
{
"cutParams": [
[
"0x981e47f3Fd5A497280Fb9adD5791F155Eb9D7c6F",
0,
["0xa76b3fda", "0x929fe9a1", "0xc2998238", "0xede4edd0", "0xabfceffc", "0x007e3dd2", "0xc488847b"]
],
[
"0xD97212b66b158C3CF8E869E3cCc4d21A0193a7D6",
0,
[
"0x981e47f3Fd5A497280Fb9adD5791F155Eb9D7c6F",
0,
[
"0xa76b3fda",
"0x929fe9a1",
"0xc2998238",
"0xede4edd0",
"0xabfceffc",
"0x007e3dd2",
"0xc488847b"
]
],
[
"0xD97212b66b158C3CF8E869E3cCc4d21A0193a7D6",
0,
[
"0xead1a8a0",
"0xda3d454c",
"0x5c778605",
"0x5ec88c79",
"0x5fc7e71e",
"0x47ef3b3b",
"0x4ef4c3e1",
"0x41c728b9",
"0xeabe7d91",
"0x51dff989",
"0x24008a62",
"0x1ededc91",
"0xd02f7351",
"0x6d35bf91",
"0xbdcdc258",
"0x6a56947e"
]
],
"0xead1a8a0",
"0xda3d454c",
"0x5c778605",
"0x5ec88c79",
"0x5fc7e71e",
"0x47ef3b3b",
"0x4ef4c3e1",
"0x41c728b9",
"0xeabe7d91",
"0x51dff989",
"0x24008a62",
"0x1ededc91",
"0xd02f7351",
"0x6d35bf91",
"0xbdcdc258",
"0x6a56947e"
]
],
[
"0x01C9caD8F9fe08397b1737F71865067dC08237d8",
0,
[
"0x01C9caD8F9fe08397b1737F71865067dC08237d8",
0,
[
"0xa7604b41",
"0xe85a2960",
"0x70bf66f0",
"0x86df31ee",
"0xadcd5fb9",
"0xd09c54ba",
"0x7858524d",
"0x42cbb15c",
"0xbf32442d",
"0xededbae6",
"0xddfd287e"
]
],
"0xa7604b41",
"0xe85a2960",
"0x70bf66f0",
"0x86df31ee",
"0xadcd5fb9",
"0xd09c54ba",
"0x7858524d",
"0x42cbb15c",
"0xbf32442d",
"0xededbae6",
"0xddfd287e"
]
],
[
"0x06c98127900274eeB636B1957287D2C76C0cb476",
0,
[
"0x06c98127900274eeB636B1957287D2C76C0cb476",
0,
[
"0xf519fc30",
"0x2b5d790c",
"0x317b0b77",
"0xe4028eee",
"0x9bf34cbb",
"0x4fd42e17",
"0xbb857450",
"0x607ef6c1",
"0x51a485e4",
"0x5f5af1aa",
"0x55ee1fe1",
"0x2a6a6065",
"0xd24febad",
"0x9cfdd9e6",
"0x2ec04124",
"0x4e0853db",
"0x6662c7c9",
"0xfd51a3ad"
]
"0xf519fc30",
"0x2b5d790c",
"0x317b0b77",
"0xe4028eee",
"0x9bf34cbb",
"0x4fd42e17",
"0xbb857450",
"0x607ef6c1",
"0x51a485e4",
"0x5f5af1aa",
"0x55ee1fe1",
"0x2a6a6065",
"0xd24febad",
"0x9cfdd9e6",
"0x2ec04124",
"0x4e0853db",
"0x6662c7c9",
"0xfd51a3ad"
]
]
]
}
}
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { impersonateAccount, setBalance } from "@nomicfoundation/hardhat-network
import { NumberLike } from "@nomicfoundation/hardhat-network-helpers/dist/src/types";
import { expect } from "chai";
import { ContractInterface, TransactionResponse } from "ethers";
import { ethers, network } from "hardhat";
import { ParamType } from "ethers/lib/utils";
import { ethers, network } from "hardhat";

import { Command, Proposal, ProposalMeta, ProposalType } from "./types";
import VENUS_CHAINLINK_ORACLE_ABI from "./vip-framework/abi/VenusChainlinkOracle.json";
Expand Down

0 comments on commit cff7477

Please sign in to comment.