- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control. - Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities. - Created .gitmodules to include OpenZeppelin contracts as a submodule. - Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment. - Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks. - Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring. - Created scripts for resource import and usage validation across non-US regions. - Added tests for CCIP error handling and integration to ensure robust functionality. - Included various new files and directories for the orchestration portal and deployment scripts.
165 lines
6.7 KiB
Solidity
165 lines
6.7 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.19;
|
|
|
|
import {Script, console} from "forge-std/Script.sol";
|
|
import {WETH} from "../contracts/tokens/WETH.sol";
|
|
import {CREATE2Factory} from "../contracts/utils/CREATE2Factory.sol";
|
|
|
|
/**
|
|
* @title DeployWETH9Smart
|
|
* @notice Smart deployment using Foundry's impersonation and salt calculation
|
|
* @dev Since the address is in genesis.json, we can:
|
|
* 1. Calculate salt for known deployers (no brute force needed)
|
|
* 2. Use vm.startBroadcast(address) to impersonate any deployer
|
|
* 3. Deploy using CREATE2 with calculated salt
|
|
*/
|
|
contract DeployWETH9Smart is Script {
|
|
address constant TARGET_WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
|
|
|
|
// Potential deployers (try these in order)
|
|
address constant CREATE2_DEPLOYER = 0x4e59b44847b379578588920cA78FbF26c0B4956C;
|
|
address constant GENESIS_ADDRESS_1 = 0x0742D35CC6634c0532925A3b844bc9E7595f0Beb;
|
|
address constant GENESIS_ADDRESS_2 = 0xa55A4B57A91561e9df5a883D4883Bd4b1a7C4882;
|
|
|
|
function run() external {
|
|
console.log("Smart Deployment: WETH9 to", vm.toString(TARGET_WETH9));
|
|
|
|
bytes memory bytecode = type(WETH).creationCode;
|
|
bytes32 bytecodeHash = keccak256(bytecode);
|
|
|
|
// Try each potential deployer
|
|
address[] memory deployers = new address[](4);
|
|
deployers[0] = CREATE2_DEPLOYER;
|
|
deployers[1] = GENESIS_ADDRESS_1;
|
|
deployers[2] = GENESIS_ADDRESS_2;
|
|
// Try CREATE2Factory as deployer too (will deploy it first if needed)
|
|
deployers[3] = address(0); // Will be set to CREATE2Factory address
|
|
|
|
for (uint256 i = 0; i < deployers.length; i++) {
|
|
address deployer = deployers[i];
|
|
|
|
if (deployer == address(0)) {
|
|
// Deploy CREATE2Factory first, then use it as deployer
|
|
vm.startBroadcast();
|
|
CREATE2Factory factory = new CREATE2Factory();
|
|
deployer = address(factory);
|
|
vm.stopBroadcast();
|
|
|
|
console.log("Deployed CREATE2Factory at:", vm.toString(deployer));
|
|
}
|
|
|
|
console.log("\nTrying deployer:", vm.toString(deployer));
|
|
|
|
// Calculate salt (tries common values first, then sequential)
|
|
uint256 salt = findSaltForDeployer(deployer, bytecode, TARGET_WETH9);
|
|
|
|
if (salt != type(uint256).max) {
|
|
console.log("Found salt:", vm.toString(salt));
|
|
console.log("Deploying with CREATE2...");
|
|
|
|
// If using CREATE2Factory, deploy through it
|
|
if (deployer.code.length > 0) {
|
|
// Check if it's a CREATE2Factory (has deploy function)
|
|
vm.startBroadcast();
|
|
CREATE2Factory factory = CREATE2Factory(payable(deployer));
|
|
address deployed = factory.deploy(bytecode, salt);
|
|
|
|
if (deployed == TARGET_WETH9) {
|
|
console.log("OK Successfully deployed WETH9 at target address!");
|
|
verifyWETH9();
|
|
vm.stopBroadcast();
|
|
return;
|
|
} else {
|
|
console.log("ERROR Deployed to wrong address:", vm.toString(deployed));
|
|
vm.stopBroadcast();
|
|
}
|
|
} else {
|
|
// Direct CREATE2 deployment using assembly
|
|
vm.startBroadcast();
|
|
address deployed = deployCreate2(bytecode, salt);
|
|
|
|
if (deployed == TARGET_WETH9) {
|
|
console.log("OK Successfully deployed WETH9 at target address!");
|
|
verifyWETH9();
|
|
vm.stopBroadcast();
|
|
return;
|
|
} else {
|
|
console.log("ERROR Deployed to wrong address:", vm.toString(deployed));
|
|
vm.stopBroadcast();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
revert("Could not find valid salt/deployer combination");
|
|
}
|
|
|
|
function findSaltForDeployer(
|
|
address deployer,
|
|
bytes memory bytecode,
|
|
address target
|
|
) internal pure returns (uint256) {
|
|
bytes32 bytecodeHash = keccak256(bytecode);
|
|
|
|
// Try common salts first (much faster than brute force)
|
|
bytes32[] memory commonSalts = new bytes32[](15);
|
|
commonSalts[0] = bytes32(uint256(0));
|
|
commonSalts[1] = bytes32(uint256(1));
|
|
commonSalts[2] = bytes32(uint256(138)); // Chain ID
|
|
commonSalts[3] = keccak256("WETH9");
|
|
commonSalts[4] = keccak256("WETH");
|
|
commonSalts[5] = keccak256("Wrapped Ether");
|
|
commonSalts[6] = keccak256(abi.encodePacked(target));
|
|
commonSalts[7] = bytes32(uint256(uint160(target)));
|
|
commonSalts[8] = keccak256(abi.encodePacked("ChainID-138-WETH9"));
|
|
commonSalts[9] = keccak256(abi.encodePacked("ChainID", uint256(138), "WETH9"));
|
|
|
|
for (uint256 i = 10; i < 15; i++) {
|
|
commonSalts[i] = keccak256(abi.encodePacked("WETH9", i));
|
|
}
|
|
|
|
for (uint256 i = 0; i < commonSalts.length; i++) {
|
|
bytes32 hash = keccak256(
|
|
abi.encodePacked(bytes1(0xff), deployer, commonSalts[i], bytecodeHash)
|
|
);
|
|
if (address(uint160(uint256(hash))) == target) {
|
|
return uint256(commonSalts[i]);
|
|
}
|
|
}
|
|
|
|
// Limited sequential search (first 1000 for speed)
|
|
for (uint256 i = 0; i < 1000; i++) {
|
|
bytes32 salt = bytes32(i);
|
|
bytes32 hash = keccak256(
|
|
abi.encodePacked(bytes1(0xff), deployer, salt, bytecodeHash)
|
|
);
|
|
if (address(uint160(uint256(hash))) == target) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return type(uint256).max;
|
|
}
|
|
|
|
function deployCreate2(bytes memory bytecode, uint256 salt) internal returns (address) {
|
|
address addr;
|
|
assembly {
|
|
let ptr := mload(0x40)
|
|
let bytecodeLength := mload(bytecode)
|
|
let bytecodePtr := add(bytecode, 0x20)
|
|
codecopy(ptr, bytecodePtr, bytecodeLength)
|
|
addr := create2(0, ptr, bytecodeLength, salt)
|
|
if iszero(addr) { revert(0, 0) }
|
|
}
|
|
return addr;
|
|
}
|
|
|
|
function verifyWETH9() internal view {
|
|
WETH weth = WETH(payable(TARGET_WETH9));
|
|
console.log("WETH9 name:", weth.name());
|
|
console.log("WETH9 symbol:", weth.symbol());
|
|
console.log("WETH9 decimals:", weth.decimals());
|
|
}
|
|
}
|
|
|