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

[API-3392] Profitability Checks #3

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open

Conversation

mattac21
Copy link

This PR adds checks when relaying a settlement (or any type of relay, but this is only implemented for settlements for now) that the settlement is going to be profitable for the relayer (since gas costs can be very high for the settlement relay on evm chains). Profitability is determined as follows:

  • Simulate the Process call on the evm side (process is the function that delivers the hyperlane message and calls the recipient contract, in our case that the is gateway contract).
  • Calculate (base fee + estimated gas tip cap) * estimated gas of process call to get the estimated tx fee in gwei
  • Fetch the current price of ETH in usd from CoinGecko (we are assuming a 1 usd = 1 usdc conversion)
  • Convert price of eth in usdc to price of gwei in usd
  • Convert tx fee in gwei to tx fee in usd
  • Convert tx fee in usd to tx fee in uusdc
  • Then, we get the % of the total value of the relay that the tx fee will take. Compare this % with the user specified min tx fee % on the relays destination chain. If the tx fee % is less than the min fee %, then the relay is profitable.

This also does some refactoring work around how hyperlane relays are submitted from other services that require replying. The order settler and the order fulfiller (specifically the timeout portion of the order fulfiller) have been refactored to directly call SubmitTxToRelay on the hyperlane relayer runner, instead of there being an impact dependency on them inserting a row into the submitted tx's table, and the hyperlane relayer runner polling that table for transfers to relay.

@mattac21 mattac21 requested a review from a team as a code owner October 28, 2024 20:44
Comment on lines +15 to +16
transfer_value TEXT,
max_gas_price_pct INTEGER,
Copy link
Author

Choose a reason for hiding this comment

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

relay profitability options are now stored in the db along with the transfers info

@@ -190,47 +206,67 @@ func (c *HyperlaneClient) getISMAddress(ctx context.Context, recipient string) (
}

func (c *HyperlaneClient) Process(ctx context.Context, domain string, message []byte, metadata []byte) ([]byte, error) {
Copy link
Author

Choose a reason for hiding this comment

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

slightly refactored the Process function just to pull some logic out into helpers (getting signer and getting address) since that logic is now also needed in QuoteProcessUUSDC

Comment on lines -53 to -64
// find settlement txns in the db and insert them as pending
// hyperlane txns in the hyperlane table
if err := r.findSettlementsToRelay(ctx); err != nil {
return fmt.Errorf("finding settlements txns to relay: %w", err)
}

// find timeout txns in the db and insert them as pending hyperlane
// txns in the hyperlane table
if err := r.findTimeoutsToRelay(ctx); err != nil {
return fmt.Errorf("finding timeout txns to relay: %w", err)
}

Copy link
Author

Choose a reason for hiding this comment

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

no longer polling the db for timeouts rows and settlement rows, these services will call the SubmitTxToRelay function on the relayer runner. this forces services that need hyperlane relaying to explicitly require the relayer runner as a dependency

Copy link
Collaborator

Choose a reason for hiding this comment

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

nice

// note that there is no profitability option being passed to the relayer
// here, timeouts transfer no value to the solver so if we pass a config
// for a min allowed gas % the timeout will never be relayed
return r.relayer.SubmitTxToRelay(ctx, txHash, initiateTimeoutChain, hyperlane.RelayOpts{})
Copy link
Author

Choose a reason for hiding this comment

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

curious if people have thoughts on the comment here? the issue is the normal profitability checks look at the value that the hyperlane relay will give to the relayer, and decides if the gas fee % of the total value is < their specified max fee %. however for timeout relays there is no value being transferred to the solver (the solver just does this at a loss). the only metric I could think of would be to have a minimum gas fee in uusdc or gwei specific to the relay destination chain and just not relay until gas is lower than that amount (or eth price drops if specified in uusdc). but again, relaying the timeouts is kind of 'for the good of the protocol', so maybe we don't want to allow people to wait to submit timeout relays since that would be a worse experience for users?

shared/evmrpc/tx_price_oracle.go Show resolved Hide resolved
@nadim-az
Copy link
Collaborator

two small comments otherwise lgtm 🙏

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.

2 participants