Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AUTO-9179: settle NOPs LINK payment offchain #12469

Merged
merged 17 commits into from
Mar 20, 2024
Merged

AUTO-9179: settle NOPs LINK payment offchain #12469

merged 17 commits into from
Mar 20, 2024

Conversation

FelixFan1992
Copy link
Contributor

No description provided.

Copy link
Contributor

I see that you haven't updated any README files. Would it make sense to do so?

Copy link
Contributor

Go solidity wrappers are out-of-date, regenerate them via the make wrappers-all command

@FelixFan1992 FelixFan1992 marked this pull request as ready for review March 18, 2024 22:35
@FelixFan1992 FelixFan1992 requested review from a team and RensR as code owners March 18, 2024 22:35
@FelixFan1992 FelixFan1992 removed request for a team and RensR March 18, 2024 22:35
uint256[] memory balances = new uint256[](length);
for (uint256 i = 0; i < length; i++) {
address transmitterAddr = s_transmittersList[i];
uint96 balance = _updateTransmitterBalanceFromPool(transmitterAddr, s_hotVars.totalPremium, uint96(length));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RyanRHall do we need to update the reserve account like
s_reserveAmounts[address(i_link)] = s_reserveAmounts[address(i_link)] - balance;?
i assume no bc using offchain settlement means there is no LINK liquidity in service chain.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow I had to think about this for a long time. I think it depends on whether LINK payments are enabled or not.

If LINK payments are disabled (most likely scenario) then we expect s_reserveAmounts[LINK] == 0, and so if we try to subtract balance, it will underflow and revert (not good!) In this scenario, we don't want to touch reserve amounts, it should just stay at 0.

But there is technically nothing stopping us from configuring a registry with LINK payments enabled and settlement mode set to offchain. In this scenario we would want to decrease the s_reserveAmounts, but only by the amount of LINK spent by upkeeps with LINK configured as the payment method, and we don't currently track this value. This is a super awkward configuration, and I would be in inclined to disable it all-together.

I think we should do the following:

  • don't touch reserveAmounts[LINK] in settleNOPsOffchain()
  • add a check in setConfig() that if a billinkToken == LINK, then require(s_payoutMode == PayoutMode.ON_CHAIN). This should prevent the awkward configuration I mentioned above.

Copy link
Contributor

@RyanRHall RyanRHall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great @FelixFan1992

@@ -428,6 +436,7 @@ abstract contract AutomationRegistryBase2_3 is ConfirmedOwner {
event FundsAdded(uint256 indexed id, address indexed from, uint96 amount);
event FundsWithdrawn(uint256 indexed id, uint256 amount, address to);
event InsufficientFundsUpkeepReport(uint256 indexed id, bytes trigger);
event NOPsSettledOffchain(address[] transmitters, uint256[] balances);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please confirm with @wentzeld that this event has all the information we need. I believe a request was made to separate balances into premium and gasFees etc.

s_transmitters[transmitterAddr].balance = 0;
}

emit NOPsSettledOffchain(s_transmittersList, balances);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we probably want to emit payees here instead of transmitters

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this bc a transmitter can use a payee which is different than transmitter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

payee is an address which has the privilege to call withdrawPayment for a transmitter. so yes they are different.

uint256[] memory balances = new uint256[](length);
for (uint256 i = 0; i < length; i++) {
address transmitterAddr = s_transmittersList[i];
uint96 balance = _updateTransmitterBalanceFromPool(transmitterAddr, s_hotVars.totalPremium, uint96(length));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow I had to think about this for a long time. I think it depends on whether LINK payments are enabled or not.

If LINK payments are disabled (most likely scenario) then we expect s_reserveAmounts[LINK] == 0, and so if we try to subtract balance, it will underflow and revert (not good!) In this scenario, we don't want to touch reserve amounts, it should just stay at 0.

But there is technically nothing stopping us from configuring a registry with LINK payments enabled and settlement mode set to offchain. In this scenario we would want to decrease the s_reserveAmounts, but only by the amount of LINK spent by upkeeps with LINK configured as the payment method, and we don't currently track this value. This is a super awkward configuration, and I would be in inclined to disable it all-together.

I think we should do the following:

  • don't touch reserveAmounts[LINK] in settleNOPsOffchain()
  • add a check in setConfig() that if a billinkToken == LINK, then require(s_payoutMode == PayoutMode.ON_CHAIN). This should prevent the awkward configuration I mentioned above.

Copy link
Contributor

@shileiwill shileiwill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -473,6 +474,37 @@ contract AutomationRegistry2_3_SetConfig is AutomationRegistry2_3_SetUp {
);
}

function testSetConfigRevertDueToInvalidBillingToken() public {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, setConfig reverts bc the payout mode is offchain, and LINK is not allowed to use. It took me a bit to understand the definition of invalid here.

s_transmitters[transmitterAddr].balance = 0;
}

emit NOPsSettledOffchain(s_transmittersList, balances);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this bc a transmitter can use a payee which is different than transmitter?

Copy link
Contributor

I see you updated files related to core. Please run pnpm changeset in the root directory to add a changeset.

@cl-sonarqube-production
Copy link

Copy link
Contributor

@RyanRHall RyanRHall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks 🔥🔥 🔥 I only have nitpicks

uint256 a = 1234;
address b = ZERO_ADDRESS;
bytes memory offchainConfigBytes = abi.encode(a, b);
bytes memory offchainConfigBytes = abi.encode(1234, ZERO_ADDRESS);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick, but all these offchainConfigBytes don't really do anything yeah? Maybe we could clean up a step further just leave them blank as "" in setConfigTypeSafe()

Comment on lines +16 to +19
uint256[] internal upkeepIds;
uint256[] internal gasLimits;
bytes[] internal performDatas;
uint256[] internal balances;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick, but it looks like these are only used within the NOPsSettlement test - I think we can move them to that contract instead of making them global across all tests?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, it looks like they're only used in one test yeah? Can we just move them to that one test?

Comment on lines +1024 to +1026
if (address(token) == address(i_link) && s_payoutMode == PayoutMode.OFF_CHAIN) {
revert InvalidBillingToken();
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, we started reading the state vars in the loop partly to avoid stack to deep errors, right? Could we add a @dev comment explaining that so that people don't think we're lazy lolol.

@RyanRHall RyanRHall self-requested a review March 20, 2024 22:59
Copy link
Contributor

@RyanRHall RyanRHall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have some nitpicks, but we can address later

@RyanRHall RyanRHall added this pull request to the merge queue Mar 20, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 20, 2024
@FelixFan1992 FelixFan1992 added this pull request to the merge queue Mar 20, 2024
Merged via the queue into develop with commit 1370133 Mar 20, 2024
116 checks passed
@FelixFan1992 FelixFan1992 deleted the AUTO-9179 branch March 20, 2024 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants