Skip to content

Conversation

@mrice32
Copy link
Contributor

@mrice32 mrice32 commented Feb 8, 2022

This doesn't include tests or some of the meat of the verification and fill logic just to allow us to agree on the interfaces before moving forward.

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
uint64 unclaimedPoolRebalanceLeafCount;
bytes32 poolRebalanceRoot;
bytes32 destinationDistributionRoot;
bytes32 slowRelayDataRoot;
Copy link
Member

Choose a reason for hiding this comment

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

you'll need to add this to initiateRelayerRefund. I can do that in a separate PR though, If you'd like as this will break a bunch of existing tests.

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 like this variable name. can it be SlowRelayFulfilmentRoot?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, I thought I added it everywhere, will do another pass to better understand where I missed.

On the naming, sure!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done on both.

}

// TODO: should these structs be in this file?
struct RelayData {
Copy link
Member

Choose a reason for hiding this comment

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

would a better name be SlowRelayFulfilment? then use this through out, such as verifySlowRelayFufilment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, it's tricky here because this is the exact data structure the SpokePool uses internally to represent a relay. I don't know if we want to rename that struct.

Copy link
Member

Choose a reason for hiding this comment

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

move this to SpokePool interface?

Copy link
Member

Choose a reason for hiding this comment

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

hhhmm. ye I see your point. not ideal.

if we move it to the SpokePool interface then we'll get the MerkleLib to import from this interface, yes? equally, we can pull the Hub's Merkle structs to a HubPool interface and import them into the MerkleLib in the same way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed!

Comment on lines +263 to +270
address depositor,
address recipient,
address destinationToken,
uint64 realizedLpFeePct,
uint64 relayerFeePct,
uint64 depositId,
uint256 originChainId,
uint256 totalRelayAmount,
Copy link
Member

Choose a reason for hiding this comment

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

all these props can be taken directly from the MerkleLib.RelayData, no? would it be cleaner to pass in one struct and then the extra fields that are not in the struct?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was trying to mirror the fill method, as I think we will effectively have 3 fill methods that will have mostly the same parameters. Would like these to be as consistent as possible, so if we use a struct here, maybe it makes sense to use a struct in the others?

Copy link
Member

Choose a reason for hiding this comment

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

ye, Ideally we pass around structs in all these methods methinks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The only issue is the interpretability on etherscan :/

Copy link
Member

Choose a reason for hiding this comment

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

we do this on v1 and you can decode them I think.

Copy link
Member

Choose a reason for hiding this comment

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

I take that back! looks like Etherscan has removed this for some reason :/

image

this is a settlement tx

Copy link
Member

Choose a reason for hiding this comment

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

we might need to re-evaluate the interface in the hub pool as well to spread the props, like you do it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this definitely used to work :((

Copy link
Member

Choose a reason for hiding this comment

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

i spread props in other external spokepool methods for thi very reason

Copy link
Member

Choose a reason for hiding this comment

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

I'll make this change in the hub :(((((

Copy link
Member

@nicholaspai nicholaspai left a comment

Choose a reason for hiding this comment

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

This skeleton makes total sense +1

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
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! good work on re-factoring the interfaces like this.

uint64 unclaimedPoolRebalanceLeafCount;
bytes32 poolRebalanceRoot;
bytes32 destinationDistributionRoot;
bytes32 slowRelayFulfilmentRoot;
Copy link
Member

Choose a reason for hiding this comment

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

nit: I hate to be that grammar guy but fulfillment has two L's in the "fill" part

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you!

I don't mean to throw @chrismaree under the bus, but I just copy-pasted this from his suggestion haha

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will fix.

import "./chain-adapters/AdapterInterface.sol";

interface HubPoolInterface {
struct PoolRebalance {
Copy link
Member

Choose a reason for hiding this comment

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

nit: Should we add "Leaf" to the end of PoolRebalance and DestiationDistribution to make it clear that they are to be used as merkle root structures? @chrismaree wdyt, i'm not strongly opinionated and its not a big deal but i think its more readable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree, will try to make this change. Hopefully will just be a simple find and replace.

* @notice Library to help with merkle roots, proofs, and claims.
*/
library MerkleLib {
// TODO: some of these data structures can be moved out if convenient.
Copy link
Member

Choose a reason for hiding this comment

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

+1 moving these to the spoke/hub pool interface i think that makes a lot of sense

// If relay token is weth then unwrap and send eth.
if (relayData.destinationToken == address(weth)) {
IERC20(relayData.destinationToken).safeTransferFrom(msg.sender, address(this), amountToSend);
if (!isSlowRelay)
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a comment explaining that the source of funds to pay the recipient is either the caller+relayer or this contract depending on whether this is a slow relay

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep!

);

bytes32 relayHash = _getRelayHash(relayData);
uint256 fillAmountPreFees = _fillRelay(relayHash, relayData, relayerFeePct, type(uint256).max / 1e18, true);
Copy link
Member

Choose a reason for hiding this comment

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

You could also set maxAmountToSend == totalRelayAmount which might make it more readable?

Copy link
Contributor Author

@mrice32 mrice32 Feb 10, 2022

Choose a reason for hiding this comment

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

Interesting idea -- what you're saying is that relayAmount >= total send, so this will always result in the relay being completely filled. I like this. Will add an explanatory comment too. Always in favor of less math.

Copy link
Member

Choose a reason for hiding this comment

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

exactly yeah, if you try to relay the full relayAmount you'll always end up sending the max


interface SpokePoolInterface {
// This leaf is meant to be decoded in the SpokePool in order to pay out individual relayers for this bundle.
struct DestinationDistribution {
Copy link
Member

Choose a reason for hiding this comment

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

nit: same as PoolRebalance, maybe add "Leaf" to end of this name

Copy link
Member

@nicholaspai nicholaspai left a comment

Choose a reason for hiding this comment

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

Thanks for merging in my SpokePool changes! I left mostly nits on naming + comments and one suggestion for which variable to pass into the internal _fillRelay method. I also appreciate you not adding tests yet so we can re-review them in a second pass or a follow up PR. I'll be sure to follow the same commit pattern on my PR's!

mrice32 and others added 3 commits February 10, 2022 17:05
Co-authored-by: nicholaspai <9457025+nicholaspai@users.noreply.github.com>
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
* @param proof the merkle proof.
*/
function verifyPoolRebalance(
function verifyPoolRebalanceLeaf(
Copy link
Member

Choose a reason for hiding this comment

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

why rename this function to end with "Leaf"? I think its not neccessary since you take in a param called "leaf", but if you do go this route then I think you should end verifyRelayData and verifyRelayerDistribution also with "Leaf"

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps verifyRelayData is more appropriately named verifyRelayDataHashLeaf or verifyRelayHashLeaf

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay, fixed on both! I reverted the Leaf change here (it was a find-and-replace issue I think)

@nicholaspai
Copy link
Member

This LGTM but just be consistent on using "leaf" in the "verify-" function names

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
import "@uma/core/contracts/common/implementation/MultiCaller.sol";
import "./MerkleLib.sol";
import "./SpokePoolInterface.sol";
import "hardhat/console.sol";
Copy link
Member

Choose a reason for hiding this comment

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

@mrice32 nit

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, will remove!

public
override
{
_initializeRelayerRefund(relayerRepaymentDistributionRoot, slowRelayFulfillmentRoot);
Copy link
Member

Choose a reason for hiding this comment

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

I know you've changed this through the play but do we think that changing these variable names would make our linting a bit easier? relayerRepaymentDistributionRoot is a very long variable name. would relayerRepaymentRoot be better? and slowRelayFulfillmentRoot to slowRelayRoot? My goal is that we have a lot of functions and variables that are wrapping onto multiple lines and would perhaps not wrap if they were a bit shorter.

dont worry about this for now but just something to think about. IMHO as much as posible having code on one line will make things a lot easier to read and generally makes the code look much cleaner.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'll leave for a follow-up. We've had a lot of back and forth on naming in this PR, and just to avoid doing a bunch more find-and-replace, we can do this in one shot in a follow up if that's cool.

package.json Outdated
},
"engines": {
"node": ">=14.0.0"
},
Copy link
Member

Choose a reason for hiding this comment

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

why?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I ran some command that failed saying it was incompatible with node version 8, and adding this fixed it. I can't remember what command it was, and I can't seem to find it in my local history, so I'll remove.

import { TokenRolesEnum } from "@uma/common";
import { getContractFactory, randomAddress, toBN, fromWei } from "./utils";

import { bondAmount, refundProposalLiveness, finalFee, identifier, repaymentChainId } from "./constants";
Copy link
Member

Choose a reason for hiding this comment

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

we should lint for unused variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree! We should turn on eslint, as it will catch stuff like this. I think these are all used, though.

Comment on lines 5 to 6
import { Contract, Signer } from "ethers";
import hre from "hardhat";
Copy link
Member

Choose a reason for hiding this comment

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

both of these lines can be imported from utils. dont worry about it now, though. I'll do a clean up PR later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed for this file. Haven't checked other files tho.

await hubPool.connect(dataWorker).initiateRelayerRefund([3117], 1, tree.getHexRoot(), consts.mockTreeRoot);
await hubPool
.connect(dataWorker)
.initiateRelayerRefund([3117], 1, tree.getHexRoot(), consts.mockTreeRoot, consts.mockSlowRelayFulfillmentRoot);
Copy link
Member

Choose a reason for hiding this comment

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

here is another example of the long ass variable names and how it makes the code ugly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, we can update these when we update the other names. I agree that shorter names would be better! So let's decide offline what these should be called and do a big naming PR.

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 great! I left a few nits but overall this is excellent work! Feel free to merge once you've implemented the nits.

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
@mrice32 mrice32 merged commit 271f16a into master Feb 11, 2022
@mrice32 mrice32 deleted the slow_relay branch February 11, 2022 22:27
pxrl added a commit that referenced this pull request Feb 20, 2024
Restoring this for backwards compatibility with the v2 ABI.

Co-authored-by: nicholaspai <9457025+nicholaspai@users.noreply.github.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