Skip to content

Conversation

@nicholaspai
Copy link
Member

No description provided.

Copy link
Contributor

@mrice32 mrice32 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! A few minor comments.

Comment on lines 89 to 95
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.
);
Copy link
Contributor

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?

Copy link
Member Author

Choose a reason for hiding this comment

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

Great idea, done: 833d320

Comment on lines 351 to 352
// 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?
Copy link
Contributor

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed


// 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");
Copy link
Contributor

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.

Copy link
Member Author

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

require(newCrossDomainAdmin != address(0), "Bad bridge router address");
crossDomainAdmin = newCrossDomainAdmin;
emit SetXDomainAdmin(crossDomainAdmin);
emit TokensBridged(
Copy link
Contributor

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?

Copy link
Member Author

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 {
Copy link
Member

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

added a TODO

distributionLeaf.l2TokenAddress,
hubPool,
distributionLeaf.amountToReturn,
6_000_000,
Copy link
Member

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.

Copy link
Member Author

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?

Copy link
Member Author

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?

Copy link
Member Author

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

Copy link
Member

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.

Copy link
Member Author

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

Comment on lines +326 to +327
require(distributionLeaf.chainId == chainId(), "Invalid chainId");
require(distributionLeaf.refundAddresses.length == distributionLeaf.refundAmounts.length, "invalid leaf");
Copy link
Member

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?

Copy link
Member Author

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

Copy link
Member Author

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)

// 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),
Copy link
Member

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.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

Copy link
Member

@chrismaree chrismaree left a 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.

address public override crossDomainAdmin;

event SetXDomainAdmin(address indexed newAdmin);
event TokensBridged(
Copy link
Contributor

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?

Copy link
Member Author

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

Copy link
Contributor

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.

Copy link
Member Author

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

@nicholaspai nicholaspai requested a review from mrice32 February 9, 2022 04:16
Copy link
Contributor

@mrice32 mrice32 left a 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
Copy link
Member

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.
Copy link
Member

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.

@nicholaspai nicholaspai merged commit 3a9df25 into master Feb 9, 2022
@nicholaspai nicholaspai deleted the npai/distribute-relayer-refund branch February 9, 2022 20:35
@nicholaspai nicholaspai restored the npai/distribute-relayer-refund branch February 14, 2022 17:02
pxrl pushed a commit that referenced this pull request Feb 13, 2024
Signed-off-by: nicholaspai <npai.nyc@gmail.com>
pxrl added a commit that referenced this pull request Feb 13, 2024
Original fix from Nick.

Signed-off-by: nicholaspai <npai.nyc@gmail.com>
Co-authored-by: nicholaspai <9457025+nicholaspai@users.noreply.github.com>
pxrl pushed a commit that referenced this pull request Feb 20, 2024
Signed-off-by: nicholaspai <npai.nyc@gmail.com>
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.

4 participants