Skip to content

Commit

Permalink
v4: testnet changes (#71)
Browse files Browse the repository at this point in the history
* feat(v4): whitelist two tokens on deployment

* v4: add deployment addresses

* feat(v4): update `generate.js`

* chore: forge fmt

* fix(generate): correct the order of meta info

* fix(generate): depend on min self delegation

* fix(generate): load oracle data

* fix(generate): add price decimals for oracle

* fix(generate): x/oracle future start block

* script: add redeploy bootstrap script

* fix(pre-req): use correct lz endpoint

* fix(script): allow set peers to run

* fix(script): allow `getDeployedCode` to work

In newer versions of Foundry, the imports are required

* fix: correct lz endpoint

* update exocore gateway deployment

* update client chain gateway address

* add corrected bootstrap deployment

* chore: forge fmt

* chore: forge fmt with newer foundry
  • Loading branch information
MaxMustermann2 authored Aug 12, 2024
1 parent 61ad95f commit 1346b0d
Show file tree
Hide file tree
Showing 11 changed files with 297 additions and 113 deletions.
58 changes: 13 additions & 45 deletions script/11_SetPeers.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ contract SetPeersAndUpgrade is BaseScript {
ExocoreGateway gateway = ExocoreGateway(payable(exocoreGatewayAddr));

vm.selectFork(exocore);
// Foundry rejects this transaction because it reports that isRegisteredClientChain fails, no matter what
// we do. Conversely, other tools like Remix and Brownie and even cast are able to report the value
// correctly. As a workaround, have `AssetsMock` return `true` value before running this script.
if (!useExocorePrecompileMock) {
_bindPrecompileMocks();
}
vm.startBroadcast(exocoreValidatorSet.privateKey);
gateway.setPeer(clientChainId, bootstrapAddr.toBytes32());
vm.stopBroadcast();
Expand All @@ -45,52 +51,14 @@ contract SetPeersAndUpgrade is BaseScript {
bootstrap.setPeer(exocoreChainId, address(exocoreGatewayAddr).toBytes32());
vm.stopBroadcast();

// check that peer is set (we run with --slow but even then there's some risk)
uint256 i = 0;
uint256 tries = 5;
bool success;
while (i < tries) {
vm.selectFork(exocore);
success = gateway.peers(clientChainId) == bootstrapAddr.toBytes32();

vm.selectFork(clientChain);
success = success && bootstrap.peers(exocoreChainId) == address(exocoreGatewayAddr).toBytes32();

if (success) {
break;
}

i++;
vm.selectFork(exocore);
vm.startBroadcast(exocoreValidatorSet.privateKey);
// fund the gateway
if (exocoreGatewayAddr.balance < 1 ether) {
(bool sent,) = exocoreGatewayAddr.call{value: 1 ether}("");
require(sent, "Failed to send Ether");
}
require(i < tries, "peers not set");

// the upgrade does not work via script due to the precompile issue
// https://github.com/ExocoreNetwork/exocore/issues/78
// // now that peers are set, we should upgrade the Bootstrap contract via gateway
// // but first allow simulation to run
// vm.selectFork(exocore);
// bytes memory mockCode = vm.getDeployedCode("ClientChainsMock.sol");
// vm.etch(CLIENT_CHAINS_PRECOMPILE_ADDRESS, mockCode);

// console.log("clientChainId", clientChainId);
// vm.startBroadcast(exocoreValidatorSet.privateKey);
// // fund the gateway
// if (exocoreGatewayAddr.balance < 1 ether) {
// (bool sent,) = exocoreGatewayAddr.call{value: 1 ether}("");
// require(sent, "Failed to send Ether");
// }
// // gateway.markBootstrapOnAllChains();

// instruct the user to upgrade manually
// this can be done even without calling x/assets UpdateParams
// because that parameter is not involved in this process.
console.log("Cross-chain upgrade command:");
console.log(
"source .env && cast send --rpc-url $EXOCORE_TESETNET_RPC",
exocoreGatewayAddr,
'"markBootstrapOnAllChains()"',
"--private-key $TEST_ACCOUNT_THREE_PRIVATE_KEY"
);
gateway.markBootstrapOnAllChains();
}

}
110 changes: 110 additions & 0 deletions script/14_CorrectBootstrapErrors.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
pragma solidity ^0.8.19;

import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";

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

import "../src/core/BeaconProxyBytecode.sol";
import {Bootstrap} from "../src/core/Bootstrap.sol";
import {ClientChainGateway} from "../src/core/ClientChainGateway.sol";

import "../src/core/ExoCapsule.sol";
import {Vault} from "../src/core/Vault.sol";
import {ICustomProxyAdmin} from "../src/interfaces/ICustomProxyAdmin.sol";

import {BaseScript} from "./BaseScript.sol";
import {ILayerZeroEndpointV2} from "@layerzero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol";
import {ERC20PresetFixedSupply} from "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol";
import "forge-std/Script.sol";

import "@beacon-oracle/contracts/src/EigenLayerBeaconOracle.sol";

// This script uses the address in `deployedBootstrapOnly` and redeploys on top of it. For that to work, the
// modifier for the initialize function needs to be changed from `initializer` to `reinitializer(2)`. At the same
// time, the `reinitializer` in the `ClientChainGateway` will need to be changed to `3`.
contract CorrectBootstrapErrors is BaseScript {

address wstETH;
address proxyAddress;
address proxyAdmin;

function setUp() public virtual override {
// load keys
super.setUp();
// load contracts
string memory prerequisiteContracts = vm.readFile("script/prerequisiteContracts.json");
clientChainLzEndpoint =
ILayerZeroEndpointV2(stdJson.readAddress(prerequisiteContracts, ".clientChain.lzEndpoint"));
require(address(clientChainLzEndpoint) != address(0), "Client chain endpoint not found");
restakeToken = ERC20PresetFixedSupply(stdJson.readAddress(prerequisiteContracts, ".clientChain.erc20Token"));
require(address(restakeToken) != address(0), "Restake token not found");
clientChain = vm.createSelectFork(clientChainRPCURL);
// we should use the pre-requisite to save gas instead of deploying our own
beaconOracle = EigenLayerBeaconOracle(stdJson.readAddress(prerequisiteContracts, ".clientChain.beaconOracle"));
require(address(beaconOracle) != address(0), "Beacon oracle not found");
// same for BeaconProxyBytecode
beaconProxyBytecode =
BeaconProxyBytecode(stdJson.readAddress(prerequisiteContracts, ".clientChain.beaconProxyBytecode"));
require(address(beaconProxyBytecode) != address(0), "Beacon proxy bytecode not found");
// wstETH on Sepolia
// https://docs.lido.fi/deployed-contracts/sepolia/
wstETH = stdJson.readAddress(prerequisiteContracts, ".clientChain.wstETH");
require(wstETH != address(0), "wstETH not found");

string memory deployed = vm.readFile("script/deployedBootstrapOnly.json");
proxyAddress = stdJson.readAddress(deployed, ".clientChain.bootstrap");
require(address(proxyAddress) != address(0), "bootstrap address should not be empty");
proxyAdmin = stdJson.readAddress(deployed, ".clientChain.proxyAdmin");
require(address(proxyAdmin) != address(0), "proxy admin address should not be empty");
vaultImplementation = Vault(stdJson.readAddress(deployed, ".clientChain.vaultImplementation"));
require(address(vaultImplementation) != address(0), "vault implementation should not be empty");
vaultBeacon = UpgradeableBeacon(stdJson.readAddress(deployed, ".clientChain.vaultBeacon"));
require(address(vaultBeacon) != address(0), "vault beacon should not be empty");
}

function run() public {
address[] memory emptyList;

vm.selectFork(clientChain);
vm.startBroadcast(exocoreValidatorSet.privateKey);
ProxyAdmin proxyAdmin = ProxyAdmin(proxyAdmin);
Bootstrap bootstrapLogic = new Bootstrap(
address(clientChainLzEndpoint), exocoreChainId, address(vaultBeacon), address(beaconProxyBytecode)
);
bytes memory data = abi.encodeCall(
Bootstrap.initialize,
(
exocoreValidatorSet.addr,
// 1 week from now
block.timestamp + 168 hours,
2 seconds,
emptyList,
address(proxyAdmin)
)
);
proxyAdmin.upgradeAndCall(ITransparentUpgradeableProxy(proxyAddress), address(bootstrapLogic), data);
Bootstrap bootstrap = Bootstrap(payable(proxyAddress));
vm.stopBroadcast();

string memory clientChainContracts = "clientChainContracts";
vm.serializeAddress(clientChainContracts, "lzEndpoint", address(clientChainLzEndpoint));
vm.serializeAddress(clientChainContracts, "erc20Token", address(restakeToken));
vm.serializeAddress(clientChainContracts, "wstETH", wstETH);
vm.serializeAddress(clientChainContracts, "proxyAdmin", address(proxyAdmin));
vm.serializeAddress(clientChainContracts, "vaultImplementation", address(vaultImplementation));
vm.serializeAddress(clientChainContracts, "vaultBeacon", address(vaultBeacon));
vm.serializeAddress(clientChainContracts, "beaconProxyBytecode", address(beaconProxyBytecode));
vm.serializeAddress(clientChainContracts, "bootstrapLogic", address(bootstrapLogic));
vm.serializeAddress(clientChainContracts, "bootstrap", address(bootstrap));
string memory clientChainContractsOutput =
vm.serializeAddress(clientChainContracts, "beaconOracle", address(beaconOracle));

string memory deployedContracts = "deployedContracts";
string memory finalJson = vm.serializeString(deployedContracts, "clientChain", clientChainContractsOutput);

vm.writeJson(finalJson, "script/correctBootstrapErrors.json");
}

}
13 changes: 11 additions & 2 deletions script/7_DeployBootstrap.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import "@beacon-oracle/contracts/src/EigenLayerBeaconOracle.sol";

contract DeployBootstrapOnly is BaseScript {

address wstETH;

function setUp() public virtual override {
// load keys
super.setUp();
Expand All @@ -37,12 +39,17 @@ contract DeployBootstrapOnly is BaseScript {
beaconProxyBytecode =
BeaconProxyBytecode(stdJson.readAddress(prerequisiteContracts, ".clientChain.beaconProxyBytecode"));
require(address(beaconProxyBytecode) != address(0), "Beacon proxy bytecode not found");
// wstETH on Sepolia
// https://docs.lido.fi/deployed-contracts/sepolia/
wstETH = stdJson.readAddress(prerequisiteContracts, ".clientChain.wstETH");
require(wstETH != address(0), "wstETH not found");
}

function run() public {
vm.selectFork(clientChain);
vm.startBroadcast(exocoreValidatorSet.privateKey);
whitelistTokens.push(address(restakeToken));
whitelistTokens.push(wstETH);

// proxy deployment
CustomProxyAdmin proxyAdmin = new CustomProxyAdmin();
Expand All @@ -64,8 +71,9 @@ contract DeployBootstrapOnly is BaseScript {
Bootstrap.initialize,
(
exocoreValidatorSet.addr,
block.timestamp + 365 days + 24 hours,
24 hours,
// 1 week from now
block.timestamp + 168 hours,
2 seconds,
whitelistTokens, // vault is auto deployed
address(proxyAdmin)
)
Expand Down Expand Up @@ -100,6 +108,7 @@ contract DeployBootstrapOnly is BaseScript {
string memory clientChainContracts = "clientChainContracts";
vm.serializeAddress(clientChainContracts, "lzEndpoint", address(clientChainLzEndpoint));
vm.serializeAddress(clientChainContracts, "erc20Token", address(restakeToken));
vm.serializeAddress(clientChainContracts, "wstETH", wstETH);
vm.serializeAddress(clientChainContracts, "proxyAdmin", address(proxyAdmin));
vm.serializeAddress(clientChainContracts, "vaultImplementation", address(vaultImplementation));
vm.serializeAddress(clientChainContracts, "vaultBeacon", address(vaultBeacon));
Expand Down
4 changes: 4 additions & 0 deletions script/BaseScript.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import {IBeacon} from "@openzeppelin/contracts/proxy/beacon/IBeacon.sol";
import {ERC20PresetFixedSupply, IERC20} from "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol";
import "forge-std/Script.sol";

import "../test/mocks/AssetsMock.sol";
import "../test/mocks/ClaimRewardMock.sol";
import "../test/mocks/DelegationMock.sol";

contract BaseScript is Script {

struct Player {
Expand Down
14 changes: 14 additions & 0 deletions script/correctBootstrapErrors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"clientChain": {
"beaconOracle": "0xd3D285cd1516038dAED61B8BF7Ae2daD63662492",
"beaconProxyBytecode": "0xA15Ce26ba8E50ac21ecDa1791BAa3bf22a95b575",
"bootstrap": "0x53f39D2ECd900Fb018180dB692A9fc29c8efD38E",
"bootstrapLogic": "0x3C9928feC16faDD504ab663a202c43cebC29f88D",
"erc20Token": "0x83E6850591425e3C1E263c054f4466838B9Bd9e4",
"lzEndpoint": "0x6EDCE65403992e310A62460808c4b910D972f10f",
"proxyAdmin": "0x266517829c443D5F8d2dB3782d3F5f6D8Ed40903",
"vaultBeacon": "0xad6F09ED99aE9E2f47892e2b49b18E024fC2938C",
"vaultImplementation": "0x4B7422868F4574b9c1830aD6466D406FF7503290",
"wstETH": "0xB82381A3fBD3FaFA77B3a7bE693342618240067b"
}
}
17 changes: 9 additions & 8 deletions script/deployedBootstrapOnly.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
"clientChain": {
"beaconOracle": "0xd3D285cd1516038dAED61B8BF7Ae2daD63662492",
"beaconProxyBytecode": "0xA15Ce26ba8E50ac21ecDa1791BAa3bf22a95b575",
"bootstrap": "0x53E91EB5105ec8C1c22055F790616cB8F82c664e",
"bootstrapLogic": "0x417CaBa1E4a63D1202dCc6E19F7c3eC79b31EC45",
"capsuleBeacon": "0xe87e516C7116eC4DcFC5408c05618De6e1Cd4c10",
"capsuleImplementation": "0xBe26AfFF7EC33d6F4BC8175d3F6f404692e82443",
"clientGatewayLogic": "0xcE10583b1Efe34319812d96c7edFFD71E8403ba2",
"bootstrap": "0x53f39D2ECd900Fb018180dB692A9fc29c8efD38E",
"bootstrapLogic": "0x46F02C2c5F8E30D88C3f53437051f4eB47EF8abD",
"capsuleBeacon": "0xB43b4344D48A3096f3d8c974E610a676C73B4fEB",
"capsuleImplementation": "0x8D3c21EBef5992041De2DebAf01f4B16Cf9f8913",
"clientGatewayLogic": "0x538Dc35cd5debEbA9D70577C3429438ee5ACaA15",
"erc20Token": "0x83E6850591425e3C1E263c054f4466838B9Bd9e4",
"lzEndpoint": "0x6EDCE65403992e310A62460808c4b910D972f10f",
"proxyAdmin": "0xE9591d5b1Ea9733ad36834cd0bDe40ce0028AE33",
"vaultBeacon": "0x2899181D6EB55847165cfa3288E4708dA5070751",
"vaultImplementation": "0xF22097E6799DF7D8b25CCeF6E64DA3CB9133012D"
"proxyAdmin": "0x266517829c443D5F8d2dB3782d3F5f6D8Ed40903",
"vaultBeacon": "0xad6F09ED99aE9E2f47892e2b49b18E024fC2938C",
"vaultImplementation": "0x4B7422868F4574b9c1830aD6466D406FF7503290",
"wstETH": "0xB82381A3fBD3FaFA77B3a7bE693342618240067b"
}
}
4 changes: 2 additions & 2 deletions script/deployedExocoreGatewayOnly.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"exocore": {
"exocoreGateway": "0xe13Ef2fE9B4bC1A3bBB62Df6bB19d6aD79525036",
"exocoreGatewayLogic": "0x617c588c3FaAA105cec3438D0c031E143A8B23fd",
"exocoreGateway": "0xbf5497Deb7C409623Ad58D798E73a865a80873DD",
"exocoreGatewayLogic": "0xdd359906110Ae307eeCdE5d1179ab59461152348",
"lzEndpoint": "0x6EDCE65403992e310A62460808c4b910D972f10f"
}
}
Loading

0 comments on commit 1346b0d

Please sign in to comment.