Skip to content

Commit

Permalink
fix withdraw LINK bug in auto 2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanRHall committed Mar 26, 2024
1 parent 684afa4 commit b41aa90
Show file tree
Hide file tree
Showing 12 changed files with 54 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .changeset/thin-coats-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"chainlink": patch
---

fix withdraw LINK bug in auto 2.3
5 changes: 5 additions & 0 deletions contracts/.changeset/famous-feet-rescue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@chainlink/contracts": patch
---

fix withdraw LINK bug in auto 2.3

Large diffs are not rendered by default.

18 changes: 13 additions & 5 deletions contracts/src/v0.8/automation/dev/test/AutomationRegistry2_3.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ contract AddFunds is SetUp {

// it fails when the billing token is not native, but trying to pay with native
function test_RevertsWhen_NativePaymentDoesntMatchBillingToken() external {
vm.expectRevert(abi.encodeWithSelector(Registry.InvalidBillingToken.selector));
vm.expectRevert(abi.encodeWithSelector(Registry.InvalidToken.selector));
registry.addFunds{value: 1}(linkUpkeepID, 0);
}

Expand Down Expand Up @@ -249,6 +249,14 @@ contract Withdraw is SetUp {
registry.withdrawERC20Fees(address(usdToken), FINANCE_ADMIN, 1);
}

function test_WithdrawERC20Fees_RevertsWhenAttemptingToWithdrawLINK() public {
_mintLink(address(registry), 1e10);
vm.startPrank(FINANCE_ADMIN);
vm.expectRevert(Registry.InvalidToken.selector);
registry.withdrawERC20Fees(address(linkToken), FINANCE_ADMIN, 1); // should revert
registry.withdrawLink(FINANCE_ADMIN, 1); // but using link withdraw functions succeeds
}

function testWithdrawERC20FeeSuccess() public {
// deposit excess USDToken to the registry (this goes to the "finance withdrawable" pool be default)
uint256 startReserveAmount = registry.getReserveAmount(address(usdToken));
Expand Down Expand Up @@ -549,7 +557,7 @@ contract SetConfig is SetUp {
);
}

function testSetConfigRevertDueToInvalidBillingToken() public {
function testSetConfigRevertDueToInvalidToken() public {
address[] memory billingTokens = new address[](1);
billingTokens[0] = address(linkToken);

Expand All @@ -566,7 +574,7 @@ contract SetConfig is SetUp {
// deploy registry with OFF_CHAIN payout mode
registry = deployRegistry(AutoBase.PayoutMode.OFF_CHAIN);

vm.expectRevert(abi.encodeWithSelector(Registry.InvalidBillingToken.selector));
vm.expectRevert(abi.encodeWithSelector(Registry.InvalidToken.selector));
registry.setConfigTypeSafe(
SIGNERS,
TRANSMITTERS,
Expand Down Expand Up @@ -811,7 +819,7 @@ contract RegisterUpkeep is SetUp {
}

function test_RevertsWhen_TheBillingTokenIsNotConfigured() public {
vm.expectRevert(Registry.InvalidBillingToken.selector);
vm.expectRevert(Registry.InvalidToken.selector);
registry.registerUpkeep(
address(TARGET1),
config.maxPerformGas,
Expand Down Expand Up @@ -890,7 +898,7 @@ contract OnTokenTransfer is SetUp {

function test_RevertsWhen_TheUpkeepDoesNotUseLINKAsItsBillingToken() public {
vm.startPrank(address(linkToken));
vm.expectRevert(Registry.InvalidBillingToken.selector);
vm.expectRevert(Registry.InvalidToken.selector);
registry.onTokenTransfer(UPKEEP_ADMIN, 100, abi.encode(usdUpkeepID));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ contract AutomationRegistry2_3 is AutomationRegistryBase2_3, OCR2Abstract, Chain
if (data.length != 32) revert InvalidDataLength();
uint256 id = abi.decode(data, (uint256));
if (s_upkeep[id].maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled();
if (address(s_upkeep[id].billingToken) != address(i_link)) revert InvalidBillingToken();
if (address(s_upkeep[id].billingToken) != address(i_link)) revert InvalidToken();
s_upkeep[id].balance = s_upkeep[id].balance + uint96(amount);
s_reserveAmounts[IERC20(address(i_link))] = s_reserveAmounts[IERC20(address(i_link))] + amount;
emit FundsAdded(id, sender, uint96(amount));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,14 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
error IncorrectNumberOfSigners();
error IndexOutOfRange();
error InsufficientBalance(uint256 available, uint256 requested);
error InvalidBillingToken();
error InvalidDataLength();
error InvalidFeed();
error InvalidTrigger();
error InvalidPayee();
error InvalidRecipient();
error InvalidReport();
error InvalidSigner();
error InvalidToken();
error InvalidTransmitter();
error InvalidTriggerType();
error MigrationNotPermitted();
Expand Down Expand Up @@ -543,7 +543,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
if (upkeep.performGas < PERFORM_GAS_MIN || upkeep.performGas > s_storage.maxPerformGas)
revert GasLimitOutsideRange();
if (address(s_upkeep[id].forwarder) != address(0)) revert UpkeepAlreadyExists();
if (address(s_billingConfigs[upkeep.billingToken].priceFeed) == address(0)) revert InvalidBillingToken();
if (address(s_billingConfigs[upkeep.billingToken].priceFeed) == address(0)) revert InvalidToken();
s_upkeep[id] = upkeep;
s_upkeepAdmin[id] = admin;
s_checkData[id] = checkData;
Expand Down Expand Up @@ -1069,7 +1069,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {

// if LINK is a billing option, payout mode must be ON_CHAIN
if (address(token) == address(i_link) && mode == PayoutMode.OFF_CHAIN) {
revert InvalidBillingToken();
revert InvalidToken();
}
if (address(token) == ZERO_ADDRESS || address(config.priceFeed) == ZERO_ADDRESS) {
revert ZeroAddressNotAllowed();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ contract AutomationRegistryLogicB2_3 is AutomationRegistryBase2_3, Chainable {

if (msg.value != 0) {
if (upkeep.billingToken != IERC20(i_wrappedNativeToken)) {
revert InvalidBillingToken();
revert InvalidToken();
}
amount = SafeCast.toUint96(msg.value);
}
Expand Down Expand Up @@ -205,13 +205,18 @@ contract AutomationRegistryLogicB2_3 is AutomationRegistryBase2_3, Chainable {
}

/**
* @notice LINK available to withdraw by the finance team
* @notice returns the size of the LINK liquidity pool
# @dev LINK max supply < 2^96, so casting to int256 is safe
*/
function linkAvailableForPayment() public view returns (int256) {
return int256(i_link.balanceOf(address(this))) - int256(s_reserveAmounts[IERC20(address(i_link))]);
}

/**
* @notice withdraws excess LINK from the liquidity pool
* @param to the address to send the fees to
* @param amount the amount to withdraw
*/
function withdrawLink(address to, uint256 amount) external {
_onlyFinanceAdminAllowed();
if (to == ZERO_ADDRESS) revert InvalidRecipient();
Expand All @@ -230,9 +235,16 @@ contract AutomationRegistryLogicB2_3 is AutomationRegistryBase2_3, Chainable {
emit FeesWithdrawn(address(i_link), to, amount);
}

/**
* @notice withdraws non-LINK fees earned by the contract
* @param asset the asset to withdraw
* @param to the address to send the fees to
* @param amount the amount to withdraw
*/
function withdrawERC20Fees(IERC20 asset, address to, uint256 amount) external {
_onlyFinanceAdminAllowed();
if (to == ZERO_ADDRESS) revert InvalidRecipient();
if (address(asset) == address(i_link)) revert InvalidToken();
uint256 available = asset.balanceOf(address(this)) - s_reserveAmounts[asset];
if (amount > available) revert InsufficientBalance(available, amount);

Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

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,11 +10,11 @@ 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 d2502d6e5d9521f5af71677f9c379598163aa18e822282c8281811b83f7d6188
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 576f8bf36c1621bedcece4e36071b72cd1c858b74d6d1ddd3be468fe983daa52
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 6c78204720f93e79fff6af600d41ec13076a9aeb22be421179d008cde6b64e9b
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 8414649696c8c602a0a12b00e98eb1d6325533870b47459d9d16ad79e6abdcf0
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
automation_registry_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin dee0957eb70146a35bfe8d51a21e56daf74c5406a3ce38bb5a57155241fdde86
automation_registry_wrapper_2_3: ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.abi ../../contracts/solc/v0.8.19/AutomationRegistry2_3/AutomationRegistry2_3.bin 843b632d5b6a5fbf51993a217db3f2c3e09e3cceda091e8e83ab1412372e3fc1
automation_utils_2_1: ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.abi ../../contracts/solc/v0.8.16/AutomationUtils2_1/AutomationUtils2_1.bin 815b17b63f15d26a0274b962eefad98cdee4ec897ead58688bbb8e2470e585f5
automation_utils_2_2: ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.abi ../../contracts/solc/v0.8.19/AutomationUtils2_2/AutomationUtils2_2.bin 8743f6231aaefa3f2a0b2d484258070d506e2d0860690e66890dccc3949edb2e
automation_utils_2_3: ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.abi ../../contracts/solc/v0.8.19/AutomationUtils2_3/AutomationUtils2_3.bin 11e2b481dc9a4d936e3443345d45d2cc571164459d214917b42a8054b295393b
Expand All @@ -34,7 +34,7 @@ flux_aggregator_wrapper: ../../contracts/solc/v0.6/FluxAggregator/FluxAggregator
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 d94c75def748323c9628fb5af737f66486a534ea19848dce37f4762c0f507fe0
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_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 b41aa90

Please sign in to comment.