diff --git a/README.md b/README.md index 48768b77..c420bb4a 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,17 @@ - Aavegotchi KEK ERC20 - 0x42E5E06EF5b90Fe15F853F59299Fc96259209c5C - Link: https://louper.dev/diamond/0x1D0360BaC7299C86Ec8E99d0c1C9A95FEfaF2a11?network=polygon +### Amoy + +- Realm Diamond deployed: 0x5a4faEb79951bAAa0866B72fD6517E693c8E4620 +- InstallationDiamond deployed: 0x514b7c55FB3DFf3533B58D85CD25Ba04bb30612D +- Tile Diamond deployed: 0xCa6F4Ef19a1Beb9BeF12f64b395087E5680bcB22 +- FUD deployed: 0xaa1C59f2B45EF192B71De7d0CB5d95b664749d9c +- FOMO deployed: 0x616d6Df54A9754B81aa43971794D86B3C229fA8B +- ALPHA deployed: 0x44bca9B7C2C5F9f47D4da5B72deCdcF3a42535d8 +- KEK deployed: 0x9b39452041aCe85C03D3Ae76D0D5ccFf3a86dEc9 +- GLTR deployed: 0x7E4CB2bc361898bB17C8D847032676A7Fd23D625 + ### Mumbai - TileDiamond: 0x0aB1547B21D81eB3af1712c0BD8ac21c0c1219a9 diff --git a/constants.ts b/constants.ts index 884d9799..0e31da64 100644 --- a/constants.ts +++ b/constants.ts @@ -90,7 +90,7 @@ const networkToVars: NetworkToConstants = { 100: maticVars, //update }; -export const gasPrice = 175000000000; +export const gasPrice = 5000000000; export const aavegotchiDAOAddress = "0xb208f8BB431f580CC4b216826AFfB128cd1431aB"; diff --git a/hardhat.config.ts b/hardhat.config.ts index c91a9e0b..470650ec 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -61,10 +61,9 @@ module.exports = { maxPriorityFeePerGas: 1 * GWEI, // timeout: 90000 }, - mumbai: { - url: process.env.MUMBAI_MORALIS, + amoy: { + url: process.env.AMOY_URL, accounts: [process.env.SECRET], - blockGasLimit: 20000000, // gasPrice: 1000000000, }, kovan: { diff --git a/scripts/deployAll.ts b/scripts/deployAll.ts new file mode 100644 index 00000000..450bb55a --- /dev/null +++ b/scripts/deployAll.ts @@ -0,0 +1,342 @@ +//@ts-ignore +import { Signer } from "@ethersproject/abstract-signer"; +import { ethers } from "hardhat"; +import { + DiamondCutFacet, + DiamondInit__factory, + Diamond__factory, + OwnershipFacet, + AlchemicaFacet, + InstallationAdminFacet, + TileFacet, + RealmGettersAndSettersFacet, + VRFFacet, +} from "../typechain"; +import { gasPrice } from "../constants"; +import { + deployAlchemica, + outputInstallation, + outputTile, +} from "./realm/realmHelpers"; +import { + alchemicaTotals, + boostMultipliers, + greatPortalCapacity, +} from "./setVars"; +import { deployDiamond } from "./installation/deploy"; +import { deployDiamondTile } from "./tile/deploy"; +import { installationTypes as mainInstallationTypes } from "../data/installations/installationTypes"; +import { installationTypes as farmingInstallationTypes } from "../data/installations/farming"; +import { installationTypes as nftInstallationTypes } from "../data/installations/nftDisplay"; +import { installationTypes as bounceGateInstallationTypes } from "../data/installations/bounceGate"; +import { installationTypes as halloweenInstallationTypes } from "../data/installations/halloween"; +import { installationTypes as xmasInstallationTypes } from "../data/installations/xmas"; +import { installationTypes as nftBigInstallationTypes } from "../data/installations/nftDisplay_big"; +import { tileTypes } from "../data/tiles/tileTypes"; + +const { getSelectors, FacetCutAction } = require("./libraries/diamond.js"); + +interface Diamond { + address: string; +} + +async function deployRealmDiamond(deployerAddress: string) { + // deploy DiamondCutFacet + const DiamondCutFacet = await ethers.getContractFactory("DiamondCutFacet"); + + console.log("Deploying diamond cut facet:"); + const diamondCutFacet = await DiamondCutFacet.deploy({ + gasPrice: gasPrice, + }); + await diamondCutFacet.deployed(); + console.log("DiamondCutFacet deployed:", diamondCutFacet.address); + + // deploy Diamond + const Diamond = (await ethers.getContractFactory( + "Diamond" + )) as Diamond__factory; + const diamond = await Diamond.deploy( + deployerAddress, + diamondCutFacet.address, + { gasPrice: gasPrice } + ); + await diamond.deployed(); + console.log("Diamond deployed:", diamond.address); + + // deploy DiamondInit + const DiamondInit = (await ethers.getContractFactory( + "DiamondInit" + )) as DiamondInit__factory; + const diamondInit = await DiamondInit.deploy({ gasPrice: gasPrice }); + await diamondInit.deployed(); + console.log("DiamondInit deployed:", diamondInit.address); + + // deploy facets + console.log(""); + console.log("Deploying facets"); + const FacetNames = [ + "DiamondLoupeFacet", + "OwnershipFacet", + "ERC721Facet", + "RealmFacet", + "RealmGettersAndSettersFacet", + "RealmGridFacet", + "AlchemicaFacet", + "BounceGateFacet", + "NFTDisplayFacet", + "VRFFacet", + ]; + const cut = []; + for (const FacetName of FacetNames) { + const Facet = await ethers.getContractFactory(FacetName); + const facet = await Facet.deploy({ + gasPrice: gasPrice, + }); + await facet.deployed(); + console.log(`${FacetName} deployed: ${facet.address}`); + cut.push({ + facetAddress: facet.address, + action: FacetCutAction.Add, + functionSelectors: getSelectors(facet), + }); + } + + const diamondCut = (await ethers.getContractAt( + "IDiamondCut", + diamond.address + )) as DiamondCutFacet; + + // call to init function + const functionCall = diamondInit.interface.encodeFunctionData("init"); + const tx = await diamondCut.diamondCut( + cut, + diamondInit.address, + functionCall, + { gasPrice: gasPrice } + ); + console.log("Diamond cut tx: ", tx.hash); + const receipt = await tx.wait(); + if (!receipt.status) { + throw Error(`Diamond upgrade failed: ${tx.hash}`); + } + console.log("Completed diamond cut"); + + const ownershipFacet = (await ethers.getContractAt( + "OwnershipFacet", + diamond.address + )) as OwnershipFacet; + const diamondOwner = await ownershipFacet.owner(); + console.log("Diamond owner is:", diamondOwner); + + if (diamondOwner !== deployerAddress) { + throw new Error( + `Diamond owner ${diamondOwner} is not deployer address ${deployerAddress}!` + ); + } + + return diamond as Diamond; +} + +export async function deploy() { + const accounts: Signer[] = await ethers.getSigners(); + const deployer = accounts[0]; + + // Constants + // TODO: Confirm + const vrfCoordinator = ethers.constants.AddressZero; + const linkAddress = ethers.constants.AddressZero; + const aavegotchiDiamond = ethers.constants.AddressZero; + const backendSigner = new ethers.Wallet(process.env.MUMBAI_REALM_PK); // PK should start with '0x' + const deployerAddress = await deployer.getAddress(); + const pixelcraft = deployerAddress; + const dao = deployerAddress; + const requestConfig = { + subId: 114, + callbackGasLimit: 500_000, + requestConfirmations: 32, + numWords: 4, + keyHash: + "0x6e099d640cde6de9d40ac749b4b594126b0169747122711109c9985d47751f93", + }; + + console.log("Deployer:", deployerAddress); + + console.log("\nDeploying Realm Diamond"); + const realmDiamond = await deployRealmDiamond(deployerAddress); + + console.log("\nDeploying Installation Diamond"); + const installationDiamond = await deployDiamond(realmDiamond.address); + + console.log("\nDeploying Tile Diamond"); + const tileDiamond = await deployDiamondTile(realmDiamond.address); + + console.log("\nDeploying Alchemicas"); + const alchemica = await deployAlchemica(ethers, realmDiamond.address); + + console.log("Realm Diamond deployed:", realmDiamond.address); + console.log("InstallationDiamond deployed:", installationDiamond); + console.log("Tile Diamond deployed:", tileDiamond); + console.log("FUD deployed:", alchemica.fud.address); + console.log("FOMO deployed:", alchemica.fomo.address); + console.log("ALPHA deployed:", alchemica.alpha.address); + console.log("KEK deployed:", alchemica.kek.address); + console.log("GLTR deployed:", alchemica.gltr.address); + + //@ts-ignore + const alchemicaFacet = (await ethers.getContractAt( + "AlchemicaFacet", + realmDiamond.address, + deployer + )) as AlchemicaFacet; + + console.log("Setting vars for realm diamond"); + let tx = await alchemicaFacet.setVars( + //@ts-ignore + alchemicaTotals(), + boostMultipliers, + greatPortalCapacity, + installationDiamond, + vrfCoordinator, + linkAddress, + [ + alchemica.fud.address, + alchemica.fomo.address, + alchemica.alpha.address, + alchemica.kek.address, + ], + alchemica.gltr.address, + ethers.utils.hexDataSlice(backendSigner.publicKey, 1), + deployerAddress, + tileDiamond, + aavegotchiDiamond, + { gasPrice: gasPrice } + ); + await tx.wait(); + + console.log("Setting channeling Limits in realm diamond"); + tx = await alchemicaFacet.setChannelingLimits( + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [ + 24 * 3600, + 18 * 3600, + 12 * 3600, + 8 * 3600, + 6 * 3600, + 4 * 3600, + 3 * 3600, + 2 * 3600, + 3600, + ], + { gasPrice: gasPrice } + ); + await tx.wait(); + + const vrfFacet = (await ethers.getContractAt( + "VRFFacet", + realmDiamond.address, + deployer + )) as VRFFacet; + + console.log("Setting VRF configs in realm diamond"); + tx = await vrfFacet.setConfig(requestConfig, vrfCoordinator, { + gasPrice: gasPrice, + }); + await tx.wait(); + + const realmGettersAndSettersFacet = (await ethers.getContractAt( + "RealmGettersAndSettersFacet", + realmDiamond.address, + deployer + )) as RealmGettersAndSettersFacet; + + console.log("Setting game active in realm diamond"); + tx = await realmGettersAndSettersFacet.setGameActive(true, { + gasPrice: gasPrice, + }); + await tx.wait(); + + const installationAdminFacet = (await ethers.getContractAt( + "InstallationAdminFacet", + installationDiamond, + deployer + )) as InstallationAdminFacet; + + console.log("Setting addresses for installation diamond"); + tx = await installationAdminFacet.setAddresses( + aavegotchiDiamond, + realmDiamond.address, + alchemica.gltr.address, + pixelcraft, + dao, + ethers.utils.hexDataSlice(backendSigner.publicKey, 1) + ); + await tx.wait(); + + console.log("Adding installation types"); + const installationTypes = [ + mainInstallationTypes, + farmingInstallationTypes, + nftInstallationTypes, + bounceGateInstallationTypes, + halloweenInstallationTypes, + xmasInstallationTypes, + nftBigInstallationTypes, + ]; + for (let i = 0; i < installationTypes.length; i++) { + tx = await installationAdminFacet.addInstallationTypes( + installationTypes[i].map((val) => outputInstallation(val)), + { + gasPrice: gasPrice, + } + ); + await tx.wait(); + } + + // const installationFacet = (await ethers.getContractAt( + // "InstallationFacet", + // installationDiamond, + // signers[0] + // )) as InstallationFacet; + // const installationTypes = await installationFacet.getInstallationTypes([]); + // console.log("Saved installationTypes:", installationTypes); + + const tileFacet = (await ethers.getContractAt( + "TileFacet", + tileDiamond, + deployer + )) as TileFacet; + + console.log("Setting addresses for tile diamond"); + tx = await tileFacet.setAddresses( + aavegotchiDiamond, + realmDiamond.address, + alchemica.gltr.address, + pixelcraft, + dao + ); + await tx.wait(); + + console.log("Adding tile types"); + tx = await tileFacet.addTileTypes( + tileTypes.map((val) => outputTile(val)), + { + gasPrice: gasPrice, + } + ); + await tx.wait(); + // const tileTypes = await tileFacet.getTileTypes([]); + // console.log("Saved tileTypes:", tileTypes); + + return realmDiamond.address; +} + +// We recommend this pattern to be able to use async/await everywhere +// and properly handle errors. +if (require.main === module) { + deploy() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); +} diff --git a/scripts/helperFunctions.ts b/scripts/helperFunctions.ts index ef98bf4d..2a8380d3 100644 --- a/scripts/helperFunctions.ts +++ b/scripts/helperFunctions.ts @@ -9,8 +9,6 @@ import { DefenderRelaySigner, } from "defender-relay-client/lib/ethers"; -export const gasPrice = 75000000000; - export async function getDiamondSigner( diamondAddress: string, ethers: HardhatEthersHelpers, diff --git a/scripts/installation/deploy.ts b/scripts/installation/deploy.ts index 5e45a78c..647dc091 100644 --- a/scripts/installation/deploy.ts +++ b/scripts/installation/deploy.ts @@ -7,13 +7,14 @@ import { InstallationDiamond__factory, OwnershipFacet, } from "../../typechain"; -import { gasPrice, maticRealmDiamondAddress } from "./helperFunctions"; +import { gasPrice } from "../../constants"; +import { maticRealmDiamondAddress } from "../tile/helperFunctions"; // import {getSelectors, FacetCutAction} from '../libraries/diamond' const { getSelectors, FacetCutAction } = require("../libraries/diamond"); -export async function deployDiamond() { +export async function deployDiamond(realmDiamondAddress) { const accounts: Signer[] = await ethers.getSigners(); const deployer = accounts[0]; const deployerAddress = await deployer.getAddress(); @@ -34,7 +35,7 @@ export async function deployDiamond() { const diamond = await Diamond.deploy( deployerAddress, diamondCutFacet.address, - maticRealmDiamondAddress, + realmDiamondAddress, { gasPrice: gasPrice } ); await diamond.deployed(); @@ -56,6 +57,7 @@ export async function deployDiamond() { "OwnershipFacet", "InstallationFacet", "InstallationAdminFacet", + "InstallationUpgradeFacet", "ERC1155Facet", ]; const cut = []; @@ -112,7 +114,7 @@ export async function deployDiamond() { // We recommend this pattern to be able to use async/await everywhere // and properly handle errors. if (require.main === module) { - deployDiamond() + deployDiamond(maticRealmDiamondAddress) .then(() => process.exit(0)) .catch((error) => { console.error(error); diff --git a/scripts/installation/helperFunctions.ts b/scripts/installation/helperFunctions.ts index 8a6548f9..6155de28 100644 --- a/scripts/installation/helperFunctions.ts +++ b/scripts/installation/helperFunctions.ts @@ -3,8 +3,6 @@ import { HardhatEthersHelpers } from "hardhat/types"; import { varsForNetwork } from "../../constants"; import { DiamondLoupeFacet } from "../../typechain"; -export const gasPrice = 180000000000; - export async function impersonate( address: string, contract: any, diff --git a/scripts/realm/realmHelpers.ts b/scripts/realm/realmHelpers.ts index ef1fc6b6..05a94861 100644 --- a/scripts/realm/realmHelpers.ts +++ b/scripts/realm/realmHelpers.ts @@ -11,6 +11,7 @@ import { } from "../../types"; import { impersonate } from "../installation/helperFunctions"; +import { gasPrice } from "../../constants"; export function outputInstallation( installation: InstallationTypeInput @@ -29,7 +30,7 @@ export function outputInstallation( //Altar spilloverRate is parsed in 2 units, reservoirs are parsed in 4 const isAltar = installation.id <= 18 ? true : false; - console.log("spill rate:", installation.spillRate.toString()); + // console.log("spill rate:", installation.spillRate.toString()); let output: InstallationTypeOutput = { deprecated: installation.deprecated, @@ -80,7 +81,7 @@ export function outputTile(tile: TileTypeInput): TileTypeOutput { ], craftTime: tile.craftTime, name: tile.name, - deprecateTime: tile.deprecateTime, + deprecateTime: tile.deprecateTime ? tile.deprecateTime : 0, }; return output; @@ -92,6 +93,68 @@ export function outputTiles(tiles: TileTypeInput[]): TileTypeOutput[] { return output; } +export async function deployAlchemica(ethers: any, diamondAddress: string) { + const Fud = await ethers.getContractFactory("AlchemicaToken"); + let fud = (await Fud.deploy({ + gasPrice: gasPrice, + })) as AlchemicaToken; + const Fomo = await ethers.getContractFactory("AlchemicaToken"); + let fomo = (await Fomo.deploy({ + gasPrice: gasPrice, + })) as AlchemicaToken; + const Alpha = await ethers.getContractFactory("AlchemicaToken"); + let alpha = (await Alpha.deploy({ + gasPrice: gasPrice, + })) as AlchemicaToken; + const Kek = await ethers.getContractFactory("AlchemicaToken"); + let kek = (await Kek.deploy({ + gasPrice: gasPrice, + })) as AlchemicaToken; + await fud.initialize( + "FUD", + "FUD", + ethers.utils.parseUnits("1000000000000"), + diamondAddress, + diamondAddress, + diamondAddress + ); + await fomo.initialize( + "FOMO", + "FOMO", + ethers.utils.parseUnits("250000000000"), + diamondAddress, + diamondAddress, + diamondAddress + ); + await alpha.initialize( + "ALPHA", + "ALPHA", + ethers.utils.parseUnits("125000000000"), + diamondAddress, + diamondAddress, + diamondAddress + ); + await kek.initialize( + "KEK", + "KEK", + ethers.utils.parseUnits("100000000000"), + diamondAddress, + diamondAddress, + diamondAddress + ); + + const Glmr = await ethers.getContractFactory("GLTR"); + let gltr = (await Glmr.deploy()) as GLTR; + + return { + fud, + fomo, + alpha, + kek, + gltr, + }; +} + const backendSigner = () => { //@ts-ignore return new ethers.Wallet(process.env.PROD_PK); // PK should start with '0x' diff --git a/scripts/tile/deploy.ts b/scripts/tile/deploy.ts index 8a67e8f6..fb86ac3e 100644 --- a/scripts/tile/deploy.ts +++ b/scripts/tile/deploy.ts @@ -7,13 +7,14 @@ import { TileDiamond__factory, OwnershipFacet, } from "../../typechain"; -import { gasPrice, maticRealmDiamondAddress } from "./helperFunctions"; +import { maticRealmDiamondAddress } from "./helperFunctions"; +import { gasPrice } from "../../constants"; // import {getSelectors, FacetCutAction} from '../libraries/diamond' const { getSelectors, FacetCutAction } = require("../libraries/diamond"); -export async function deployDiamondTile() { +export async function deployDiamondTile(realmDiamondAddress) { const accounts: Signer[] = await ethers.getSigners(); const deployer = accounts[0]; const deployerAddress = await deployer.getAddress(); @@ -34,7 +35,7 @@ export async function deployDiamondTile() { const diamond = await Diamond.deploy( deployerAddress, diamondCutFacet.address, - maticRealmDiamondAddress, + realmDiamondAddress, { gasPrice: gasPrice } ); await diamond.deployed(); @@ -55,7 +56,7 @@ export async function deployDiamondTile() { "DiamondLoupeFacet", "OwnershipFacet", "TileFacet", - "ERC1155FacetTile", + "ERC1155TileFacet", ]; const cut = []; for (const FacetName of FacetNames) { @@ -111,7 +112,7 @@ export async function deployDiamondTile() { // We recommend this pattern to be able to use async/await everywhere // and properly handle errors. if (require.main === module) { - deployDiamondTile() + deployDiamondTile(maticRealmDiamondAddress) .then(() => process.exit(0)) .catch((error) => { console.error(error); diff --git a/scripts/tile/helperFunctions.ts b/scripts/tile/helperFunctions.ts index e28766a6..edb3ec9c 100644 --- a/scripts/tile/helperFunctions.ts +++ b/scripts/tile/helperFunctions.ts @@ -1,8 +1,6 @@ import { Contract } from "@ethersproject/contracts"; import { DiamondLoupeFacet } from "../../typechain"; -export const gasPrice = 900000000000; - export async function impersonate( address: string, contract: any,