Skip to content

Commit

Permalink
write VerifyV1Deployments.s.sol script
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanRHall committed Dec 11, 2024
1 parent 6f3b24b commit 7aab323
Show file tree
Hide file tree
Showing 8 changed files with 215 additions and 13 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ jobs:
- name: Run unit tests
run: make test
id: test

- name: Run deployment tests
run: forge script script/VerifyV1Deployments.s.sol --ffi
id: deployment-tests
10 changes: 5 additions & 5 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ dev-2 = "https://holesky.gateway.tenderly.co"
dev-3 = "https://holesky.gateway.tenderly.co"
# used for `test` environment
holesky = "https://holesky.gateway.tenderly.co"
sepolia = "${SEPOLIA_RPC_URL}"
base_sepolia = "${BASE_SEPOLIA_RPC_URL}"
sepolia = "https://ethereum-sepolia-rpc.publicnode.com"
base_sepolia = "https://base-sepolia-rpc.publicnode.com"
fraxtal_testnet = "https://rpc.testnet.frax.com"
mantle_sepolia = "https://rpc.sepolia.mantle.xyz"
scroll_sepolia = "https://sepolia-rpc.scroll.io"
# prod environment
mainnet = "${MAINNET_RPC_URL}"
base = "${BASE_RPC_URL}"
mainnet = "https://ethereum-rpc.publicnode.com"
base = "https://base-rpc.publicnode.com"
fraxtal = "https://rpc.frax.com"
mantle = "https://rpc.mantle.xyz"
polygon_zkevm = "https://zkevm-rpc.com"
Expand All @@ -47,7 +47,7 @@ holesky = { key = "${MAINNET_ETHERSCAN_API_KEY}" }
base_sepolia = { key = "${BASESCAN_API_KEY}" }
fraxtal_testnet = { key = "${FRAXSCAN_API_KEY}" }
mantle_sepolia = { key = "${MANTLESCAN_API_KEY}" }
scroll-sepolia = { key = "${SCROLLSCAN_API_KEY}" }
scroll_sepolia = { key = "${SCROLLSCAN_API_KEY}" }

mainnet = { key = "${MAINNET_ETHERSCAN_API_KEY}" }
base = { key = "${BASESCAN_API_KEY}" }
Expand Down
197 changes: 197 additions & 0 deletions script/VerifyV1Deployments.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {Script, console2 as console} from "forge-std/Script.sol";
import {stdJson} from "forge-std/StdJson.sol";
import {LPNQueryV1} from "../src/v1/client/LPNQueryV1.sol";
import {ERC1967Proxy} from
"@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {LibString} from "solady/utils/LibString.sol";
import {
MANTLE_MAINNET,
MANTLE_SEPOLIA,
isMainnet,
isTestnet
} from "../src/utils/Constants.sol";

contract VerifyV1Deployments is Script {
using stdJson for string;
using LibString for string;

bytes32 constant IMPLEMENTATION_SLOT =
bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1);

constructor() {
setChain(
"mantle",
ChainData("Mantle", MANTLE_MAINNET, "https://rpc.mantle.xyz")
);
setChain(
"mantle_sepolia",
ChainData(
"Mantle Sepolia",
MANTLE_SEPOLIA,
"https://rpc.sepolia.mantle.xyz"
)
);

setChain(
"polygon_zkevm",
ChainData("Polygon zkEVM", 1101, "https://zkevm-rpc.com")
);

setChain("scroll_sepolia", ChainData("Scroll Sepolia", 534351, ""));
}

/// @notice entrypoint for the script; verifies the arrangement of all deployed v1 contracts
function run() public {
execute(false);
}

/// @notice alternative entrypoint for the script; verifies the arrangement of all deployed v1 contracts
/// and attempts to fix any misaligned json files
function fix() public {
execute(true);
}

/// @param shouldFix if true, will attempt to fix the misaligned json files
/// @dev this script does change anything about the deployed contracts; it sends no transactions;
/// it only verifies the correctness of the local json files
function execute(bool shouldFix) internal {
// Find all v1-deployment.json files
string[] memory shellCommandInputs = new string[](3);
shellCommandInputs[0] = "/bin/sh";
shellCommandInputs[1] = "-c";
shellCommandInputs[2] = "find . -name v1-deployment.json | sort";

bytes memory output = vm.ffi(shellCommandInputs);
string[] memory files = string(output).split("\n");

bool shouldFail;

for (uint256 i = 0; i < files.length; i++) {
string memory jsonStr = vm.readFile(files[i]);

// Extract chain ID and switch RPC
uint256 chainId =
abi.decode(jsonStr.parseRaw(".chainInfo.chainId"), (uint256));
vm.createSelectFork(getChain(chainId).rpcUrl);

// Extract addresses
address queryClientProxy = abi.decode(
jsonStr.parseRaw(".addresses.queryClientProxy"), (address)
);
address queryClientImpl = abi.decode(
jsonStr.parseRaw(".addresses.queryClientImpl"), (address)
);
address registryProxy = abi.decode(
jsonStr.parseRaw(".addresses.registryProxy"), (address)
);
address registryImpl = abi.decode(
jsonStr.parseRaw(".addresses.registryImpl"), (address)
);

// Print deployment info
console.log("\nVerifying deployment in file:", files[i]);
console.log("Chain ID:", chainId);
console.log("QueryClient Proxy:", queryClientProxy);
console.log("QueryClient Implementation:", queryClientImpl);
console.log("Registry Proxy:", registryProxy);
console.log("Registry Implementation:", registryImpl);
console.log(
"--------------------- Assertions ---------------------"
);

// Verify query client proxy implementation
if (queryClientProxy != address(0)) {
address actualQueryImpl =
getProxyImplementation(queryClientProxy);
if (actualQueryImpl != queryClientImpl) {
shouldFail = true;
console.log(
unicode"✗ QueryClient Proxy points to incorrect implementation"
);
if (shouldFix) {
jsonStr = vm.serializeString(
jsonStr,
".addresses.queryClientImpl",
vm.toString(actualQueryImpl)
);
}
} else {
console.log(
unicode"✓ QueryClient Proxy points to correct implementation"
);
}
} else {
console.log(
unicode"✓ QueryClient Proxy not deployed, skipping check"
);
}

// Verify query client points to the correct registry
if (queryClientProxy != address(0)) {
address linkedRegistry =
address(LPNQueryV1(queryClientProxy).lpnRegistry());
if (linkedRegistry != registryProxy) {
shouldFail = true;
console.log(
unicode"✗ QueryClient points to incorrect LPNRegistry"
);
} else {
console.log(
unicode"✓ QueryClient points to correct LPNRegistry"
);
}
} else {
console.log(
unicode"✓ QueryClient Proxy not deployed, skipping check"
);
}

// Verify registry proxy implementation
if (registryProxy != address(0)) {
address actualRegistryImpl =
getProxyImplementation(registryProxy);
if (actualRegistryImpl != registryImpl) {
shouldFail = true;
console.log(
unicode"✗ Registry Proxy points to incorrect implementation"
);
if (shouldFix) {
jsonStr = vm.serializeString(
jsonStr,
".addresses.registryImpl",
vm.toString(actualRegistryImpl)
);
}
} else {
console.log(
unicode"✓ Registry proxy points to correct implementation"
);
}
} else {
console.log(
unicode"✓ Registry proxy not deployed, skipping check"
);
}

vm.writeJson(jsonStr, files[i]);
}

if (shouldFail) revert("verification failed");
}

function getProxyImplementation(address proxy)
internal
view
returns (address)
{
address implementation;
bytes32 result = vm.load(proxy, IMPLEMENTATION_SLOT);
assembly {
implementation := result
}
return implementation;
}
}
6 changes: 3 additions & 3 deletions script/output/dev-0/v1-deployment.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"addresses": {
"queryClient": "0x9e81a7a0A234E6Ede4604DD7823018D0efE53b4b",
"queryClientProxy": "0x5C189dC46c2c6136dBaFdAAa02Db46CD2dF683A3",
"registryImpl": "0x7a9C8a9af98119249F1b8f4786Fa9aE1B5fBB60A",
"queryClientImpl": "0x400e7aAEadcc134B0d8413092119221Ad736ed3e",
"queryClientProxy": "0x859fAB84a9EB80Ba45E1ACb90B75608ce484caa9",
"registryImpl": "0xd2CB2F1a106E5145D9aa882b8902cB0fA800Da6d",
"registryProxy": "0x851Abc818275932215a345B7059d40a89939C074"
},
"chainInfo": {
Expand Down
2 changes: 1 addition & 1 deletion script/output/holesky/v1-deployment.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"addresses": {
"queryClientImpl": "0x80c0a42F808d6f35e83F4939482A485caE536e6a",
"queryClientImpl": "0xa0Ac691e90460Ac0fB5ADC8AC0Dd9b28CFAD69b4",
"queryClientProxy": "0xcB170B5a3cf707b4dAc2AbdD6919A0c30A8ec145",
"registryImpl": "0x12a628B8F31939bFa233E284862945870BBE649A",
"registryProxy": "0xF8E0EfefAFfa31f9C85F175147d64753e4eC8157"
Expand Down
4 changes: 2 additions & 2 deletions script/output/holesky_dev/v1-deployment.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"addresses": {
"queryClientImpl": "0xE1b71B57Ea95ae274018aE844ae7013F39Cb06Dc",
"queryClientImpl": "0x9e81a7a0A234E6Ede4604DD7823018D0efE53b4b",
"queryClientProxy": "0x5C189dC46c2c6136dBaFdAAa02Db46CD2dF683A3",
"registryImpl": "0x4015A66c1a8f4C6bD93507290f6C5304c38a4c56",
"registryImpl": "0xd0fA8Ea6981894687DeFc1AAebf5804CDa7e654F",
"registryProxy": "0xC9135b51c4DD04B6E082e2cB56a5C26b3a53Ee47"
},
"chainInfo": {
Expand Down
2 changes: 1 addition & 1 deletion script/output/mainnet/v1-deployment.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
"erc20ProportionateBalance": "0x0000000000000000000000000000000000000000",
"erc721Enumerable": "0x0000000000000000000000000000000000000000"
}
}
}
3 changes: 2 additions & 1 deletion script/output/scroll_sepolia/v1-deployment.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"addresses": {
"queryClient": "0x0000000000000000000000000000000000000000",
"queryClientImpl": "0x0000000000000000000000000000000000000000",
"queryClientProxy": "0x0000000000000000000000000000000000000000",
"registryImpl": "0xBeAd7Fe75B567Ac0fc12526225451eb3F964d834",
"registryProxy": "0xC9135b51c4DD04B6E082e2cB56a5C26b3a53Ee47"
},
Expand Down

0 comments on commit 7aab323

Please sign in to comment.