-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
some contract v2.3 tuning #12790
some contract v2.3 tuning #12790
Conversation
shileiwill
commented
Apr 11, 2024
•
edited
edited
- revert on duplicate registration in registrar
- handle upkeep migration when 2 upkeeps use same billing token
- registerUpkeep using safeTransfer
- cancel upkeep refunds the right token
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome job 🎉
struct PendingRequest { | ||
address admin; | ||
IERC20 billingToken; | ||
uint96 balance; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could get rid of this entire struct and change s_pendingRequests
to...
mapping(bytes32 => PendingRequest) private s_pendingRequests;
... this is what our friends recommended too :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, can you elaborate a bit more on this? if we dont have this PendingRequest struct, when users cancel their pending upkeep, how we do refund?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually nevermind - forget I said anything 🙃
revert TransferFailed(request.admin); | ||
} | ||
|
||
request.billingToken.safeTransfer(request.admin, request.balance); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
s_pendingRequests[hash] = PendingRequest({ | ||
admin: params.adminAddress, | ||
billingToken: params.billingToken, | ||
balance: params.amount | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think here we could just do s_pendingRequests[hash] = true;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto, would like some clarification.
@@ -10,7 +10,7 @@ import {Chainable} from "../../Chainable.sol"; | |||
import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol"; | |||
import {OCR2Abstract} from "../../../shared/ocr2/OCR2Abstract.sol"; | |||
import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol"; | |||
import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/SafeCast.sol"; | |||
import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't look like we use any library functions in this contract? So I think all this really did is increase the contract size. Not a strong opinion, but I might have left this contract as-is to keep the hot path cheaper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, my bad, i forgot to clean this up after moving the addFund
@@ -201,6 +207,7 @@ contract AutomationRegistryLogicA2_3 is AutomationRegistryBase2_3, Chainable { | |||
billingToken.safeTransfer(destination, balanceToTransfer); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we move this transfer to outside the loop and drop the if
clause? I think that would look cleaner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, agreed.
@@ -356,6 +358,10 @@ contract AutomationRegistrar2_3 is TypeAndVersionInterface, ConfirmedOwner, IERC | |||
} | |||
bytes32 hash = keccak256(abi.encode(params)); | |||
|
|||
if (s_pendingRequests[hash].admin != address(0)) { | |||
revert DuplicateEntry(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we add a foundry test for the duplicate registration scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do.
assertEq( | ||
linkToken.balanceOf(address(newRegistry)), | ||
newRegistry.getBalance(linkUpkeepID) + newRegistry.getBalance(linkUpkeepID2) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome 🙌
Go solidity wrappers are out-of-date, regenerate them via the |
1 similar comment
Go solidity wrappers are out-of-date, regenerate them via the |
Quality Gate passedIssues Measures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just the one question!
function addFunds(uint256 id, uint96 amount) external payable { | ||
Upkeep memory upkeep = s_upkeep[id]; | ||
if (upkeep.maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); | ||
|
||
if (msg.value != 0) { | ||
if (upkeep.billingToken != IERC20(i_wrappedNativeToken)) { | ||
revert InvalidToken(); | ||
} | ||
amount = SafeCast.toUint96(msg.value); | ||
} | ||
|
||
s_upkeep[id].balance = upkeep.balance + amount; | ||
s_reserveAmounts[upkeep.billingToken] = s_reserveAmounts[upkeep.billingToken] + amount; | ||
|
||
if (msg.value == 0) { | ||
// ERC20 payment | ||
bool success = upkeep.billingToken.transferFrom(msg.sender, address(this), amount); | ||
if (!success) revert TransferFailed(); | ||
} else { | ||
// native payment | ||
i_wrappedNativeToken.deposit{value: amount}(); | ||
} | ||
|
||
emit FundsAdded(id, msg.sender, amount); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we add this back to the root contract now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unfortunately no~ the addFunds requires SafeCast and SafeERC20 libraries, so when we move back the function, we also need to move back the libs. it is oversize.
for (uint256 idx = 0; idx < ids.length; idx++) { | ||
id = ids[idx]; | ||
upkeep = s_upkeep[id]; | ||
|
||
if (idx == 0) { | ||
billingToken = s_upkeep[id].billingToken; | ||
billingToken = upkeep.billingToken; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
* some contract v2.3 tuning * address comments