diff --git a/remappings.txt b/remappings.txt index 72f9506..9b23047 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,3 +1,5 @@ -ds-test/=lib/forge-std/lib/ds-test/src/ +ds-test/=lib/socket-protocol/lib/forge-std/lib/ds-test/src/ forge-std/=lib/forge-std/src/ socket-protocol/=lib/socket-protocol/ +solady/=lib/socket-protocol/lib/solady/src/ +solmate/=lib/socket-protocol/lib/solmate/src/ diff --git a/script/SetupScript.sol b/script/SetupScript.sol new file mode 100644 index 0000000..192fc36 --- /dev/null +++ b/script/SetupScript.sol @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Script} from "forge-std/Script.sol"; +import {console} from "forge-std/console.sol"; +import {DepositFees} from "socket-protocol/script/PayFeesInArbitrumETH.s.sol"; +import {Fees} from "socket-protocol/contracts/protocol/utils/common/Structs.sol"; +import {FeesPlug} from "socket-protocol/contracts/protocol/payload-delivery/FeesPlug.sol"; +import {ETH_ADDRESS, FAST} from "socket-protocol/contracts/protocol/utils/common/Constants.sol"; +import {FeesManager} from "socket-protocol/contracts/protocol/payload-delivery/app-gateway/FeesManager.sol"; + +interface IAppGateway { + function withdrawFeeTokens(uint32 chainId, address token, uint256 amount, address recipient) external; +} + +interface IDeployer { + function deployContracts(uint32 chainId) external; +} + +abstract contract SetupScript is Script { + // ----- ENVIRONMENT VARIABLES ----- + string rpcEVMx = vm.envString("EVMX_RPC"); + string rpcArbSepolia = vm.envString("ARBITRUM_SEPOLIA_RPC"); + address addressResolver = vm.envAddress("ADDRESS_RESOLVER"); + address auctionManager = vm.envAddress("AUCTION_MANAGER"); + address feesPlugArbSepolia = vm.envAddress("ARBITRUM_FEES_PLUG"); + address feesManagerAddress = vm.envAddress("FEES_MANAGER"); + uint256 privateKey = vm.envUint("PRIVATE_KEY"); + address deployerAddress = vm.envAddress("DEPLOYER"); + address appGatewayAddress = vm.envAddress("APP_GATEWAY"); + + // ----- SCRIPT VARIABLES ----- + uint32 arbSepChainId = 411614; + uint32 opSepChainId = 11155420; + + Fees fees = Fees({feePoolChain: arbSepChainId, feePoolToken: ETH_ADDRESS, amount: 0.001 ether}); + FeesManager feesManager = FeesManager(payable(feesManagerAddress)); + FeesPlug feesPlug = FeesPlug(payable(feesPlugArbSepolia)); + + function checkDepositedFees(uint32 chainId) internal returns (uint256 availableFees) { + vm.createSelectFork(rpcEVMx); + + (uint256 deposited, uint256 blocked) = + feesManager.appGatewayFeeBalances(appGatewayAddress, chainId, ETH_ADDRESS); + console.log("App Gateway:", appGatewayAddress); + console.log("Deposited fees:", deposited); + console.log("Blocked fees:", blocked); + + availableFees = feesManager.getAvailableFees(chainId, appGatewayAddress, ETH_ADDRESS); + console.log("Available fees:", availableFees); + } + + function withdrawAppFees(uint32 chainId) internal { + // EVMX Check available fees + vm.createSelectFork(rpcEVMx); + + uint256 availableFees = feesManager.getAvailableFees(chainId, appGatewayAddress, ETH_ADDRESS); + console.log("Available fees:", availableFees); + + if (availableFees > 0) { + // Switch to Arbitrum Sepolia to get gas price + vm.createSelectFork(rpcArbSepolia); + + // Gas price from Arbitrum + uint256 arbitrumGasPrice = block.basefee + 0.1 gwei; // With buffer + uint256 gasLimit = 5_000_000; // Estimate + uint256 estimatedGasCost = gasLimit * arbitrumGasPrice; + + console.log("Arbitrum gas price (wei):", arbitrumGasPrice); + console.log("Gas limit:", gasLimit); + console.log("Estimated gas cost:", estimatedGasCost); + + // Calculate amount to withdraw + uint256 amountToWithdraw = availableFees > estimatedGasCost ? availableFees - estimatedGasCost : 0; + + if (amountToWithdraw > 0) { + // Switch back to EVMX to perform withdrawal + vm.createSelectFork(rpcEVMx); + vm.startBroadcast(privateKey); + address sender = vm.addr(privateKey); + console.log("Withdrawing amount:", amountToWithdraw); + IAppGateway(appGateway()).withdrawFeeTokens(chainId, ETH_ADDRESS, amountToWithdraw, sender); + vm.stopBroadcast(); + + // Switch back to Arbitrum Sepolia to check final balance + vm.createSelectFork(rpcArbSepolia); + console.log("Final sender balance:", sender.balance); + } else { + console.log("Available fees less than estimated gas cost"); + } + } + } + + function deployOnchainContracts(uint32[] memory chainIds) internal { + vm.createSelectFork(rpcEVMx); + vm.startBroadcast(privateKey); + + for (uint256 i = 0; i < chainIds.length; i++) { + IDeployer(deployer()).deployContracts(chainIds[i]); + } + + vm.stopBroadcast(); + console.log("Contracts deployed"); + } + + // Abstract functions to be implemented by child contracts + function appGateway() internal view virtual returns (address); + function deployer() internal view virtual returns (address); + + // Standard flow + // Each implementation script will call these functions + function _run(uint32 chainId) internal { + uint256 availableFees = checkDepositedFees(chainId); + + if (availableFees > 0) { + executeScriptSpecificLogic(); + withdrawAppFees(chainId); + } else { + console.log("NO AVAILABLE FEES - Please deposit fees before running this script"); + } + } + + // Abstract function to be implemented by child contracts + function executeScriptSpecificLogic() internal virtual; +} diff --git a/script/deployment-mistakes/DeployEVMxDeploymentMistakesApp.s.sol b/script/deployment-mistakes/DeployEVMxDeploymentMistakesApp.s.sol index 4f9e2e0..d7cba33 100644 --- a/script/deployment-mistakes/DeployEVMxDeploymentMistakesApp.s.sol +++ b/script/deployment-mistakes/DeployEVMxDeploymentMistakesApp.s.sol @@ -9,7 +9,7 @@ import {ETH_ADDRESS, FAST} from "socket-protocol/contracts/protocol/utils/common import {DeploymentMistakesAppGateway} from "../../src/deployment-mistakes/DeploymentMistakesAppGateway.sol"; import {DeploymentMistakesDeployer} from "../../src/deployment-mistakes/DeploymentMistakesDeployer.sol"; -contract DeployMistakes is Script { +contract DeployEVMxContracts is Script { function run() external { address addressResolver = vm.envAddress("ADDRESS_RESOLVER"); address auctionManager = vm.envAddress("AUCTION_MANAGER"); diff --git a/script/deployment-mistakes/RunEVMxDeploymentMistakes.s.sol b/script/deployment-mistakes/RunEVMxDeploymentMistakes.s.sol index 8d7d308..7e9d680 100644 --- a/script/deployment-mistakes/RunEVMxDeploymentMistakes.s.sol +++ b/script/deployment-mistakes/RunEVMxDeploymentMistakes.s.sol @@ -1,14 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {Script} from "forge-std/Script.sol"; import {console} from "forge-std/console.sol"; -import {DepositFees} from "socket-protocol/script/PayFeesInArbitrumETH.s.sol"; -import {Fees} from "socket-protocol/contracts/protocol/utils/common/Structs.sol"; -import {FeesPlug} from "socket-protocol/contracts/protocol/payload-delivery/FeesPlug.sol"; -import {ETH_ADDRESS, FAST} from "socket-protocol/contracts/protocol/utils/common/Constants.sol"; -import {FeesManager} from "socket-protocol/contracts/protocol/payload-delivery/app-gateway/FeesManager.sol"; - +import {SetupScript} from "../SetupScript.sol"; import {DeploymentMistakesAppGateway} from "../../src/deployment-mistakes/DeploymentMistakesAppGateway.sol"; import {DeploymentMistakesDeployer} from "../../src/deployment-mistakes/DeploymentMistakesDeployer.sol"; import { @@ -20,28 +14,9 @@ import { PlugNoInitInitialize } from "../../src/deployment-mistakes/DeployOnchainMistakes.sol"; -contract RunEVMxDeploy is Script { - // ----- ENVIRONMENT VARIABLES ----- - string rpcEVMx = vm.envString("EVMX_RPC"); - string rpcArbSepolia = vm.envString("ARBITRUM_SEPOLIA_RPC"); - address addressResolver = vm.envAddress("ADDRESS_RESOLVER"); - address auctionManager = vm.envAddress("AUCTION_MANAGER"); - address feesPlugArbSepolia = vm.envAddress("ARBITRUM_FEES_PLUG"); - address feesManagerAddress = vm.envAddress("FEES_MANAGER"); - uint256 privateKey = vm.envUint("PRIVATE_KEY"); - address deployerAddress = vm.envAddress("DEPLOYER"); - address appGatewayAddress = vm.envAddress("APP_GATEWAY"); - - // ----- SCRIPT VARIABLES ----- - uint32 arbSepChainId = 411614; - uint32 opSepChainId = 11155420; - - Fees fees = Fees({feePoolChain: arbSepChainId, feePoolToken: ETH_ADDRESS, amount: 0.001 ether}); - FeesManager feesManager = FeesManager(payable(feesManagerAddress)); - FeesPlug feesPlug = FeesPlug(payable(feesPlugArbSepolia)); - - DeploymentMistakesDeployer deployer = DeploymentMistakesDeployer(deployerAddress); - DeploymentMistakesAppGateway appGateway = DeploymentMistakesAppGateway(appGatewayAddress); +contract RunEVMxDeploymentMistakes is SetupScript { + DeploymentMistakesDeployer mistakesDeployer; + DeploymentMistakesAppGateway mistakesAppGateway; address noPlugNoInititializeForwarder; address noPlugInitializeForwarder; address plugNoInitializeForwarder; @@ -49,88 +24,38 @@ contract RunEVMxDeploy is Script { address plugInitializeTwiceForwarder; address plugNoInitInitializeForwarder; - function checkDepositedFees(uint32 chainId) internal returns (uint256 availableFees) { - vm.createSelectFork(rpcEVMx); - - (uint256 deposited, uint256 blocked) = - feesManager.appGatewayFeeBalances(appGatewayAddress, chainId, ETH_ADDRESS); - console.log("App Gateway:", appGatewayAddress); - console.log("Deposited fees:", deposited); - console.log("Blocked fees:", blocked); - - availableFees = feesManager.getAvailableFees(chainId, appGatewayAddress, ETH_ADDRESS); - console.log("Available fees:", availableFees); + function appGateway() internal view override returns (address) { + return address(mistakesAppGateway); } - function withdrawAppFees(uint32 chainId) internal { - // EVMX Check available fees - vm.createSelectFork(rpcEVMx); - - uint256 availableFees = feesManager.getAvailableFees(chainId, appGatewayAddress, ETH_ADDRESS); - console.log("Available fees:", availableFees); - - if (availableFees > 0) { - // Switch to Arbitrum Sepolia to get gas price - vm.createSelectFork(rpcArbSepolia); - - // Gas price from Arbitrum - uint256 arbitrumGasPrice = block.basefee + 0.1 gwei; // With buffer - uint256 gasLimit = 5_000_000; // Estimate - uint256 estimatedGasCost = gasLimit * arbitrumGasPrice; - - console.log("Arbitrum gas price (wei):", arbitrumGasPrice); - console.log("Gas limit:", gasLimit); - console.log("Estimated gas cost:", estimatedGasCost); - - // Calculate amount to withdraw - uint256 amountToWithdraw = availableFees > estimatedGasCost ? availableFees - estimatedGasCost : 0; - - if (amountToWithdraw > 0) { - // Switch back to EVMX to perform withdrawal - vm.createSelectFork(rpcEVMx); - vm.startBroadcast(privateKey); - address sender = vm.addr(privateKey); - console.log("Withdrawing amount:", amountToWithdraw); - appGateway.withdrawFeeTokens(chainId, ETH_ADDRESS, amountToWithdraw, sender); - vm.stopBroadcast(); - - // Switch back to Arbitrum Sepolia to check final balance - vm.createSelectFork(rpcArbSepolia); - console.log("Final sender balance:", sender.balance); - } else { - console.log("Available fees less than estimated gas cost"); - } - } - } - - function deployOnchainContracts() internal { - vm.createSelectFork(rpcEVMx); - vm.startBroadcast(privateKey); - deployer.deployContracts(arbSepChainId); - vm.stopBroadcast(); - - console.log("Contracts deployed"); + function deployer() internal view override returns (address) { + return address(mistakesDeployer); } function getForwarderAddresses() internal { vm.createSelectFork(rpcEVMx); - noPlugNoInititializeForwarder = deployer.forwarderAddresses(deployer.noPlugNoInititialize(), arbSepChainId); + noPlugNoInititializeForwarder = + mistakesDeployer.forwarderAddresses(mistakesDeployer.noPlugNoInititialize(), arbSepChainId); console.log("No Plug No Init Forwarder:", noPlugNoInititializeForwarder); - noPlugInitializeForwarder = deployer.forwarderAddresses(deployer.noPlugInitialize(), arbSepChainId); + noPlugInitializeForwarder = + mistakesDeployer.forwarderAddresses(mistakesDeployer.noPlugInitialize(), arbSepChainId); console.log("No Plug Init Forwarder:", noPlugInitializeForwarder); - plugNoInitializeForwarder = deployer.forwarderAddresses(deployer.plugNoInitialize(), arbSepChainId); + plugNoInitializeForwarder = + mistakesDeployer.forwarderAddresses(mistakesDeployer.plugNoInitialize(), arbSepChainId); console.log("Plug No Init Forwarder:", plugNoInitializeForwarder); - plugInitializeForwarder = deployer.forwarderAddresses(deployer.plugInitialize(), arbSepChainId); + plugInitializeForwarder = mistakesDeployer.forwarderAddresses(mistakesDeployer.plugInitialize(), arbSepChainId); console.log("Plug Init Forwarder:", plugInitializeForwarder); - plugInitializeTwiceForwarder = deployer.forwarderAddresses(deployer.plugInitializeTwice(), arbSepChainId); + plugInitializeTwiceForwarder = + mistakesDeployer.forwarderAddresses(mistakesDeployer.plugInitializeTwice(), arbSepChainId); console.log("Plug Init Init Forwarder:", plugInitializeTwiceForwarder); - plugNoInitInitializeForwarder = deployer.forwarderAddresses(deployer.plugNoInitInitialize(), arbSepChainId); + plugNoInitInitializeForwarder = + mistakesDeployer.forwarderAddresses(mistakesDeployer.plugNoInitInitialize(), arbSepChainId); console.log("Plug No Init Init Forwarder:", plugNoInitInitializeForwarder); } @@ -180,19 +105,21 @@ contract RunEVMxDeploy is Script { vm.stopBroadcast(); } - function run() external { - uint256 availableFees = checkDepositedFees(arbSepChainId); + function executeScriptSpecificLogic() internal override { + // Initialize contract references + mistakesDeployer = DeploymentMistakesDeployer(deployerAddress); + mistakesAppGateway = DeploymentMistakesAppGateway(appGatewayAddress); - if (availableFees > 0) { - // Set up onchain deployments - deployOnchainContracts(); - getForwarderAddresses(); + // Deploy only to Arbitrum Sepolia + uint32[] memory chainIds = new uint32[](1); + chainIds[0] = arbSepChainId; + deployOnchainContracts(chainIds); - validateMistakes(); + getForwarderAddresses(); + validateMistakes(); + } - withdrawAppFees(arbSepChainId); - } else { - console.log("NO AVAILABLE FEES - Please deposit fees before running this script"); - } + function run() external { + _run(arbSepChainId); } } diff --git a/script/inbox/DeployEVMxInbox.s.sol b/script/inbox/DeployEVMxInbox.s.sol new file mode 100644 index 0000000..68da615 --- /dev/null +++ b/script/inbox/DeployEVMxInbox.s.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {Script} from "forge-std/Script.sol"; +import {console} from "forge-std/console.sol"; +import {Fees} from "socket-protocol/contracts/protocol/utils/common/Structs.sol"; +import {ETH_ADDRESS, FAST} from "socket-protocol/contracts/protocol/utils/common/Constants.sol"; + +import {InboxAppGateway} from "../../src/inbox/InboxAppGateway.sol"; +import {InboxDeployer} from "../../src/inbox/InboxDeployer.sol"; + +contract DeployEVMxContracts is Script { + function run() external { + address addressResolver = vm.envAddress("ADDRESS_RESOLVER"); + address auctionManager = vm.envAddress("AUCTION_MANAGER"); + string memory rpc = vm.envString("EVMX_RPC"); + vm.createSelectFork(rpc); + + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + vm.startBroadcast(deployerPrivateKey); + + Fees memory fees = Fees({feePoolChain: 421614, feePoolToken: ETH_ADDRESS, amount: 0.001 ether}); + + InboxDeployer deployer = new InboxDeployer(addressResolver, auctionManager, FAST, fees); + + InboxAppGateway gateway = new InboxAppGateway(addressResolver, address(deployer), auctionManager, fees); + + console.log("Contracts deployed:"); + console.log("Deployer:", address(deployer)); + console.log("AppGateway:", address(gateway)); + } +} diff --git a/script/inbox/RunEVMxInbox.s.sol b/script/inbox/RunEVMxInbox.s.sol new file mode 100644 index 0000000..8535c55 --- /dev/null +++ b/script/inbox/RunEVMxInbox.s.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {console} from "forge-std/console.sol"; +import {SetupScript} from "../SetupScript.sol"; +import {InboxDeployer} from "../../src/inbox/InboxDeployer.sol"; +import {InboxAppGateway, IInbox} from "../../src/inbox/InboxAppGateway.sol"; + +contract RunEVMxInbox is SetupScript { + InboxDeployer inboxDeployer; + InboxAppGateway inboxAppGateway; + address opSepForwarder; + address arbSepForwarder; + + function appGateway() internal view override returns (address) { + return address(inboxAppGateway); + } + + function deployer() internal view override returns (address) { + return address(inboxDeployer); + } + + function getForwarderAddresses() internal { + vm.createSelectFork(rpcEVMx); + opSepForwarder = inboxDeployer.forwarderAddresses(inboxDeployer.inbox(), opSepChainId); + arbSepForwarder = inboxDeployer.forwarderAddresses(inboxDeployer.inbox(), arbSepChainId); + + console.log("Optimism Sepolia Forwarder:", opSepForwarder); + console.log("Arbitrum Sepolia Forwarder:", arbSepForwarder); + } + + function inboxTransactions() internal { + address opSepInboxAddress = inboxDeployer.getOnChainAddress(inboxDeployer.inbox(), opSepChainId); + address arbSepInboxAddress = inboxDeployer.getOnChainAddress(inboxDeployer.inbox(), arbSepChainId); + + vm.createSelectFork(rpcEVMx); + vm.startBroadcast(privateKey); + + IInbox(opSepInboxAddress).increaseOnGateway(5); + require(inboxAppGateway.valueOnGateway() != 5, "Expected the same value"); + inboxAppGateway.updateOnchain(opSepChainId); + require(IInbox(opSepInboxAddress).value() != 5, "Expected the same value"); + IInbox(opSepInboxAddress).propagateToAnother(arbSepChainId); + require(IInbox(arbSepInboxAddress).value() != 5, "Expected the same value"); + + vm.stopBroadcast(); + console.log("All inbox transactions executed successfully"); + } + + function executeScriptSpecificLogic() internal override { + // Initialize contract references + inboxDeployer = InboxDeployer(deployerAddress); + inboxAppGateway = InboxAppGateway(appGatewayAddress); + + // Deploy to both test chains + uint32[] memory chainIds = new uint32[](2); + chainIds[0] = opSepChainId; + chainIds[1] = arbSepChainId; + deployOnchainContracts(chainIds); + + getForwarderAddresses(); + inboxTransactions(); + } + + function run() external { + _run(arbSepChainId); + } +} diff --git a/script/robust/RunEVMxRobustness.s.sol b/script/robust/RunEVMxRobustness.s.sol index ca7d929..e819cb7 100644 --- a/script/robust/RunEVMxRobustness.s.sol +++ b/script/robust/RunEVMxRobustness.s.sol @@ -1,110 +1,29 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {Script} from "forge-std/Script.sol"; import {console} from "forge-std/console.sol"; -import {DepositFees} from "socket-protocol/script/PayFeesInArbitrumETH.s.sol"; -import {Fees} from "socket-protocol/contracts/protocol/utils/common/Structs.sol"; -import {FeesPlug} from "socket-protocol/contracts/protocol/payload-delivery/FeesPlug.sol"; -import {ETH_ADDRESS, FAST} from "socket-protocol/contracts/protocol/utils/common/Constants.sol"; -import {FeesManager} from "socket-protocol/contracts/protocol/payload-delivery/app-gateway/FeesManager.sol"; - +import {SetupScript} from "../SetupScript.sol"; import {RobustnessDeployer} from "../../src/robustness/RobustnessDeployer.sol"; import {RobustnessAppGateway} from "../../src/robustness/RobustnessAppGateway.sol"; -contract RunEVMxRobustness is Script { - // ----- ENVIRONMENT VARIABLES ----- - string rpcEVMx = vm.envString("EVMX_RPC"); - string rpcArbSepolia = vm.envString("ARBITRUM_SEPOLIA_RPC"); - address addressResolver = vm.envAddress("ADDRESS_RESOLVER"); - address auctionManager = vm.envAddress("AUCTION_MANAGER"); - address feesPlugArbSepolia = vm.envAddress("ARBITRUM_FEES_PLUG"); - address feesManagerAddress = vm.envAddress("FEES_MANAGER"); - uint256 privateKey = vm.envUint("PRIVATE_KEY"); - address deployerAddress = vm.envAddress("DEPLOYER"); - address appGatewayAddress = vm.envAddress("APP_GATEWAY"); - - // ----- SCRIPT VARIABLES ----- - uint32 arbSepChainId = 411614; - uint32 opSepChainId = 11155420; - - Fees fees = Fees({feePoolChain: arbSepChainId, feePoolToken: ETH_ADDRESS, amount: 0.001 ether}); - FeesManager feesManager = FeesManager(payable(feesManagerAddress)); - FeesPlug feesPlug = FeesPlug(payable(feesPlugArbSepolia)); - - RobustnessDeployer deployer = RobustnessDeployer(deployerAddress); - RobustnessAppGateway appGateway = RobustnessAppGateway(appGatewayAddress); +contract RunEVMxRobustness is SetupScript { + RobustnessDeployer robustnessDeployer; + RobustnessAppGateway robustnessAppGateway; address opSepForwarder; address arbSepForwarder; - function checkDepositedFees(uint32 chainId) internal returns (uint256 availableFees) { - vm.createSelectFork(rpcEVMx); - - (uint256 deposited, uint256 blocked) = - feesManager.appGatewayFeeBalances(appGatewayAddress, chainId, ETH_ADDRESS); - console.log("App Gateway:", appGatewayAddress); - console.log("Deposited fees:", deposited); - console.log("Blocked fees:", blocked); - - availableFees = feesManager.getAvailableFees(chainId, appGatewayAddress, ETH_ADDRESS); - console.log("Available fees:", availableFees); + function appGateway() internal view override returns (address) { + return address(robustnessAppGateway); } - function withdrawAppFees(uint32 chainId) internal { - // EVMX Check available fees - vm.createSelectFork(rpcEVMx); - - uint256 availableFees = feesManager.getAvailableFees(chainId, appGatewayAddress, ETH_ADDRESS); - console.log("Available fees:", availableFees); - - if (availableFees > 0) { - // Switch to Arbitrum Sepolia to get gas price - vm.createSelectFork(rpcArbSepolia); - - // Gas price from Arbitrum - uint256 arbitrumGasPrice = block.basefee + 0.1 gwei; // With buffer - uint256 gasLimit = 5_000_000; // Estimate - uint256 estimatedGasCost = gasLimit * arbitrumGasPrice; - - console.log("Arbitrum gas price (wei):", arbitrumGasPrice); - console.log("Gas limit:", gasLimit); - console.log("Estimated gas cost:", estimatedGasCost); - - // Calculate amount to withdraw - uint256 amountToWithdraw = availableFees > estimatedGasCost ? availableFees - estimatedGasCost : 0; - - if (amountToWithdraw > 0) { - // Switch back to EVMX to perform withdrawal - vm.createSelectFork(rpcEVMx); - vm.startBroadcast(privateKey); - address sender = vm.addr(privateKey); - console.log("Withdrawing amount:", amountToWithdraw); - appGateway.withdrawFeeTokens(chainId, ETH_ADDRESS, amountToWithdraw, sender); - vm.stopBroadcast(); - - // Switch back to Arbitrum Sepolia to check final balance - vm.createSelectFork(rpcArbSepolia); - console.log("Final sender balance:", sender.balance); - } else { - console.log("Available fees less than estimated gas cost"); - } - } - } - - function deployOnchainContracts() internal { - vm.createSelectFork(rpcEVMx); - vm.startBroadcast(privateKey); - deployer.deployContracts(opSepChainId); - deployer.deployContracts(arbSepChainId); - vm.stopBroadcast(); - - console.log("Contracts deployed"); + function deployer() internal view override returns (address) { + return address(robustnessDeployer); } function getForwarderAddresses() internal { vm.createSelectFork(rpcEVMx); - opSepForwarder = deployer.forwarderAddresses(deployer.multichain(), opSepChainId); - arbSepForwarder = deployer.forwarderAddresses(deployer.multichain(), arbSepChainId); + opSepForwarder = robustnessDeployer.forwarderAddresses(robustnessDeployer.multichain(), opSepChainId); + arbSepForwarder = robustnessDeployer.forwarderAddresses(robustnessDeployer.multichain(), arbSepChainId); console.log("Optimism Sepolia Forwarder:", opSepForwarder); console.log("Arbitrum Sepolia Forwarder:", arbSepForwarder); @@ -118,31 +37,31 @@ contract RunEVMxRobustness is Script { // 1. Trigger Sequential Write console.log("triggerSequentialWrite..."); - appGateway.triggerSequentialWrite(opSepForwarder); + robustnessAppGateway.triggerSequentialWrite(opSepForwarder); // 2. Trigger Parallel Write console.log("triggerParallelWrite..."); - appGateway.triggerParallelWrite(arbSepForwarder); + robustnessAppGateway.triggerParallelWrite(arbSepForwarder); // 3. Trigger Alternating Write between chains console.log("triggerAltWrite..."); - appGateway.triggerAltWrite(opSepForwarder, arbSepForwarder); + robustnessAppGateway.triggerAltWrite(opSepForwarder, arbSepForwarder); // 4. Trigger Parallel Read console.log("triggerParallelRead..."); - appGateway.triggerParallelRead(opSepForwarder); + robustnessAppGateway.triggerParallelRead(opSepForwarder); // 5. Trigger Alternating Read between chains console.log("triggerAltRead..."); - appGateway.triggerAltRead(opSepForwarder, arbSepForwarder); + robustnessAppGateway.triggerAltRead(opSepForwarder, arbSepForwarder); // 6. Trigger Read and Write console.log("triggerReadAndWrite..."); - appGateway.triggerReadAndWrite(arbSepForwarder); + robustnessAppGateway.triggerReadAndWrite(arbSepForwarder); // 7. Trigger Timeouts console.log("triggerTimeouts..."); - appGateway.triggerTimeouts(); + robustnessAppGateway.triggerTimeouts(); vm.stopBroadcast(); console.log("All triggers executed successfully"); @@ -156,7 +75,7 @@ contract RunEVMxRobustness is Script { // Check values array console.log("Values array:"); for (uint256 i = 0; i < 10; i++) { - try appGateway.values(i) returns (uint256 value) { + try robustnessAppGateway.values(i) returns (uint256 value) { console.log("values[%s]: %s", i, value); } catch { console.log("values[%s]: not set", i); @@ -167,8 +86,8 @@ contract RunEVMxRobustness is Script { // Check resolve times for timeouts console.log("\nTimeout resolve times:"); for (uint256 i = 0; i < 10; i++) { - uint256 resolveTime = appGateway.resolveTimes(i); - uint256 duration = appGateway.timeoutDurations(i); + uint256 resolveTime = robustnessAppGateway.resolveTimes(i); + uint256 duration = robustnessAppGateway.timeoutDurations(i); if (resolveTime > 0) { console.log("Timeout %s (duration %s): resolved at timestamp %s", i, duration, resolveTime); } else { @@ -177,20 +96,23 @@ contract RunEVMxRobustness is Script { } } - function run() external { - uint256 availableFees = checkDepositedFees(arbSepChainId); + function executeScriptSpecificLogic() internal override { + // Initialize contract references + robustnessDeployer = RobustnessDeployer(deployerAddress); + robustnessAppGateway = RobustnessAppGateway(appGatewayAddress); - if (availableFees > 0) { - // Set up onchain deployments - deployOnchainContracts(); - getForwarderAddresses(); + // Deploy to both test chains + uint32[] memory chainIds = new uint32[](2); + chainIds[0] = opSepChainId; + chainIds[1] = arbSepChainId; + deployOnchainContracts(chainIds); - runAllTriggers(); - checkResults(); // TODO: Check if we need to wait before checking the results + getForwarderAddresses(); + runAllTriggers(); + checkResults(); + } - withdrawAppFees(arbSepChainId); - } else { - console.log("NO AVAILABLE FEES - Please deposit fees before running this script"); - } + function run() external { + _run(arbSepChainId); } } diff --git a/src/inbox/Inbox.sol b/src/inbox/Inbox.sol new file mode 100644 index 0000000..0daf05a --- /dev/null +++ b/src/inbox/Inbox.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.21; + +import "solady/auth/Ownable.sol"; +import "socket-protocol/contracts/base/PlugBase.sol"; + +contract Inbox is Ownable, PlugBase { + uint256 public value; + + // Message types + uint32 public constant INCREASE_ON_GATEWAY = 1; + uint32 public constant PROPAGATE_TO_ANOTHER = 2; + + function increaseOnGateway(uint256 value_) external returns (bytes32) { + return _callAppGateway( + abi.encode(INCREASE_ON_GATEWAY, abi.encode(value_)), + bytes32(0) + ); + } + + function propagateToAnother(uint32 targetChain) external returns (bytes32) { + return _callAppGateway( + abi.encode(PROPAGATE_TO_ANOTHER, abi.encode(value, targetChain)), + bytes32(0) + ); + } + + function updateFromGateway(uint256 value_) external onlySocket { + value = value_; + } +} diff --git a/src/inbox/InboxAppGateway.sol b/src/inbox/InboxAppGateway.sol new file mode 100644 index 0000000..55e3caa --- /dev/null +++ b/src/inbox/InboxAppGateway.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.0; +import "socket-protocol/contracts/base/AppGatewayBase.sol"; + +interface IInboxDeployer { + function inbox() external pure returns (bytes32 bytecode); + + function forwarderAddresses( + bytes32 contractId_, + uint32 chainSlug_ + ) external view returns (address forwarderAddress); +} + +interface IInbox { + function value() external returns (uint256); + function increaseOnGateway(uint256 value_) external returns (bytes32); + function propagateToAnother(uint32 targetChain) external returns (bytes32); + function updateFromGateway(uint256 value) external; +} + +contract InboxAppGateway is AppGatewayBase { + uint256 public valueOnGateway; + address deployerAddress; + + // Message types + uint32 public constant INCREASE_ON_GATEWAY = 1; + uint32 public constant PROPAGATE_TO_ANOTHER = 2; + + constructor( + address addressResolver_, + address deployerContract_, + address auctionManager_, + Fees memory fees_ + ) AppGatewayBase(addressResolver_, auctionManager_) { + addressResolver__.setContractsToGateways(deployerContract_); + deployerAddress = deployerContract_; + _setOverrides(fees_); + } + + function updateOnchain(uint32 targetChain) public { + address inboxForwarderAddress = IInboxDeployer(deployerAddress).forwarderAddresses(IInboxDeployer(deployerAddress).inbox(), targetChain); + IInbox(inboxForwarderAddress).updateFromGateway(valueOnGateway); + } + + function callFromInbox( + uint32, + address, + bytes calldata payload_, + bytes32 + ) external override onlyWatcherPrecompile { + (uint32 msgType, bytes memory payload) = abi.decode(payload_, (uint32, bytes)); + if (msgType == INCREASE_ON_GATEWAY) { + uint256 valueOnchain = abi.decode(payload, (uint256)); + valueOnGateway += valueOnchain; + } else if (msgType == PROPAGATE_TO_ANOTHER) { + (uint256 valueOnchain, uint32 targetChain) = abi.decode(payload, (uint256, uint32)); + address inboxForwarderAddress = IInboxDeployer(deployerAddress).forwarderAddresses(IInboxDeployer(deployerAddress).inbox(), targetChain); + IInbox(inboxForwarderAddress).updateFromGateway(valueOnchain); + } else { + revert("InboxGateway: invalid message type"); + } + } + + function setFees(Fees memory fees_) public { + fees = fees_; + } + + function withdrawFeeTokens(uint32 chainSlug_, address token_, uint256 amount_, address receiver_) external { + _withdrawFeeTokens(chainSlug_, token_, amount_, receiver_); + } +} diff --git a/src/inbox/InboxDeployer.sol b/src/inbox/InboxDeployer.sol new file mode 100644 index 0000000..f1dca30 --- /dev/null +++ b/src/inbox/InboxDeployer.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.0; + +import "socket-protocol/contracts/base/AppDeployerBase.sol"; +import "./Inbox.sol"; + +contract InboxDeployer is AppDeployerBase { + bytes32 public inbox = _createContractId("inbox"); + + constructor(address addressResolver_, address auctionManager_, bytes32 sbType_, Fees memory fees_) + AppDeployerBase(addressResolver_, auctionManager_, sbType_) + { + creationCodeWithArgs[inbox] = abi.encodePacked(type(Inbox).creationCode); + _setOverrides(fees_); + } + + function deployContracts(uint32 chainSlug_) external async { + _deploy(inbox, chainSlug_, IsPlug.YES); + } + + function initialize(uint32) public pure override { + return; + } + + function setFees(Fees memory fees_) public { + fees = fees_; + } +}