Skip to content

Commit

Permalink
improve auto 2.3 migration path efficiency (#12642)
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanRHall authored Mar 29, 2024
1 parent 49a51b7 commit 192fbfb
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 54 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
uint32 internal constant UINT32_MAX = type(uint32).max;
// The first byte of the mask can be 0, because we only ever have 31 oracles
uint256 internal constant ORACLE_MASK = 0x0001010101010101010101010101010101010101010101010101010101010101;
/**
* @dev UPKEEP_TRANSCODER_VERSION_BASE is temporary necessity for backwards compatibility with
* MigratableAutomationRegistryInterfaceV1 - it should be removed in future versions in favor of
* UPKEEP_VERSION_BASE and MigratableAutomationRegistryInterfaceV2
*/
UpkeepFormat internal constant UPKEEP_TRANSCODER_VERSION_BASE = UpkeepFormat.V1;
uint8 internal constant UPKEEP_VERSION_BASE = 3;
uint8 internal constant UPKEEP_VERSION_BASE = 4;

// Next block of constants are only used in maxPayment estimation during checkUpkeep simulation
// These values are calibrated using hardhat tests which simulates various cases and verifies that
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,18 @@ contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable {
* @dev a transcoder must be set in order to enable migration
* @dev migration permissions must be set on *both* sending and receiving registries
* @dev only an upkeep admin can migrate their upkeeps
* @dev this function is most gas-efficient if upkeepIDs are sorted by billing token
* @dev TODO - this needs better multi-token testing
*/
// TODO - this is not efficient and need to be re-worked
function migrateUpkeeps(uint256[] calldata ids, address destination) external {
if (
s_peerRegistryMigrationPermission[destination] != MigrationPermission.OUTGOING &&
s_peerRegistryMigrationPermission[destination] != MigrationPermission.BIDIRECTIONAL
) revert MigrationNotPermitted();
if (s_storage.transcoder == ZERO_ADDRESS) revert TranscoderNotSet();
if (ids.length == 0) revert ArrayHasNoEntries();
IERC20 billingToken;
uint256 balanceToTransfer;
uint256 id;
Upkeep memory upkeep;
address[] memory admins = new address[](ids.length);
Expand All @@ -164,6 +167,19 @@ contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable {
for (uint256 idx = 0; idx < ids.length; idx++) {
id = ids[idx];
upkeep = s_upkeep[id];

if (idx == 0) {
billingToken = s_upkeep[id].billingToken;
balanceToTransfer = upkeep.balance;
}

// if we encounter a new billing token, send the sum from the last billing token to the destination registry
if (upkeep.billingToken != billingToken) {
s_reserveAmounts[billingToken] = s_reserveAmounts[billingToken] - balanceToTransfer;
billingToken.safeTransfer(destination, balanceToTransfer);
billingToken = upkeep.billingToken;
balanceToTransfer = upkeep.balance;
}
_requireAdminAndNotCancelled(id);
upkeep.forwarder.updateRegistry(destination);
upkeeps[idx] = upkeep;
Expand All @@ -179,8 +195,12 @@ contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable {
delete s_proposedAdmin[id];
s_upkeepIDs.remove(id);
emit UpkeepMigrated(id, upkeep.balance, destination);
s_reserveAmounts[upkeep.billingToken] = s_reserveAmounts[upkeep.billingToken] - upkeep.balance;
upkeep.billingToken.safeTransfer(destination, upkeep.balance);

// always transfer the rolling sum at the end of the array
if (idx == ids.length - 1) {
s_reserveAmounts[billingToken] = s_reserveAmounts[billingToken] - balanceToTransfer;
billingToken.safeTransfer(destination, balanceToTransfer);
}
}
bytes memory encodedUpkeeps = abi.encode(
ids,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,6 @@ contract AutomationRegistryLogicC2_3 is AutomationRegistryBase2_3 {
return s_payoutMode;
}

function upkeepTranscoderVersion() public pure returns (UpkeepFormat) {
return UPKEEP_TRANSCODER_VERSION_BASE;
}

function upkeepVersion() public pure returns (uint8) {
return UPKEEP_VERSION_BASE;
}
Expand Down
46 changes: 46 additions & 0 deletions contracts/src/v0.8/automation/dev/v2_3/UpkeepTranscoder5_0.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: BUSL-1.1

pragma solidity 0.8.19;

import {UpkeepTranscoderInterfaceV2} from "../../interfaces/UpkeepTranscoderInterfaceV2.sol";
import {TypeAndVersionInterface} from "../../../interfaces/TypeAndVersionInterface.sol";

enum RegistryVersion {
V12,
V13,
V20,
V21,
V23
}

/**
* @notice UpkeepTranscoder is a contract that allows converting upkeep data from previous registry versions to newer versions
* @dev it currently only supports 2.3 -> 2.3 migrations
*/
contract UpkeepTranscoder5_0 is UpkeepTranscoderInterfaceV2, TypeAndVersionInterface {
error InvalidTranscoding();

string public constant override typeAndVersion = "UpkeepTranscoder 5.0.0";

/**
* @notice transcodeUpkeeps transforms upkeep data from the format expected by
* one registry to the format expected by another. It future-proofs migrations
* by allowing automation team to customize migration paths and set sensible defaults
* when new fields are added
* @param fromVersion version the upkeep is migrating from
* @param toVersion version the upkeep is migrating to
* @param encodedUpkeeps encoded upkeep data
* @dev this transcoder should ONLY be use for V23->V23 migrations for now
*/
function transcodeUpkeeps(
uint8 fromVersion,
uint8 toVersion,
bytes calldata encodedUpkeeps
) external view override returns (bytes memory) {
if (toVersion == uint8(RegistryVersion.V23) && fromVersion == uint8(RegistryVersion.V23)) {
return encodedUpkeeps;
}

revert InvalidTranscoding();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ describe('AutomationRegistry2_3', () => {
.connect(owner)
.deploy(8, nativeUSD)
const upkeepTranscoderFactory = await ethers.getContractFactory(
'UpkeepTranscoder4_0',
'UpkeepTranscoder5_0',
)
transcoder = await upkeepTranscoderFactory.connect(owner).deploy()
mockArbGasInfo = await mockArbGasInfoFactory.connect(owner).deploy()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { AutomationRegistryBase2_3__factory as AutomationRegistryBaseFactory } f
import { Chainable__factory as ChainableFactory } from '../../../typechain/factories/Chainable__factory'
import { IAutomationRegistryMaster2_3__factory as IAutomationRegistryMasterFactory } from '../../../typechain/factories/IAutomationRegistryMaster2_3__factory'
import { IAutomationRegistryConsumer__factory as IAutomationRegistryConsumerFactory } from '../../../typechain/factories/IAutomationRegistryConsumer__factory'
import { MigratableKeeperRegistryInterface__factory as MigratableKeeperRegistryInterfaceFactory } from '../../../typechain/factories/MigratableKeeperRegistryInterface__factory'
import { MigratableKeeperRegistryInterfaceV2__factory as MigratableKeeperRegistryInterfaceV2Factory } from '../../../typechain/factories/MigratableKeeperRegistryInterfaceV2__factory'
import { OCR2Abstract__factory as OCR2AbstractFactory } from '../../../typechain/factories/OCR2Abstract__factory'
import { IAutomationV21PlusCommon__factory as IAutomationV21PlusCommonFactory } from '../../../typechain/factories/IAutomationV21PlusCommon__factory'
Expand Down Expand Up @@ -81,13 +80,6 @@ describe('IAutomationRegistryMaster2_3', () => {
)
})

it('satisfies the MigratableKeeperRegistryInterface interface', async () => {
assertSatisfiesInterface(
IAutomationRegistryMasterFactory.abi,
MigratableKeeperRegistryInterfaceFactory.abi,
)
})

it('satisfies the MigratableKeeperRegistryInterfaceV2 interface', async () => {
assertSatisfiesInterface(
IAutomationRegistryMasterFactory.abi,
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogi
automation_registrar_wrapper2_1: ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.abi ../../contracts/solc/v0.8.16/AutomationRegistrar2_1/AutomationRegistrar2_1.bin eb06d853aab39d3196c593b03e555851cbe8386e0fe54a74c2479f62d14b3c42
automation_registrar_wrapper2_3: ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistrar2_3/AutomationRegistrar2_3.bin 20fac1208261e866caa1f3ffc71030f682a96761bebe79e5ecd71186fce86c60
automation_registry_logic_a_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_2/AutomationRegistryLogicA2_2.bin 2f267fb8467a15c587ce4586ac56069f7229344ad3936430d7c7624c0528a171
automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin efd57ea3e47b4ddda363281bdb423e1ba55c6e2f54caa2e55e272daf04bc24fc
automation_registry_logic_a_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicA2_3/AutomationRegistryLogicA2_3.bin 72dbf7eec4fae9b92d704c001611cb4c118b879388e4109494ed1697043e7152
automation_registry_logic_b_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_2/AutomationRegistryLogicB2_2.bin a6d33dfbbfb0ff253eb59a51f4f6d6d4c22ea5ec95aae52d25d49a312b37a22f
automation_registry_logic_b_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistryLogicB2_3/AutomationRegistryLogicB2_3.bin 69cbe10a666d47822b92e44c189b30e59d51c5e67cc47e2b81737ff5a6a4c365
automation_registry_wrapper_2_2: ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_2/AutomationRegistry2_2.bin de60f69878e9b32a291a001c91fc8636544c2cfbd9b507c8c1a4873b602bfb62
Expand All @@ -31,7 +31,7 @@ dummy_protocol_wrapper: ../../contracts/solc/v0.8.16/DummyProtocol/DummyProtocol
gas_wrapper: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2/KeeperRegistryCheckUpkeepGasUsageWrapper1_2.bin 4a5dcdac486d18fcd58e3488c15c1710ae76b977556a3f3191bd269a4bc75723
gas_wrapper_mock: ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.abi ../../contracts/solc/v0.8.6/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock/KeeperRegistryCheckUpkeepGasUsageWrapper1_2Mock.bin a9b08f18da59125c6fc305855710241f3d35161b8b9f3e3f635a7b1d5c6da9c8
i_automation_registry_master_wrapper_2_2: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster/IAutomationRegistryMaster.bin 9ff7087179f89f9b05964ebc3e71332fce11f1b8e85058f7b16b3bc0dd6fb96b
i_automation_registry_master_wrapper_2_3: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.bin c95d3f8287af68310a29f87c9f1b760276e00a539b1a3749b968e514f4349344
i_automation_registry_master_wrapper_2_3: ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.abi ../../contracts/solc/v0.8.19/IAutomationRegistryMaster2_3/IAutomationRegistryMaster2_3.bin fa36a6cd0b28d68401b14e7361214ad1d55e5ebb40a39f81dae8a34785e673b6
i_automation_v21_plus_common: ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.abi ../../contracts/solc/v0.8.19/IAutomationV21PlusCommon/IAutomationV21PlusCommon.bin e8a601ec382c0a2e83c49759de13b0622b5e04e6b95901e96a1e9504329e594c
i_chain_module: ../../contracts/solc/v0.8.19/IChainModule/IChainModule.abi ../../contracts/solc/v0.8.19/IChainModule/IChainModule.bin 383611981c86c70522f41b8750719faacc7d7933a22849d5004799ebef3371fa
i_keeper_registry_master_wrapper_2_1: ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.abi ../../contracts/solc/v0.8.16/IKeeperRegistryMaster/IKeeperRegistryMaster.bin ee0f150b3afbab2df3d24ff3f4c87851efa635da30db04cd1f70cb4e185a1781
Expand Down

0 comments on commit 192fbfb

Please sign in to comment.