Skip to content

Commit

Permalink
update deploy scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
chimera-defi committed Jul 2, 2024
1 parent f5a6ead commit 7029195
Show file tree
Hide file tree
Showing 13 changed files with 351 additions and 37 deletions.
5 changes: 5 additions & 0 deletions contracts/v2/core/SharedDepositMinterV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ import {Address} from "@openzeppelin/contracts/utils/Address.sol";

import {ETH2DepositWithdrawalCredentials} from "../lib/ETH2DepositWithdrawalCredentials.sol";

/// @title SharedDepositMinterV2
/// @author ChimeraDefi - [email protected] | sharedstake.org
/// @notice Mints LSD tokens for ETH deposited to the contract. Handles the depositing of ETH to the ETH2 deposit contract and validator creation
/// @dev Deployment params:
/// - addresses : [feeCalc, sgeth, wsgeth, gov]
contract SharedDepositMinterV2 is AccessControl, Pausable, ReentrancyGuard, ETH2DepositWithdrawalCredentials {
/* ========== STATE VARIABLES ========== */
uint256 public adminFee;
Expand Down
2 changes: 1 addition & 1 deletion contracts/v2/core/WithdrawalQueue.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {SharedDepositMinterV2} from "./SharedDepositMinterV2.sol";
* 3. Fulfill any remaining redeemRequests i.e. totalPendingRequest,
* for all RedeemRequest events from requestsFulfilled to requestsCreated
*/
contract WithdrawalQueue is AccessControl, GranularPause, ReentrancyGuard, FIFOQueue, OperatorSettable {
contract WithdrawalQueue is AccessControl, ReentrancyGuard, GranularPause, FIFOQueue, OperatorSettable {
using Address for address payable;

struct Request {
Expand Down
4 changes: 2 additions & 2 deletions contracts/v2/periphery/FeeCalc.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ contract FeeCalc is Ownable2Step {
config.adminFee = amount;
}

function processDeposit(uint256 value, address sender) external view returns (uint256 amt, uint256 fee) {
function processDeposit(uint256 value, address _sender) external view returns (uint256 amt, uint256 fee) {

Check failure on line 44 in contracts/v2/periphery/FeeCalc.sol

View workflow job for this annotation

GitHub Actions / build (20.x)

Variable "_sender" is unused
// TODO: semder is currently unsused but can be used later to calculate a fee reduction based on token holdings
if (config.chargeOnDeposit) {
fee = (value * adminFee) / BIPS;
amt = value - fee;
}
}

function processWithdraw(uint256 value, address sender) external view returns (uint256 amt, uint256 fee) {
function processWithdraw(uint256 value, address _sender) external view returns (uint256 amt, uint256 fee) {

Check failure on line 52 in contracts/v2/periphery/FeeCalc.sol

View workflow job for this annotation

GitHub Actions / build (20.x)

Variable "_sender" is unused
// TODO: semder is currently unsused but can be used later to calculate a fee reduction based on token holdings
if (config.refundFeesOnWithdraw) {
fee = (value * adminFee) / BIPS;
Expand Down
2 changes: 1 addition & 1 deletion deploy/03_paymentSplitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const func: DeployFunction = async hre => {
const multiSig = hre.network.tags.hardhat ? accounts.multiSig.address : "0x610c92c70eb55dfeafe8970513d13771da79f2e0";

const splitterAddresses = [accounts.deployer.address, multiSig, wsgEth.target];
const splitterValues = [6, 3, 31];
const splitterValues = [60, 30, 910]; // deploy splitter, with 1k total shares. 9% total fees - 6% for deployer, 3% for multisig, 91% for stakers.

await deploy(PaymentSplitter__factory, {
args: [splitterAddresses, splitterValues],
Expand Down
21 changes: 16 additions & 5 deletions deploy/04_minter.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import {DeployFunction} from "hardhat-deploy/types";
import Ship from "../utils/ship";
import {SgETH, SgETH__factory, SharedDepositMinterV2__factory, WSGETH, WSGETH__factory} from "../types";
import {SgETH, SgETH__factory, SharedDepositMinterV2__factory, WSGETH, WSGETH__factory, DepositContract, DepositContract__factory, FeeCalc, FeeCalc__factory} from "../types";
import {ZeroAddress} from "ethers";

const func: DeployFunction = async hre => {
const {deploy, connect, accounts} = await Ship.init(hre);

const sgEth = (await connect(SgETH__factory)) as SgETH;
const wsgEth = (await connect(WSGETH__factory)) as WSGETH;
const feeCalc = (await connect(FeeCalc__factory)) as FeeCalc;

let chainId = await hre.getChainId();

let depositContractAddr;
if ( chainId != '1') {
let depositContract = (await connect(DepositContract__factory)) as DepositContract;
depositContractAddr = depositContract.target;
} else {
depositContractAddr = "0x00000000219ab540356cBB839Cbe05303d7705Fa";
}

const numValidators = 1000;
const adminFee = 0;
Expand All @@ -19,12 +30,12 @@ const func: DeployFunction = async hre => {
// await feeCalc.deployed();

const addresses = [
ZeroAddress,
//feeCalc.address, // fee splitter
// ZeroAddress,
feeCalc.target, // fee splitter
sgEth.target, // sgETH address
wsgEth.target, // wsgETH address
multiSig, // government address
ZeroAddress, // deposit contract address - can't find deposit contract - using dummy address
depositContractAddr, // deposit contract address - can't find deposit contract - using dummy address
];

const minter = await deploy(SharedDepositMinterV2__factory, {
Expand All @@ -40,4 +51,4 @@ const func: DeployFunction = async hre => {

export default func;
func.tags = ["minter"];
func.dependencies = ["sgEth", "wsgEth"];
func.dependencies = ["sgEth", "wsgEth", "depositContract", "feeCalc"];
20 changes: 20 additions & 0 deletions deploy/04a_depositContract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {DeployFunction} from "hardhat-deploy/types";
import Ship from "../utils/ship";
import {DepositContract__factory} from "../types";

/**
*
* This only needs to be deployed on testnets like sepolia which do not have a deposit contract.
* Do not deploy on mainnet
*/
const func: DeployFunction = async hre => {
const {deploy} = await Ship.init(hre);

const dc = await deploy(DepositContract__factory, {
args: [],
});
};

export default func;
func.tags = ["depositContract"];
func.dependencies = [];
25 changes: 25 additions & 0 deletions deploy/04b_feeCalc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {DeployFunction} from "hardhat-deploy/types";
import Ship from "../utils/ship";
import {FeeCalc__factory} from "../types";

/**
*
* This only needs to be deployed on testnets like sepolia which do not have a deposit contract.
*/
const func: DeployFunction = async hre => {
const {deploy} = await Ship.init(hre);

const fc = await deploy(FeeCalc__factory, {
args: [{
adminFee : 10,
exitFee : 0,
refundFeesOnWithdraw : true,
chargeOnDeposit : true,
chargeOnExit : false,
}],
});
};

export default func;
func.tags = ["feeCalc"];
func.dependencies = [];
16 changes: 16 additions & 0 deletions deploy/06_rewardsReceiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Ship from "../utils/ship";
import {
PaymentSplitter,
PaymentSplitter__factory,
RewardsReceiver,
RewardsReceiver__factory,
SgETH,
SgETH__factory,
Expand All @@ -14,6 +15,18 @@ import {
WithdrawalQueue__factory,
} from "../types";

function makeWithdrawalCred(params: any) {
// see https://github.com/ethereum/consensus-specs/pull/2149/files & https://github.com/stakewise/contracts/blob/0e51a35e58676491060df84d665e7ebb0e735d17/test/pool/depositDataMerkleRoot.js#L140
// pubkey is 0x01 + (11 bytes?) 20 0s + eth1 addr 20 bytes (40 characters) ? = final length 66
//
let withdrawalCredsPrefix = `0x010000000000000000000000`;
let eth1Withdraw = `${withdrawalCredsPrefix}${params.split("x")[1]}`;
console.log(`setWithdrawalCredential ${eth1Withdraw}`);

return eth1Withdraw;
}


const func: DeployFunction = async hre => {
const {deploy, connect} = await Ship.init(hre);

Expand All @@ -26,6 +39,9 @@ const func: DeployFunction = async hre => {
await deploy(RewardsReceiver__factory, {
args: [withdrawalQueue.target, [sgEth.target, wsgEth.target, paymentSplitter.target, minter.target]],
});

let rr = (await connect(RewardsReceiver__factory)) as RewardsReceiver;
await minter.setWithdrawalCredential(makeWithdrawalCred(rr.target));
};

export default func;
Expand Down
9 changes: 7 additions & 2 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,15 @@ const MAINNET_PRIVATE_KEY = process.env.MAINNET_PRIVATE_KEY ? process.env.MAINNE
const ETHERSCAN_API = process.env.ETHERSCAN_API ? process.env.ETHERSCAN_API : false;

const ALCHEMY_SEPOLIA_KEY = process.env.ALCHEMY_SEPOLIA_KEY ? process.env.ALCHEMY_SEPOLIA_KEY : "";
const SEPOLIA_RPC_URL = `https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_SEPOLIA_KEY}`;
const SEPOLIA_RPC_URL = process.env.SEPOLIA_RPC_URL
? process.env.SEPOLIA_RPC_URL
: `https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_SEPOLIA_KEY}`;

const SEPOLIA_PRIVATE_KEY = process.env.SEPOLIA_PRIVATE_KEY ? process.env.SEPOLIA_PRIVATE_KEY : GOERLIPK;

const ACTIVE_DEPLOYER_PK = SEPOLIA_PRIVATE_KEY ? SEPOLIA_PRIVATE_KEY : (MAINNET_PRIVATE_KEY ? MAINNET_PRIVATE_KEY : GOERLIPK);
// const ACTIVE_DEPLOYER_PK = GOERLIPK;

// END required user input

const path = require("path");
Expand Down Expand Up @@ -156,7 +161,7 @@ const config: HardhatUserConfig = {
target: "ethers-v6",
},
namedAccounts: {
deployer: 0,
deployer: `privatekey://0x${ACTIVE_DEPLOYER_PK}`,
multiSig: 1,
alice: 3,
bob: 4,
Expand Down
34 changes: 17 additions & 17 deletions scripts/v2/1_deploy_minterv2.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ async function main() {
let wsgETHAddr = dh.addressOf(wsgETH);
params.wsgETH = wsgETHAddr;


await dh.deployContract("FeeCalc", "FeeCalc", [{
adminFee: 10,
exitFee: 0,
refundFeesOnWithdraw: true,
chargeOnDeposit: true,
chargeOnExit: false
}]);
await dh.deployContract("FeeCalc", "FeeCalc", [
{
adminFee: 10,
exitFee: 0,
refundFeesOnWithdraw: true,
chargeOnDeposit: true,
chargeOnExit: false,
},
]);
params.feeCalcAddr = dh.addressOf("FeeCalc");


await deployMinterV2(dh, params);
let minter = dh.addressOf(params.names.minter);
Expand Down Expand Up @@ -126,14 +126,14 @@ async function main() {
// test deposit withdraw flow
await dh.e2e(params);

// starting sgeth bal 0.0
// Deposited Eth, got sgETH: 0.01 0.01
// new sgETH bal post withdraw 0.0
// warmed up deposit/withdraw
// starting wsgeth bal 0.0
// Staked Eth, got wsgETH: 0.01 0.01
// Unstaked wsgETH, new wsgETH bal: 0.005
// warmed up stake/unstake
// starting sgeth bal 0.0
// Deposited Eth, got sgETH: 0.01 0.01
// new sgETH bal post withdraw 0.0
// warmed up deposit/withdraw
// starting wsgeth bal 0.0
// Staked Eth, got wsgETH: 0.01 0.01
// Unstaked wsgETH, new wsgETH bal: 0.005
// warmed up stake/unstake
}

// We recommend this pattern to be able to use async/await everywhere
Expand Down
4 changes: 2 additions & 2 deletions scripts/v2/lib/DeployHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ class DeployHelper extends OnchainActions {

if (this.launchNetwork === "sepolia") {
// we can get away with less gas on sepolia maybe
// this.overrides.maxFeePerGas = this.overrides.maxFeePerGas / ethers.getUint(10);
// this.overrides.maxPriorityFeePerGas = this.overrides.maxPriorityFeePerGas / ethers.getUint(10);
this.overrides.maxFeePerGas = this.overrides.maxFeePerGas / ethers.getUint(2);
this.overrides.maxPriorityFeePerGas = this.overrides.maxPriorityFeePerGas / ethers.getUint(2);
}

log(`Using gas settings: ${ethers.formatUnits((this.overrides.maxFeePerGas).toString(), "gwei")} gwei & bribe: ${ethers.formatUnits(this.overrides.maxPriorityFeePerGas, "gwei")} gwei`);
Expand Down
28 changes: 21 additions & 7 deletions scripts/v2/lib/deploy_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ const isMainnet = launchNetwork => {
// some behaviours need to be tested with a mainnet fork which behaves the same as mainnet
return launchNetwork == "localhost" || launchNetwork == "mainnet";
};
const _wait = async ms => await new Promise(resolve => setTimeout(resolve, ms));
const _wait = async ms => {
log(`Waiting ${ms} ms`);
await new Promise(resolve => setTimeout(resolve, ms));
}
const _printOverrides = o => {
return {
type: 2,
Expand All @@ -40,6 +43,12 @@ const _printOverrides = o => {

const asMill = (n) => n * 1e7;

const defaultGas = {
type: 2,
maxFeePerGas: ethers.parseUnits("25", "gwei"),
maxPriorityFeePerGas: ethers.parseUnits("1", "gwei"),
};

const _getOverrides = async () => {
const overridesForEIP1559 = {
type: 2,
Expand All @@ -64,6 +73,9 @@ const _getOverrides = async () => {

gas = await ethers.provider.getFeeData();
mfpg = gas.maxFeePerGas;
// if (mfpg >= defaultGas.maxFeePerGas) {
// gas = defaultGas;
// }
console.log("Done waiting for gas resolution; new gas settings: ", ethers.formatUnits(mfpg.toString(), "gwei"));
}
overridesForEIP1559.maxPriorityFeePerGas = overridesForEIP1559.maxPriorityFeePerGas >= (gas.maxPriorityFeePerGas)
Expand Down Expand Up @@ -95,6 +107,9 @@ const _estimateDeploymentGasLimit = async (contractDeployTx) => {
// const deploymentData = contract.interface.encodeDeploy(cArgs)
// const estimatedGas = await ethers.provider.estimateGas({ data: deploymentData });
const estimatedGas = await ethers.provider.estimateGas(contractDeployTx)
log(`Estimated gas for cdtx: ${Object.keys(contractDeployTx).join(' ')} \n ${Object.values(contractDeployTx).join(' ')}`);
log(`Estimated gas: ${Object.keys(estimatedGas).join(' ')} \n ${Object.values(estimatedGas).join(' ')}`);

return estimatedGas;
}

Expand All @@ -109,15 +124,15 @@ const _deployContract = async (name, launchNetwork = false, cArgs = [], cachedOv
const overridesForEIP1559 = cachedOverrides ? cachedOverrides : await _getOverrides();
const factory = await ethers.getContractFactory(name);
// const factory = await ethers.ContractFactory
let cdtx = await factory.getDeployTransaction(...cArgs, overridesForEIP1559);
let estimate = await _estimateDeploymentGasLimit(cdtx);

log(` estimate with settings: \n ${Object.keys(estimate).join(' ')} \n ${Object.values(estimate).join(' ')} from ${cdtx}`)
// let cdtx = await factory.getDeployTransaction(...cArgs, overridesForEIP1559);
// let estimate = await _estimateDeploymentGasLimit(cdtx);
// log(` estimate with settings: \n ${Object.keys(estimate).join(' ')} \n ${Object.values(estimate).join(' ')} from ${cdtx}`)
// over write our custom gas limit with what the tx should take
// overridesForEIP1559.gasLimit = cdtx.gasLimit > 0 && cdtx.gasLimit < overridesForEIP1559.gasLimit ? cdtx.gasLimit : overridesForEIP1559.gasLimit;
// log(` Deploying with settings: \n ${Object.keys(overridesForEIP1559).join(' ')} \n ${Object.values(overridesForEIP1559).join(' ')}`)

log(` Deploying with settings: \n ${Object.keys(overridesForEIP1559).join(' ')} \n ${Object.values(overridesForEIP1559).join(' ')}`)
const contract = await factory.deploy(...cArgs, overridesForEIP1559);
await _wait(10000);
console.log("deployment done, now to waitForDeployment")
await contract.waitForDeployment();
log(`\n waitForDeployment wait for ${name} \n on ${launchNetwork}. `);
Expand All @@ -142,7 +157,6 @@ const _verifyAll = async (allContracts, launchNetwork) => {
let num = 60000; // 60s
log(`Waiting ${num} ms to make sure everything has propagated on etherscan`);
await _wait(num);
// wait 10s to make sure everything has propagated on etherscan

let contractArr = [],
verifyAttemtLog = {};
Expand Down
Loading

0 comments on commit 7029195

Please sign in to comment.