Skip to content

Commit

Permalink
chore: resolve merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
spicysquid168 committed May 18, 2023
2 parents ab30a33 + 630f507 commit 92efda4
Show file tree
Hide file tree
Showing 95 changed files with 5,434 additions and 8,294 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
.vscode
.env

cache/
forge_cache/
out/

artifacts/
cache/
node_modules/
typechain/

yarn-error.log/
yarn-error.log

broadcast/

Expand Down
14 changes: 12 additions & 2 deletions .mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"doge": "0xbA2aE424d960c26247Dd6c32edC70B295c744C43",
"dot": "0x7083609fCE4d1d8Dc0C979AAb8c869Ea2C873402",
"eth": "0x2170Ed0880ac9A755fd29B2688956BD959F933F8",
"high": "0x5f4Bde007Dc06b867f86EBFE4802e34A1fFEEd63",
"matic": "0xCC42724C6683B7E57334c4E856f4c9965ED682bD",
"tusd": "0x14016E85a25aeb13065688cAFB43044C2ef86784",
"usdt": "0x55d398326f99059fF775485246999027B3197955",
Expand Down Expand Up @@ -52,6 +53,7 @@
"collateralFacet": "0x8cE125c65605f937AE16645a3642d3A335852936",
"diamondCutFacet": "0x2E28CbF8995969d4ea1F03FfB6f25dab8afEE45C",
"diamondLoupeFacet": "0xaDB5Be7b114Ca6721e00778F97e615B85D095952",
"flashloanFacet": "",
"lendFacet": "0x0d8AE68ee3eE728Ed7AE9E99Edc10f2cfc3959b1",
"liquidationFacet": "0xaB530549D03AE12A96292d749c75f7f719EA2f9D",
"nonCollatBorrowFacet": "0xF22133299081534780777D1504A6B38955195b03",
Expand Down Expand Up @@ -194,5 +196,13 @@
}
]
},
"moneyMarketReader": "0x1d3cb2f91207afDA9E9baB89caDE1a4c3222cf6a"
}
"rewarders": [],
"moneyMarketReader": "0x4913DEC75cC0e061Ba78ebbDb2584905760be4C6",
"smartTreasury": {
"implementation": "",
"proxy": ""
},
"pathReader": {
"v3": ""
}
}
155 changes: 155 additions & 0 deletions deploy/core/facets/diamond-cut/execute-diamond.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { ethers } from "hardhat";

import * as readlineSync from "readline-sync";
import { ConfigFileHelper } from "../../../file-helper.ts/config-file.helper";
import { getDeployer } from "../../../utils/deployer-helper";
import { facetContractNameToAddress, getSelectors } from "../../../utils/diamond";
import { IMMDiamondCut, MMDiamondCutFacet__factory, MMDiamondLoupeFacet__factory } from "../../../../typechain";

enum FacetCutAction {
Add,
Replace,
Remove,
}

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
/*
░██╗░░░░░░░██╗░█████╗░██████╗░███╗░░██╗██╗███╗░░██╗░██████╗░
░██║░░██╗░░██║██╔══██╗██╔══██╗████╗░██║██║████╗░██║██╔════╝░
░╚██╗████╗██╔╝███████║██████╔╝██╔██╗██║██║██╔██╗██║██║░░██╗░
░░████╔═████║░██╔══██║██╔══██╗██║╚████║██║██║╚████║██║░░╚██╗
░░╚██╔╝░╚██╔╝░██║░░██║██║░░██║██║░╚███║██║██║░╚███║╚██████╔╝
░░░╚═╝░░░╚═╝░░╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚══╝╚═╝╚═╝░░╚══╝░╚═════╝░
Check all variables below before execute the deployment script
*/

const FACET = "ViewFacet";
const INITIALIZER_ADDRESS = ethers.constants.AddressZero;
const OLD_FACET_ADDRESS = "0xA7D618BF3880f146Bbc0F0d18eB6f13F59d3D339";

const deployer = await getDeployer();

const configFileHelper = new ConfigFileHelper();
const config = configFileHelper.getConfig();

const diamondLoupeFacet = MMDiamondLoupeFacet__factory.connect(config.moneyMarket.moneyMarketDiamond, deployer);

const diamondCutFacet = MMDiamondCutFacet__factory.connect(config.moneyMarket.moneyMarketDiamond, deployer);

console.log(`> Diamond cutting ${FACET}`);

// Build the facetCuts array
console.log(`> Build the action selectors array from ${FACET} contract`);
const contractFactory = await ethers.getContractFactory(FACET);
const facetAddress = facetContractNameToAddress(FACET);
const existedFacetCuts = (await diamondLoupeFacet.facets())
.map((each) => each.functionSelectors)
.reduce((result, array) => result.concat(array), []);

const previousFacet = (await diamondLoupeFacet.facets()).find((each) => each.facetAddress == OLD_FACET_ADDRESS);
if (!previousFacet) {
console.log("Previous facet not found");
return;
}

const facetCuts: Array<IMMDiamondCut.FacetCutStruct> = [];
const replaceSelectors: Array<string> = [];
const addSelectors: Array<string> = [];
const removeSelectors: Array<string> = [];
const functionSelectors = getSelectors(contractFactory);
// Loop through each selector to find out if it needs to replace or add
for (const selector of functionSelectors) {
if (existedFacetCuts.includes(selector)) {
replaceSelectors.push(selector);
} else {
addSelectors.push(selector);
}
}
// Loop through existed facet cuts to find out selectors to remove
for (const selector of previousFacet.functionSelectors) {
if (!functionSelectors.includes(selector)) {
removeSelectors.push(selector);
}
}

console.log(`> Build the facetCuts array from ${FACET} contract`);
// Put the replaceSelectors and addSelectors into facetCuts
if (replaceSelectors.length > 0) {
facetCuts.push({
facetAddress,
action: FacetCutAction.Replace,
functionSelectors: replaceSelectors,
});
}
if (addSelectors.length > 0) {
facetCuts.push({
facetAddress,
action: FacetCutAction.Add,
functionSelectors: addSelectors,
});
}
if (removeSelectors.length > 0) {
// Get the old facet address based on the selector
facetCuts.push({
facetAddress: ethers.constants.AddressZero,
action: FacetCutAction.Remove,
functionSelectors: removeSelectors,
});
}

console.log(`> Found ${replaceSelectors.length} selectors to replace`);
console.log(`> Methods to replace:`);
console.table(
replaceSelectors.map((each) => {
return {
functionName: contractFactory.interface.getFunction(each).name,
selector: each,
};
})
);
console.log(`> Found ${addSelectors.length} selectors to add`);
console.log(`> Methods to add:`);
console.table(
addSelectors.map((each) => {
return {
functionName: contractFactory.interface.getFunction(each).name,
selector: each,
};
})
);
console.log(`> Found ${removeSelectors.length} selectors to remove`);
console.log(`> Methods to remove:`);
console.table(
removeSelectors.map((each) => {
return {
functionName: "unknown (TODO: integrate with 4bytes dictionary)",
selector: each,
};
})
);

// Ask for confirmation
const confirmExecuteDiamondCut = readlineSync.question("Confirm? (y/n): ");
switch (confirmExecuteDiamondCut.toLowerCase()) {
case "y":
break;
case "n":
console.log("Aborting");
return;
default:
console.log("Invalid input");
return;
}

console.log("> Executing diamond cut");
const tx = await diamondCutFacet.diamondCut(facetCuts, INITIALIZER_ADDRESS, "0x", { gasLimit: 10000000 });
console.log(`> Tx is submitted: ${tx.hash}`);
console.log(`> Waiting for tx to be mined`);
await tx.wait();
console.log(`> Tx is mined`);
};

export default func;
func.tags = ["ExecuteDiamondCut"];
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Config, Market, MiniFLPool } from "../interfaces";
import { Config, Market, MiniFLPool, Rewarder } from "../interfaces";
import MainnetConfig from "../../.mainnet.json";
import * as fs from "fs";

Expand All @@ -20,6 +20,25 @@ export class ConfigFileHelper {
this._writeConfigFile(this.config);
}

public setMiniFLPoolRewarders(pid: number, rewarderAddresses: string[]): void {
const miniFLPool = this.config.miniFL.pools.find((pool) => pool.id === Number(pid))!;

const rewarders = rewarderAddresses.map(
(rewarder) => this.config.rewarders.find((configRewarder) => configRewarder.address === rewarder)!
);
miniFLPool.rewarders = rewarders;
this._writeConfigFile(this.config);
}

public addRewarder(rewarder: Rewarder): void {
this.config.rewarders.push(rewarder);
this._writeConfigFile(this.config);
}

public getConfig() {
return this.config;
}

private _writeConfigFile(config: Config) {
console.log(`>> Writing ${this.filePath}`);
fs.writeFileSync(this.filePath, JSON.stringify(config, null, 2));
Expand Down
23 changes: 22 additions & 1 deletion type-script/interfaces.ts → deploy/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
export interface Config {
moneyMarket: MoneyMarket;
miniFL: MiniFL;
rewarders: Rewarder[];
}

export interface MoneyMarket {
moneyMarketDiamond: string;
facets: {
adminFacet: string;
borrowFacet: string;
collateralFacet: string;
diamondCutFacet: string;
diamondLoupeFacet: string;
flashloanFacet: string;
lendFacet: string;
liquidationFacet: string;
nonCollatBorrowFacet: string;
ownershipFacet: string;
viewFacet: string;
};
markets: Market[];
}

Expand All @@ -24,7 +39,13 @@ export interface MiniFLPool {
id: number;
name: string;
stakingToken: string;
rewarders: string[];
rewarders: Rewarder[];
}

export interface Rewarder {
name: string;
address: string;
rewardToken: string;
}

export type AssetTier = 0 | 1 | 2 | 3;
Expand Down
26 changes: 26 additions & 0 deletions deploy/utils/deployer-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { ethers, network } from "hardhat";
import { JsonRpcProvider } from "@ethersproject/providers";
import { HttpNetworkUserConfig } from "hardhat/types";

export async function getDeployer(): Promise<SignerWithAddress> {
const [defaultDeployer] = await ethers.getSigners();

if (isFork()) {
const provider = ethers.getDefaultProvider((network.config as HttpNetworkUserConfig).url) as JsonRpcProvider;
const signer = provider.getSigner("0xC44f82b07Ab3E691F826951a6E335E1bC1bB0B51");
const mainnetForkDeployer = await SignerWithAddress.create(signer);

return mainnetForkDeployer;
}

return defaultDeployer;
}

export function isFork() {
const networkUrl = (network.config as HttpNetworkUserConfig).url;
if (networkUrl) {
return networkUrl.indexOf("https://rpc.tenderly.co/fork/") !== -1;
}
throw new Error("invalid Network Url");
}
23 changes: 23 additions & 0 deletions deploy/utils/diamond.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ContractFactory } from "ethers";
import _ from "lodash";
import { ConfigFileHelper } from "../file-helper.ts/config-file.helper";

export function getSelectors(contract: ContractFactory): Array<string> {
const signatures = Object.keys(contract.interface.functions);
const selectors = signatures.reduce((acc, val) => {
acc.push(contract.interface.getSighash(val));
return acc;
}, [] as Array<string>);
return selectors;
}

export function facetContractNameToAddress(contractName: string): string {
const config = new ConfigFileHelper().getConfig();
const facetList = config.moneyMarket.facets as any;
contractName = _.camelCase(contractName);
const address = facetList[contractName];
if (!address) {
throw new Error(`${contractName} not found in config`);
}
return address;
}
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ optimizer = true
optimizer-runs = 1
src = 'solidity/contracts'
out = 'out'
cache_path = './forge_cache'
libs = ['node_modules']
test = 'solidity/tests'
fs_permissions = [{ access = "read-write", path = "./" }]
Expand Down
19 changes: 11 additions & 8 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { config as dotEnvConfig } from "dotenv";
import { HardhatUserConfig } from "hardhat/config";
dotEnvConfig();

import "@openzeppelin/hardhat-upgrades";
import "@nomiclabs/hardhat-ethers";
import "@typechain/hardhat";
import "hardhat-deploy";

module.exports = {
const config: HardhatUserConfig = {
defaultNetwork: "hardhat",
networks: {
// rinkeby: {
// url: process.env.RINKEBY_RPC,
// accounts:
// process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [],
// },
bsc_mainnet: {
chainId: 56,
url: process.env.BSC_RPC_URL,
accounts: process.env.DEPLOYER_PRIVATE_KEY !== undefined ? [process.env.DEPLOYER_PRIVATE_KEY] : [],
},
},
solidity: {
version: "0.8.19",
Expand All @@ -21,7 +23,6 @@ module.exports = {
enabled: true,
runs: 1,
},
evmVersion: "istanbul",
},
},
paths: {
Expand All @@ -32,9 +33,11 @@ module.exports = {
},
typechain: {
outDir: "./typechain",
target: process.env.TYPECHAIN_TARGET || "ethers-v5",
target: "ethers-v5",
},
mocha: {
timeout: 100000,
},
};

export default config;
Loading

0 comments on commit 92efda4

Please sign in to comment.