-
Notifications
You must be signed in to change notification settings - Fork 75
feat(spoke-pool): Distribute relayer refund #24
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
Conversation
mrice32
left a comment
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.
Looks great! A few minor comments.
contracts/Optimism_SpokePool.sol
Outdated
| IL2ERC20Bridge(Lib_PredeployAddresses.L2_STANDARD_BRIDGE).withdrawTo( | ||
| distributionLeaf.l2TokenAddress, // _l2Token. Address of the L2 token to bridge over. | ||
| hubPool, // _to. Withdraw, over the bridge, to the l1 pool contract. | ||
| distributionLeaf.amountToReturn, // _amount. Send the full balance of the deposit box to bridge. | ||
| 6_000_000, // _l1Gas. Unused, but included for potential forward compatibility considerations | ||
| "" // _data. We don't need to send any data for the bridging action. | ||
| ); |
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.
nit: should we just put this bit of special logic in a virtual internal method that's called by the base class? That way the more generic logic could all live in the base class and this dispatch bit would be the only part that's custom per chain?
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.
Great idea, done: 833d320
contracts/SpokePool.sol
Outdated
| // TODO: Should we be checking that distributionLeaf.refundAddresses.length == distributionLeaf.refundAmounts.length | ||
| // or can we assume that the `initiateRelayerRefund` on the HubPool would have been disputed on L1? |
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.
As long as it's fairly cheap to check (which I think it is), I think this check makes sense to avoid any unexpected behavior below.
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.
Agreed
contracts/SpokePool.sol
Outdated
|
|
||
| // TODO: Similar question to above: should we assume that the L2 token is not address(0) or any other address | ||
| // that would have been disputed on L1? | ||
| require(distributionLeaf.l2TokenAddress != address(0), "invalid leaf"); |
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 wouldn't worry about this unless there's something particularly bad that would happen if it were address 0.
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.
Yeah this would revert anyways if l2 token was address 0, and also should be disputed on L1
contracts/Optimism_SpokePool.sol
Outdated
| require(newCrossDomainAdmin != address(0), "Bad bridge router address"); | ||
| crossDomainAdmin = newCrossDomainAdmin; | ||
| emit SetXDomainAdmin(crossDomainAdmin); | ||
| emit TokensBridged( |
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.
Should we only emit this if we actually bridged tokens?
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.
yup! This is now implemented here 833d320
_bridgeTokensToHubPool is only called if amountToReturn > 0, and that method should emit an event for each L2-specific implementation, like it is in the Optimism_SpokePool demo code
| require(newCrossDomainAdmin != address(0), "Bad bridge router address"); | ||
| crossDomainAdmin = newCrossDomainAdmin; | ||
| emit SetXDomainAdmin(crossDomainAdmin); | ||
| function _bridgeTokensToHubPool(MerkleLib.DestinationDistribution memory distributionLeaf) internal override { |
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.
this will need branching logic for WETH. can do it in a future PR.
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.
added a TODO
contracts/Optimism_SpokePool.sol
Outdated
| distributionLeaf.l2TokenAddress, | ||
| hubPool, | ||
| distributionLeaf.amountToReturn, | ||
| 6_000_000, |
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 should set this in a variable and then let the owner change it. does not need to happen in this PR though but should probs do it.
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 can change in this PR. what's annoying is that this is potentially Optimism specific, but HubPool will need to implement a method that can trigger the cross chain admin function to make this call. Shold we just implement setL2GasLimit in the SpokePool and have it be useless for some L2s?
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.
And consider other constants such as maxSubmissionCost and l2GasPrice (and refundAddress) that will be Arbitrum specific?
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.
Perhaps in the HubPool we can allow it to call any arbitrary encoded method to the SpokePool so it can call L2-specific admin functions like setL2GasLimit for Optimism and setL2GasPrice for Arbitrum
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.
ye, so I think that what makes the most sence is to have this be a chain specific event, like you mention. then, each SpokePool specific implementation for a given chain has these extra methods on them for those chain specific things.
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.
Cool added a universal event emitted by SpokePool and added an Optimism specific OptimismTokenBridged event. Also added a setL1Gas onlyOwner method on the OptimismSpokePool
| require(distributionLeaf.chainId == chainId(), "Invalid chainId"); | ||
| require(distributionLeaf.refundAddresses.length == distributionLeaf.refundAmounts.length, "invalid leaf"); |
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 dont think any of these checks are needed. If either of these fail then the proof will fail. it's somewhat redundant, no?
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 its better to be safe in case the bots miss something, we won't get into weird state
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.
merging this comment: #24 (comment)
contracts/SpokePool.sol
Outdated
| // Check that `inclusionProof` proves that `distributionLeaf` is contained within the distribution root. | ||
| // Note: This should revert if the `distributionRoot` is uninitialized. | ||
| require( | ||
| MerkleLib.verifyRelayerDistribution(refund.distributionRoot, distributionLeaf, inclusionProof), |
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.
nit: if you re-name the inclusionProof to proof t his might fit on one line and then it's consistant with the HubPool.
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.
done
chrismaree
left a comment
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.
This is awesome! I left some nits and comments but once those are sorted we are good to go.
contracts/Optimism_SpokePool.sol
Outdated
| address public override crossDomainAdmin; | ||
|
|
||
| event SetXDomainAdmin(address indexed newAdmin); | ||
| event TokensBridged( |
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.
Do we need this event to be different per chain? Or could we standardize and put in the base class?
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 it should be diff per chain since each chain will use different params to bridge tokens. For example, Arbitrum uses something called a maxSubmissionCost whereas optimsim does not
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.
Gotcha, okay. Could make sense to have a standard event that we use for all contracts, if the specific parameters aren't relevant. Just something to think about later. Not something I think we should change 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.
Hmmm ill add a TODO
…art-contracts-v2 into npai/distribute-relayer-refund
mrice32
left a comment
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.
LGTM!
| crossDomainAdmin = newCrossDomainAdmin; | ||
| emit SetXDomainAdmin(crossDomainAdmin); | ||
| function _bridgeTokensToHubPool(MerkleLib.DestinationDistribution memory distributionLeaf) internal override { | ||
| // TODO: Handle WETH token unwrapping |
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.
yup! this part you can copy some of the work done in the other contracts, fortunately.
| // TODO: Handle WETH token unwrapping | ||
| IL2ERC20Bridge(Lib_PredeployAddresses.L2_STANDARD_BRIDGE).withdrawTo( | ||
| distributionLeaf.l2TokenAddress, // _l2Token. Address of the L2 token to bridge over. | ||
| hubPool, // _to. Withdraw, over the bridge, to the l1 pool contract. |
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.
this might need to change in the context of weth.
…ethod to OptimismSpokePool
Co-authored-by: Chris Maree <christopher.maree@gmail.com>
…art-contracts-v2 into npai/distribute-relayer-refund
Signed-off-by: nicholaspai <npai.nyc@gmail.com>
Signed-off-by: nicholaspai <npai.nyc@gmail.com>
No description provided.