Skip to content

Commit

Permalink
Implement deployment script, deploy to Holesky
Browse files Browse the repository at this point in the history
  • Loading branch information
jac18281828 committed May 1, 2024
1 parent 91e985e commit 38bc698
Show file tree
Hide file tree
Showing 17 changed files with 292 additions and 38 deletions.
24 changes: 8 additions & 16 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,12 @@
"JuanBlanco.solidity"
]
}
},
"containerEnv": {
"PRIVATE_KEY": "${localEnv:PRIVATE_KEY}",
"PUBLIC_KEY": "${localEnv:PUBLIC_KEY}",
"RPC_URL": "${localEnv:RPC_URL}",
"HOLESKY_URL": "${localEnv:HOLESKY_URL}",
"ETHERSCAN_API_KEY": "${localEnv:ETHERSCAN_API_KEY}"
}

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Uncomment the next line to run commands after the container is created.
// "postCreateCommand": "cat /etc/os-release",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "devcontainer"
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ out/
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/
broadcast/

# Docs
docs/
Expand Down
10 changes: 8 additions & 2 deletions .solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
"plugins": [],
"rules": {
"avoid-suicide": "error",
"avoid-sha3": "warn"
"avoid-sha3": "warn",
"func-visibility": [
"warn",
{
"ignoreConstructors": true
}
]
}
}
}
89 changes: 88 additions & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,93 @@
"kind": "test",
"isDefault": false
}
}
},
{
"label": "deployproxyadmin",
"type": "shell",
"command": "forge script ./script/HSETH.s.sol:DeployHSETH --sig 'deployAdmin()' --broadcast --slow --rpc-url ${HOLESKY_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify",
"options": {
"cwd": "${workspaceFolder}",
"env": {
"HSETH_ADMIN": "0x2E1F5C7f87096fb7FfFbB6654Fc3b2CE303aEff5",
}
},
"dependsOn": "test",
"group": {
"kind": "test",
"isDefault": false
}
},
{
"label": "deployhseth",
"type": "shell",
"command": "forge script ./script/HSETH.s.sol:DeployHSETH --sig 'proxyDeploy()' --broadcast --slow --rpc-url ${HOLESKY_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify",
"options": {
"cwd": "${workspaceFolder}",
"env": {
"HSETH_ADMIN": "0x2E1F5C7f87096fb7FfFbB6654Fc3b2CE303aEff5",
"PROXY_ADMIN": "0x6904603c27392310D19E389105CA792FB935C43C",
}
},
"dependsOn": "test",
"group": {
"kind": "test",
"isDefault": false
}
},
{
"label": "upgradehseth",
"type": "shell",
"command": "forge script ./script/HSETH.s.sol:DeployHSETH --sig 'proxyUpgrade()' --broadcast --slow --rpc-url ${HOLESKY_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify",
"options": {
"cwd": "${workspaceFolder}",
"env": {
"PROXY_ADMIN": "0x6904603c27392310D19E389105CA792FB935C43C",
"PROXY_ADDRESS": "0x217EBabCf15EC6deaCF11f737d79275e95C97EFE",
}
},
"dependsOn": "test",
"group": {
"kind": "test",
"isDefault": false
}
},
{
"label": "deploystakingmanager",
"type": "shell",
"command": "forge script ./script/StaderHavenStakingManager.s.sol:DeployStakingManager --sig 'proxyDeploy()' --broadcast --slow --rpc-url ${HOLESKY_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify",
"options": {
"cwd": "${workspaceFolder}",
"env": {
"HSETH_ADMIN": "0x2E1F5C7f87096fb7FfFbB6654Fc3b2CE303aEff5",
"PROXY_ADMIN": "0x6904603c27392310D19E389105CA792FB935C43C",
"HSETH": "0x217EBabCf15EC6deaCF11f737d79275e95C97EFE",
"TREASURY": "0x2E1F5C7f87096fb7FfFbB6654Fc3b2CE303aEff5",
"STADER_CONFIG": "0x50FD3384783EE49011E7b57d7A3430a762b3f3F2"
}
},
"dependsOn": "test",
"group": {
"kind": "test",
"isDefault": false
}
},
{
"label": "upgradestakingmanager",
"type": "shell",
"command": "forge script ./script/StaderHavenStakingManager.s.sol:DeployStakingManager --sig 'proxyUpgrade()' --broadcast --slow --rpc-url ${HOLESKY_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify",
"options": {
"cwd": "${workspaceFolder}",
"env": {
"PROXY_ADMIN": "0x6904603c27392310D19E389105CA792FB935C43C",
"PROXY_ADDRESS": "0xDBAaD20ffd67dfaeBdE40b842cB78eAa18F1BB74",
}
},
"dependsOn": "test",
"group": {
"kind": "test",
"isDefault": false
}
},
]
}
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,47 @@
## HsETH

### Haven1 ETHx Wrapper designed by Stader Labs

hsETH is an ERC-20 token developed by Stader Labs, specifically designed for the Staders restaking ecosystem. It allows users to deposit ETH tokens into the contract and mint liquid hsETH, providing unique opportunities for decentralized exchange liquidity pools. This facilitates easy entry and exit from positions representing restaked assets.

### Deployment

| Contract | Address | Network |
| ------------------------- | ------------------------------------------ | ------- |
| ProxyAdmin | 0x6904603c27392310D19E389105CA792FB935C43C | Holesky |
| HsETH | 0x217EBabCf15EC6deaCF11f737d79275e95C97EFE | Holesky |
| StaderHavenStakingManager | 0xDBAaD20ffd67dfaeBdE40b842cB78eAa18F1BB74 | Holesky |
| ProxyAdmin | 0x12eA3B1265d5D41a3b582410241537A751FC52ff | Sepolia |
| HsETH | 0x063d4c8CFeF375C2Fc1710934504e2b7aB85fd15 | Sepolia |

#### Deployment Process

##### hsETH

1. Deploy ProxyAdmin or choose an existing Admin
```bash
$ HSETH_ADMIN=0x2E1F5C7f87096fb7FfFbB6654Fc3b2CE303aEff5 forge script ./script/HSETH.s.sol:DeployHSETH --sig 'deployAdmin()' --broadcast --slow --rpc-url ${RPC_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify
```
Make note of deployment details, contract address and owner.
2. Deploy HsETH contract with ProxyAdmin as owner
```bash
$ HSETH_ADMIN=0x2E1F5C7f87096fb7FfFbB6654Fc3b2CE303aEff5 PROXY_ADMIN=0x6904603c27392310D19E389105CA792FB935C43C forge script ./script/HSETH.s.sol:DeployHSETH --sig 'proxyDeploy()' --broadcast --slow --rpc-url ${RPC_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify
```
3. Upgrade HsETH Contract as required
```bash
$ PROXY_ADMIN=0x6904603c27392310D19E389105CA792FB935C43C PROXY_ADDRESS=0x217EBabCf15EC6deaCF11f737d79275e95C97EFE forge script ./script/HSETH.s.sol:DeployHSETH --sig 'proxyUpgrade()' --broadcast --slow --rpc-url ${RPC_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify
```

##### StaderHavenStakingManager

1. Deploy StaderHavenStakingManager
```bash
$ HSETH_ADMIN=0x2E1F5C7f87096fb7FfFbB6654Fc3b2CE303aEff5 PROXY_ADMIN=0x6904603c27392310D19E389105CA792FB935C43C HSETH=0x217EBabCf15EC6deaCF11f737d79275e95C97EFE TREASURY=0x2E1F5C7f87096fb7FfFbB6654Fc3b2CE303aEff5 STADER_CONFIG=0x50FD3384783EE49011E7b57d7A3430a762b3f3F2 forge script ./script/StaderHavenStakingManager.s.sol:DeployStakingManager --sig 'proxyDeploy()' --broadcast --slow --rpc-url ${HOLESKY_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify
```
2. Upgrade StaderHavenStakingManager as needed
```bash
$ PROXY_ADMIN=0x6904603c27392310D19E389105CA792FB935C43C PROXY_ADDRESS=0xDBAaD20ffd67dfaeBdE40b842cB78eAa18F1BB74 forge script ./script/StaderHavenStakingManager.s.sol:DeployStakingManager --sig 'proxyUpgrade()' --broadcast --slow --rpc-url ${HOLESKY_URL} --private-key ${PRIVATE_KEY} --etherscan-api-key ${ETHERSCAN_API_KEY} --verify
```
## Foundry

**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.**
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[profile.default]
src = "src"
src = "contracts"
out = "out"
libs = ["lib"]

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "solhint 'contracts/**/*.sol'"
"lint": "solhint 'contracts/**/*.sol' 'script/**/*.sol'"
},
"repository": {
"type": "git",
Expand Down
53 changes: 53 additions & 0 deletions script/HSETH.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: UNLICENSED
// solhint-disable no-console
pragma solidity 0.8.16;

import { Script, console } from "forge-std/Script.sol";
import { ProxyAdmin } from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";

import {
ITransparentUpgradeableProxy,
TransparentUpgradeableProxy
} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";

import { HSETH } from "../contracts/HSETH.sol";

contract DeployHSETH is Script {
event ProxyAdminCreated(address admin);
event HsETHProxy(address proxy);
event HsETHUpgrade(address proxy, address implementation);

function deployAdmin() public {
address admin = vm.envAddress("HSETH_ADMIN");
vm.startBroadcast();
ProxyAdmin proxyAdmin = new ProxyAdmin();
console.log("ProxyAdmin: ", address(proxyAdmin));
proxyAdmin.transferOwnership(admin);
emit ProxyAdminCreated(address(proxyAdmin));
vm.stopBroadcast();
}

function proxyDeploy() public {
address admin = vm.envAddress("HSETH_ADMIN");
address proxyAdmin = vm.envAddress("PROXY_ADMIN");
vm.startBroadcast();
HSETH implementation = new HSETH();
bytes memory initializationCalldata = abi.encodeWithSelector(implementation.initialize.selector, admin);
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(address(implementation), proxyAdmin, initializationCalldata);
console.log("hsETH Transparent Proxy: ", address(proxy));
emit HsETHProxy(address(proxy));
vm.stopBroadcast();
}

function proxyUpgrade() public {
address proxyAdmin = vm.envAddress("PROXY_ADMIN");
address proxyAddress = vm.envAddress("PROXY_ADDRESS");
vm.startBroadcast();
HSETH implementation = new HSETH();
ITransparentUpgradeableProxy proxy = ITransparentUpgradeableProxy(proxyAddress);
ProxyAdmin(proxyAdmin).upgrade(proxy, address(implementation));
console.log("hsETH Transparent Proxy Upgraded: ", address(proxyAddress), " to ", address(implementation));
emit HsETHUpgrade(address(proxyAddress), address(implementation));
vm.stopBroadcast();
}
}
51 changes: 51 additions & 0 deletions script/StaderHavenStakingManager.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: UNLICENSED
// solhint-disable no-console
pragma solidity 0.8.16;

import { Script, console } from "forge-std/Script.sol";
import { ProxyAdmin } from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";

import {
ITransparentUpgradeableProxy,
TransparentUpgradeableProxy
} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";

import { StaderHavenStakingManager } from "../contracts/StaderHavenStakingManager.sol";
import { HSETH } from "../contracts/HSETH.sol";

contract DeployStakingManager is Script {
event StakingManagerProxy(address proxy);
event StakingManagerUpgrade(address proxy, address implementation);

function proxyDeploy() public {
address admin = vm.envAddress("HSETH_ADMIN");
address proxyAdmin = vm.envAddress("PROXY_ADMIN");
address hsETH = vm.envAddress("HSETH");
address treasury = vm.envAddress("TREASURY");
address staderConfig = vm.envAddress("STADER_CONFIG");
vm.startBroadcast();
StaderHavenStakingManager implementation = new StaderHavenStakingManager();
bytes memory initializationCalldata = abi.encodeWithSelector(implementation.initialize.selector, admin, hsETH, treasury, staderConfig);
TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy(address(implementation), proxyAdmin, initializationCalldata);
console.log("StakingManager Transparent Proxy: ", address(proxy));
StaderHavenStakingManager staderHavenStakingManager = StaderHavenStakingManager(address(proxy));
staderHavenStakingManager.grantRole(staderHavenStakingManager.MANAGER(), admin);
HSETH hsETHToken = HSETH(hsETH);
hsETHToken.grantRole(hsETHToken.MINTER_ROLE(), address(staderHavenStakingManager));
hsETHToken.grantRole(hsETHToken.BURNER_ROLE(), address(staderHavenStakingManager));
emit StakingManagerProxy(address(proxy));
vm.stopBroadcast();
}

function proxyUpgrade() public {
address proxyAdmin = vm.envAddress("PROXY_ADMIN");
address proxyAddress = vm.envAddress("PROXY_ADDRESS");
vm.startBroadcast();
StaderHavenStakingManager implementation = new StaderHavenStakingManager();
ITransparentUpgradeableProxy proxy = ITransparentUpgradeableProxy(proxyAddress);
ProxyAdmin(proxyAdmin).upgrade(proxy, address(implementation));
console.log("StakingManager Transparent Proxy Upgraded: ", address(proxyAddress), " to ", address(implementation));
emit StakingManagerUpgrade(address(proxyAddress), address(implementation));
vm.stopBroadcast();
}
}
9 changes: 5 additions & 4 deletions test/HSETH.t.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.16;

import "../src/HSETH.sol";
import { TransparentUpgradeableProxy } from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import { ProxyAdmin } from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";

import "forge-std/Test.sol";
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
import { Test } from "forge-std/Test.sol";

import { HSETH } from "../contracts/HSETH.sol";

contract HSETHTest is Test {
address admin;
Expand Down
Loading

0 comments on commit 38bc698

Please sign in to comment.