Skip to content

Commit

Permalink
auto-10161: replicate v2_3 to v2_3_zksync (#14035)
Browse files Browse the repository at this point in the history
* auto-10161: replicate v2_3 to v2_3_zksync

* update

* small fixes

* add an zksync automation forwarder

* fix linter

* update

* update

* lint
  • Loading branch information
FelixFan1992 authored Aug 7, 2024
1 parent e500c1a commit 215277f
Show file tree
Hide file tree
Showing 13 changed files with 3,080 additions and 6 deletions.
5 changes: 5 additions & 0 deletions contracts/.changeset/loud-lobsters-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@chainlink/contracts': patch
---

auto: create a replication from v2_3 to v2_3_zksync
1 change: 1 addition & 0 deletions contracts/.solhintignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
./src/v0.8/automation/libraries/internal/Cron.sol
./src/v0.8/automation/AutomationForwarder.sol
./src/v0.8/automation/AutomationForwarderLogic.sol
./src/v0.8/automation/ZKSyncAutomationForwarder.sol
./src/v0.8/automation/interfaces/v2_2/IAutomationRegistryMaster.sol
./src/v0.8/automation/interfaces/v2_3/IAutomationRegistryMaster2_3.sol

Expand Down
2 changes: 1 addition & 1 deletion contracts/scripts/native_solc_compile_all_automation
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,4 @@ compileContract automation/v2_3/AutomationUtils2_3.sol
compileContract automation/interfaces/v2_3/IAutomationRegistryMaster2_3.sol

compileContract automation/testhelpers/MockETHUSDAggregator.sol
compileContract automation/test/v2_3/WETH9.sol
compileContract automation/test/WETH9.sol
92 changes: 92 additions & 0 deletions contracts/src/v0.8/automation/ZKSyncAutomationForwarder.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.16;

import {IAutomationRegistryConsumer} from "./interfaces/IAutomationRegistryConsumer.sol";

uint256 constant PERFORM_GAS_CUSHION = 5_000;

/**
* @title AutomationForwarder is a relayer that sits between the registry and the customer's target contract
* @dev The purpose of the forwarder is to give customers a consistent address to authorize against,
* which stays consistent between migrations. The Forwarder also exposes the registry address, so that users who
* want to programmatically interact with the registry (ie top up funds) can do so.
*/
contract ZKSyncAutomationForwarder {
/// @notice the user's target contract address
address private immutable i_target;

/// @notice the shared logic address
address private immutable i_logic;

IAutomationRegistryConsumer private s_registry;

constructor(address target, address registry, address logic) {
s_registry = IAutomationRegistryConsumer(registry);
i_target = target;
i_logic = logic;
}

/**
* @notice forward is called by the registry and forwards the call to the target
* @param gasAmount is the amount of gas to use in the call
* @param data is the 4 bytes function selector + arbitrary function data
* @return success indicating whether the target call succeeded or failed
*/
function forward(uint256 gasAmount, bytes memory data) external returns (bool success, uint256 gasUsed) {
if (msg.sender != address(s_registry)) revert();
address target = i_target;
gasUsed = gasleft();
assembly {
let g := gas()
// Compute g -= PERFORM_GAS_CUSHION and check for underflow
if lt(g, PERFORM_GAS_CUSHION) {
revert(0, 0)
}
g := sub(g, PERFORM_GAS_CUSHION)
// if g - g//64 <= gasAmount, revert
// (we subtract g//64 because of EIP-150)
if iszero(gt(sub(g, div(g, 64)), gasAmount)) {
revert(0, 0)
}
// solidity calls check that a contract actually exists at the destination, so we do the same
if iszero(extcodesize(target)) {
revert(0, 0)
}
// call with exact gas
success := call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0)
}
gasUsed = gasUsed - gasleft();
return (success, gasUsed);
}

function getTarget() external view returns (address) {
return i_target;
}

fallback() external {
// copy to memory for assembly access
address logic = i_logic;
// copied directly from OZ's Proxy contract
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())

// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), logic, 0, calldatasize(), 0, 0)

// Copy the returned data.
returndatacopy(0, 0, returndatasize())

switch result
// delegatecall returns 0 on error.
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
}
4 changes: 2 additions & 2 deletions contracts/src/v0.8/automation/test/v2_3/BaseTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ import {ChainModuleBase} from "../../chains/ChainModuleBase.sol";
import {IERC20Metadata as IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {MockUpkeep} from "../../mocks/MockUpkeep.sol";
import {IWrappedNative} from "../../interfaces/v2_3/IWrappedNative.sol";
import {WETH9} from "./WETH9.sol";
import {WETH9} from "../WETH9.sol";

/**
* @title BaseTest provides basic test setup procedures and dependencies for use by other
* unit tests
*/
contract BaseTest is Test {
// test state (not exposed to derrived tests)
// test state (not exposed to derived tests)
uint256 private nonce;

// constants
Expand Down
Loading

0 comments on commit 215277f

Please sign in to comment.