From 87ac7494d2bcf316d8791eeada920b2af16220bc Mon Sep 17 00:00:00 2001 From: FelixFan1992 Date: Wed, 26 Jun 2024 17:10:10 -0400 Subject: [PATCH] AUTO-10161: the second approach --- .../ZKSyncAutomationRegistry2_2.sol | 42 +++++++++++++++---- .../ZKSyncAutomationRegistryBase2_2.sol | 22 +--------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/contracts/src/v0.8/automation/v2_2_zksync/ZKSyncAutomationRegistry2_2.sol b/contracts/src/v0.8/automation/v2_2_zksync/ZKSyncAutomationRegistry2_2.sol index 974b6dd9bd2..ea7a6bf3967 100644 --- a/contracts/src/v0.8/automation/v2_2_zksync/ZKSyncAutomationRegistry2_2.sol +++ b/contracts/src/v0.8/automation/v2_2_zksync/ZKSyncAutomationRegistry2_2.sol @@ -9,6 +9,13 @@ import {Chainable} from "../Chainable.sol"; import {IERC677Receiver} from "../../shared/interfaces/IERC677Receiver.sol"; import {OCR2Abstract} from "../../shared/ocr2/OCR2Abstract.sol"; +interface ISystemContext { + function gasPerPubdataByte() external view returns (uint256 gasPerPubdataByte); + function getCurrentPubdataSpent() external view returns (uint256 currentPubdataSpent); +} + +ISystemContext constant SYSTEM_CONTEXT_CONTRACT = ISystemContext(address(0x800b)); + /** * @notice Registry for adding work for Chainlink nodes to perform on client * contracts. Clients must support the AutomationCompatibleInterface interface. @@ -63,7 +70,6 @@ contract ZKSyncAutomationRegistry2_2 is ZKSyncAutomationRegistryBase2_2, OCR2Abs // solhint-disable-next-line gas-struct-packing struct TransmitVars { uint16 numUpkeepsPassedChecks; -// uint256 totalCalldataWeight; uint96 totalReimbursement; uint96 totalPremium; } @@ -109,13 +115,11 @@ contract ZKSyncAutomationRegistry2_2 is ZKSyncAutomationRegistryBase2_2, OCR2Abs UpkeepTransmitInfo[] memory upkeepTransmitInfo = new UpkeepTransmitInfo[](report.upkeepIds.length); TransmitVars memory transmitVars = TransmitVars({ numUpkeepsPassedChecks: 0, -// totalCalldataWeight: 0, totalReimbursement: 0, totalPremium: 0 }); uint256 blocknumber = hotVars.chainModule.blockNumber(); -// uint256 l1Fee = hotVars.chainModule.getCurrentL1Fee(); for (uint256 i = 0; i < report.upkeepIds.length; i++) { upkeepTransmitInfo[i].upkeep = s_upkeep[report.upkeepIds[i]]; @@ -136,16 +140,30 @@ contract ZKSyncAutomationRegistry2_2 is ZKSyncAutomationRegistryBase2_2, OCR2Abs } // Actually perform the target upkeep + uint256 p1 = SYSTEM_CONTEXT_CONTRACT.getCurrentPubdataSpent(); (upkeepTransmitInfo[i].performSuccess, upkeepTransmitInfo[i].gasUsed) = _performUpkeep( upkeepTransmitInfo[i].upkeep.forwarder, report.gasLimits[i], report.performDatas[i] ); + uint256 p2 = SYSTEM_CONTEXT_CONTRACT.getCurrentPubdataSpent(); + uint256 pubdataUsed; + if (p2 > p1) { + pubdataUsed = p2 - p1; + } + uint256 gasPerPubdataByte = SYSTEM_CONTEXT_CONTRACT.gasPerPubdataByte(); + upkeepTransmitInfo[i].l1GasUsed = gasPerPubdataByte * pubdataUsed; + if (report.gasLimits[i] < upkeepTransmitInfo[i].l1GasUsed + upkeepTransmitInfo[i].gasUsed) { + // revert or ? + revert InsufficientGas(upkeepTransmitInfo[i].gasUsed, upkeepTransmitInfo[i].l1GasUsed); + } + emit GasDetails(pubdataUsed, gasPerPubdataByte, upkeepTransmitInfo[i].gasUsed, p1, p2, tx.gasprice); // Deduct that gasUsed by upkeep from our running counter - // for zksync, the L1 gas is deducted at the end of a transaction but gasUsed here already has all the cost - // if we don't add l1GasUsed here for zksync, `gasOverhead - gasleft()` will underflow - gasOverhead -= upkeepTransmitInfo[i].gasUsed; + // for zksync, the L1 gas is deducted at the end of a transaction + // so gasleft() is actually higher than it's actual value by (upkeepTransmitInfo[i].l1GasUsed) amount + // ?? + gasOverhead = gasOverhead + upkeepTransmitInfo[i].l1GasUsed - upkeepTransmitInfo[i].gasUsed; // Store last perform block number / deduping key for upkeep _updateTriggerMarker(report.upkeepIds[i], blocknumber, upkeepTransmitInfo[i]); @@ -173,7 +191,7 @@ contract ZKSyncAutomationRegistry2_2 is ZKSyncAutomationRegistryBase2_2, OCR2Abs report.fastGasWei, report.linkNative, gasOverhead, - 0 + upkeepTransmitInfo[i].l1GasUsed * tx.gasprice ); transmitVars.totalPremium += premium; transmitVars.totalReimbursement += reimbursement; @@ -216,7 +234,17 @@ contract ZKSyncAutomationRegistry2_2 is ZKSyncAutomationRegistryBase2_2, OCR2Abs if (s_hotVars.paused) revert RegistryPaused(); Upkeep memory upkeep = s_upkeep[id]; + uint256 p1 = SYSTEM_CONTEXT_CONTRACT.getCurrentPubdataSpent(); (success, gasUsed) = _performUpkeep(upkeep.forwarder, upkeep.performGas, performData); + uint256 p2 = SYSTEM_CONTEXT_CONTRACT.getCurrentPubdataSpent(); + uint256 pubdataUsed; + if (p2 > p1) { + pubdataUsed = p2 - p1; + } + uint256 gasPerPubdataByte = SYSTEM_CONTEXT_CONTRACT.gasPerPubdataByte(); + if (upkeep.performGas < pubdataUsed * gasPerPubdataByte + gasUsed) { + return (false, pubdataUsed * gasPerPubdataByte + gasUsed); + } return (success, gasUsed); } diff --git a/contracts/src/v0.8/automation/v2_2_zksync/ZKSyncAutomationRegistryBase2_2.sol b/contracts/src/v0.8/automation/v2_2_zksync/ZKSyncAutomationRegistryBase2_2.sol index 4ea19e2c6f6..b019c207480 100644 --- a/contracts/src/v0.8/automation/v2_2_zksync/ZKSyncAutomationRegistryBase2_2.sol +++ b/contracts/src/v0.8/automation/v2_2_zksync/ZKSyncAutomationRegistryBase2_2.sol @@ -13,13 +13,6 @@ import {KeeperCompatibleInterface} from "../interfaces/KeeperCompatibleInterface import {UpkeepFormat} from "../interfaces/UpkeepTranscoderInterface.sol"; import {IChainModule} from "../interfaces/IChainModule.sol"; -interface ISystemContext { - function gasPerPubdataByte() external view returns (uint256 gasPerPubdataByte); - function getCurrentPubdataSpent() external view returns (uint256 currentPubdataSpent); -} - -ISystemContext constant SYSTEM_CONTEXT_CONTRACT = ISystemContext(address(0x800b)); - /** * @notice Base Keeper Registry contract, contains shared logic between * AutomationRegistry and AutomationRegistryLogic @@ -808,20 +801,7 @@ abstract contract ZKSyncAutomationRegistryBase2_2 is ConfirmedOwner { bytes memory performData ) internal nonReentrant returns (bool success, uint256 gasUsed) { performData = abi.encodeWithSelector(PERFORM_SELECTOR, performData); - uint256 p1 = SYSTEM_CONTEXT_CONTRACT.getCurrentPubdataSpent(); - (bool success, uint256 executionGasUsed) = forwarder.forward(performGas, performData); - uint256 p2 = SYSTEM_CONTEXT_CONTRACT.getCurrentPubdataSpent(); - uint256 pubdataUsed; - if (p2 > p1) { - pubdataUsed = p2 - p1; - } - uint256 gasPerPubdataByte = SYSTEM_CONTEXT_CONTRACT.gasPerPubdataByte(); - emit GasDetails(pubdataUsed, gasPerPubdataByte, executionGasUsed, p1, p2, tx.gasprice); - uint256 l1GasUsed = gasPerPubdataByte * pubdataUsed; - if (performGas < l1GasUsed + executionGasUsed) { - revert InsufficientGas(executionGasUsed, l1GasUsed); - } - return (success, executionGasUsed + l1GasUsed); + return forwarder.forward(performGas, performData); } /**