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

Specify ics20-2 #577

Closed
wants to merge 1 commit into from
Closed

Specify ics20-2 #577

wants to merge 1 commit into from

Conversation

ethanfrey
Copy link
Contributor

@ethanfrey ethanfrey commented May 24, 2021

Update: rebased on #576 (now merged). Diff displayed is now only changes related to this PR for easier review

This defines a simple backwards-compatible extension to the ics20-1 logic to allow for optional, pseudonymous relayer incentivization. Care was taken to avoid unnecessary code branches in handlers to handle both ics20-1 and ics20-2 as well as limit failure modes if there happens to be confusion in the communication line.

Copy link
Member

@AdityaSripal AdityaSripal left a comment

Choose a reason for hiding this comment

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

This looks like a good approach for a backwards-compatible way to incentivize ICS-20 relaying.

I have a couple broad-level questions:

  1. Is there a way to generalize this relayer incentivization over all packet types/applications? I imagine many apps beyond ICS-20 will want to incentivize relayers.
  2. Is there any reward for relaying the acknowledgement or timeout back to the sending chain?

@charleenfei
Copy link
Contributor

This looks like a good approach for a backwards-compatible way to incentivize ICS-20 relaying.

I have a couple broad-level questions:

  1. Is there a way to generalize this relayer incentivization over all packet types/applications? I imagine many apps beyond ICS-20 will want to incentivize relayers.
  2. Is there any reward for relaying the acknowledgement or timeout back to the sending chain?
  1. I think a general relayer incentivisation will be much more difficult to achieve bc of the token access (lack of) on the handler level of the SDK -- we would have to write a lot more custom logic and there would be more complex implications because of that. That's why the approach right now is to start with ICS-20, which will anyway be the bulk of IBC tx upcoming for now.

@ethanfrey
Copy link
Contributor Author

ethanfrey commented May 25, 2021

  1. Is there a way to generalize this relayer incentivization over all packet types/applications? I imagine many apps beyond ICS-20 will want to incentivize relayers.

A general approach will be much more difficult to design and probably build on this one anyway. I am happy to have a discussion on this, but let's do that on a call. It is too much for github. In short, the other spec would need to have a way to handle at least a subset ics20 tokens. If I send a packet over ibcaccount/channel-3 and even if I lock some tokens in escrow on the other side, could I really create some tokens claiming to be from transfer/channel-2 (the standard ics20 connection)? If not, then this contract must issue it's own ics20 tokens. Or maintain some bookkeeping of the fees collected and allow a way to redeem them on the original chain (a subset of ics20).

Since ics20 includes all the needed functionality to issue fungible vouchers on the destination chain and redeem them on the source chain, this becomes very easy for this one protocol. This is the only ics in the while now and we can get this working well. From this, we can start discussing an approach that could be added to the other ics's.

(Basically what Charly said)

@ethanfrey
Copy link
Contributor Author

ethanfrey commented May 25, 2021

  1. Is there any reward for relaying the acknowledgement or timeout back to the sending chain?

This is a good question and idea. We could, for example, have multiple "fee" fields for the forward and backward messages or such. Or allow a "timeout" or "error" acknowledgement to capture the fees that were not captured on the destination chain. We should discuss such ideas to see if they provide desirable behavior and if so, I would be happy to discuss more on how to add them to this protocol.

I don't see the need to incentivize success acknowledgement packets, as they don't ever need to be relayed (they are a no-op basically).

I do see the use of incentivizing a relayer to relay a timeout message to allow you to recover your funds on the source chain. Since we know the fee was never claimed on the destination chain, it could be claimed (once) by the relayer that relays the timeout and provides you this service.

We need to think about what the semantics of an error acknowledgement are.

My first reaction on the timeout issue, is that relayers could just never submit your packet and get the same reward for timing them out than actually doing their job. However, upon reflection, and assuming these incentives provide a ecosystem of multiple economically interested relayers, I think this case will never happen. If there is enough fees to make it economically viable to relay it, some relayer will relay it (and not all wait for the timeout). However, if the destination chain has higher fees than the source chain, it could be economically viable to relay the timeout on source, but not the original packet.

Let's talk more on the call. but my first impression is that no incentives for success ack. Yes, pay fees for timeout relays, and a big question about handling error acknowledgements (does the spec indicate that no state change should happen inside the ibctransfer app on the destination in this case?)

success: "AQ=="
}

interface FungibleTokenPacketSuccess {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
interface FungibleTokenPacketSuccess {
interface FungibleTokenPacketError {

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 in #576 (Chris also pointed out this typo)

```

Fee is defined here as some number of tokens to be sent to the address who submitted the IbcReceivePacket on the destination chain. The information of `signer` is available when submitting the packet, but discarded in the application-specific handlers for `ibc-go`. We can simply expose that information to the application to allow it to optionally take action based on who submitted the packet. Note that this means *anyone* can submit a valid packet and we do not hard code an allowed relayer nor force the token sender to select a relayer.

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 want to consider a relayer address to be optionally provided by the message sender to support permissioned relaying? If field is left empty (default) anyone can 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.

Let us discuss this. I believe there was a great concern that permissioned relaying would involve money transfer laws and require heavy regulation. We should wait until the lawyers come back with their analysis of the law, but I would add a comment on this in any case.

- `amount - (fee || 0)` is the total amount to be sent to the `receiver` on the receiving chain
- `fee || 0` is the total amount to be sent to the relayer account (`signer`)

Defining `amount + fee` to be escrowed on the sending chain would potentially cause lost tokens if `fee` were set in the packet sender, but the recipient ignored the field.
Copy link
Contributor

Choose a reason for hiding this comment

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

What if fee is payed on the receiving chain; I guess in that case as it is optionally payed, no assets are lost in case receiver does not support ics20-2?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What if fee is payed on the receiving chain;

It is paid on the receiving (destination) chain, the same time amount is paid.

Or do I misunderstand your comment?

@colin-axner
Copy link
Contributor

Excellent! The current design looks great to me. I appreciate the care to ensuring backwards compatibility with a clean implementation

Relayer incentivization appears to be a tricky area legally, architecturally, and economically. I support the approach of incremental experimentation. This seems like a very safe first step and after a little feedback, we will be more informed on the best way to extend this even further. Perhaps timeouts and failed receipts are extremely rare and don't require incentivization. Perhaps timeouts and failed receipts can be sustainably managed by altruistic relayers. Giving this proposed approach some usage, will likely inform those decisions

I imagine relayers may also want to be paid in native tokens as opposed to IBC tokens, but again, there's a lot of unknowns in this assertion. Best to try something out to see what works and doesn't work

@ethanfrey
Copy link
Contributor Author

I imagine relayers may also want to be paid in native tokens as opposed to IBC tokens, but again, there's a lot of unknowns in this assertion

They probably will, but this is way out of scope of ics20. I would consider it likely that in the near future, any meaningful token transferred will be tradable on an AMM on either the source or destination chain, providing the relayers a way to get to native token. This is the same logic used by the Gravity Bridge, which collects erc20 fees and then can uniswap them to ethereum to cover the gas paid (and more).

If a clear pattern of usage emerges, we can also work to standardize it.

@ethanfrey
Copy link
Contributor Author

ethanfrey commented May 25, 2021

Trying to summarize some discussion on from the IBC call. Please correct any points here that I mis-represent. In the end, there are 3 general approaches to in-protocol relayer incentivization. Each somehow "more correct" than the last, but also more difficult to design/implement:

  1. Only pay for IbcReceivePacket for ICS20, basically what is laid out in 0e10970
  2. Incentivizing both directions (receive packet, acknowledge packet, timeout), but only for ics20. Brought up by aditya here: Specify ics20-2 #577 (review)
  3. Making a generic incentivization mechanism like ICS ?: IBC threat model & security assumptions #2 for all ibc protocols - brought up by Dean in the call.

@ethanfrey
Copy link
Contributor Author

ethanfrey commented May 25, 2021

Informal Systems and the Gravity Dex team are working out a plan for "altruistic" relayers to support the gravity dex rollout shortly. However a more general and sustainable solution would be good to have in place for the Hub upgrade after this one.

We should have a legal opinion on the money transfer issue and what requirements that places on the protocol design. (Estimate: June 4th more or less)

We agreed for 2 weeks of technical discussion on this issue to work out the best design for ics20. Hopefully we can work out the details and alternatives in this PR and come to a final conclusion on the June 8th IBC call.

In parallel, Dean will open an issue to collect ideas on an IBC-protocol level incentivization mechanism so we can start progress there. There should be good feedback between the ics20-only and the more generic solutions. If this comes to a quick solution, we can scrap ics20-2 in favor of a more general solution. Otherwise, we can proceed with the ics20-2 proposal without being blocked by the general one. Once this is implemented, users/chains can opt into using IBC1.1/ics20-1 fee payments over IBC1.0/ics20-2 fee payments, so there is an evolutionary step.

Is this a correct summary?

@ethanfrey
Copy link
Contributor Author

Focusing on the bi-directional incentivization idea, this seems even more important in the general case than ics20 (as errors are rare/impossible in ics20 and success acknowledgements are a no-op). The unidirectional only incentivizes receive packet submission, and only in the success case (app state is reverted in error).

  1. IbcReceivePacket == success => incentivize both packet submission as well as acknowledgement submission
  2. IbcReceivePacket == error => incentivize acknowledgement submission (to release tokens). is it possible to pay the receive packet signer?
  3. IbcTimeoutPacket => incentivize this message, no receive packet sent

In the first 2 cases, there are 2 messages to be incentivized, which may be submitted by different relayers. This makes payment trickier in the general case. Either the receive packet is immediately paid on the destination chain and the acknowledge is paid on the source chain. Or the information of who signed the receive packet is sent packet in the acknowlegement and both are rewarded on the source chain.

This also brings up the issue of splitting fees. Are there two opt-in fees? One for the receive and one for acknowledge? What do you get for timeout? Just the acknowledgement fee?

This is a very important question and essential to work out for the general case @dtribble

@ethanfrey
Copy link
Contributor Author

However, if we focus on ICS20-2, I think we can simplify this:

  1. On receive success, acknowledgement is a noop, so no need to incentivize this. Just keep the fee payment in IbcReceive as currently defined
  2. On receive error (rare case), the app cannot deduct fees on the destination (state changes reverted) and it is important to release the original funds. Here the entire fee goes to whoever submits an acknowledgement of an error.
  3. On timeouts, nothing happened on the destination, so the fees goes to whoever submitted the timeout.

Changes to the original spec would be releasing fee tokens on the source chain in cases (2) and (3). Is there agreement this is a positive change from the original spec, and that is sufficient fee incentivization if we only look at ics20 (we don't need to worry about acks for successes or ReceivePacket for errors)?

Please add some emoji voting:

  • Positive change 👍 / neutral or negative 👎
  • Sufficient improvement for bidirectional incentivization for ics20 🚀 / we need to keep looking at better solutions 👀

For 👀, please at least point out what you feel is missing and why it is important, even if you don't have a clear solution.

Copy link
Member

@AdityaSripal AdityaSripal left a comment

Choose a reason for hiding this comment

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

Note: my 👀 for MVP is just supporting different fee denomination. Other comments are nice-to-have

Either the receive packet is immediately paid on the destination chain and the acknowledge is paid on the source chain. Or the information of who signed the receive packet is sent packet in the acknowlegement and both are rewarded on the source chain.
This also brings up the issue of splitting fees. Are there two opt-in fees? One for the receive and one for acknowledge? What do you get for timeout? Just the acknowledgement fee?

I think this is a key question. I do believe that we need to incentivize relaying a timeout or ack_error to refund tokens. As Ethan said, with multiple non-colluding relayers this shouldn't introduce problems.

So the only message we don't need to incentivize is relaying successful ack. It's not necessary for user, but it does help remove state on sender chain and provides useful information to sending chain watchers (backpressure discussion from @dtribble )

Given that, I think it makes sense to just incentivize the entire packet flow and allow users to specify the fees for each message.

The other point I had and explained above was to allow fees to be specified in separate denom from amount.

Taking the two together, I believe processing fee payment completely on sender chain is the easiest to implement.

I get there might be a relayer desire to get tokens on executing chain so they can submit a multimsg tx that swaps/sends the fee elsewhere.
However, if fee is fully handled on source chain, one can get native tokens as a fee.

It's a choice between 2 invariants. We either say fees are always collected on executing chain. Or we say fees are always collected on original sender chain.

In the second case, we also have the mild benefit that relayer is incentivized to relay a successful ack (public but not private good) since that is how they get paid.

Comment on lines +362 to +366
In order to maintain maximum compatibility with `ics20-1`, we will define `amount` and `fee` in such a way that a valid `ics20-2` sender and a valid `ics20-1` recipient will not create or destroy any tokens (just ignore the fee field when set). That means:

- `amount` is the total amount that is escrowed by the sending chain.
- `amount - (fee || 0)` is the total amount to be sent to the `receiver` on the receiving chain
- `fee || 0` is the total amount to be sent to the relayer account (`signer`)
Copy link
Member

Choose a reason for hiding this comment

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

I really think that we should allow fee to be payed in a different denomination. Since ICS-20 currently only supports a single coin amount, we would need to change the logic here such that amount+fee gets escrowed on sender chain to support this.

Even with the existence of AMM, I don't expect relayers to be perfectly agnostic as to what denomination they get paid in. I still expect that they will want to be paid in a very liquid, high market-cap token.

The proposal as is would work fine for ICS-20 transfer packets sending well-known desirable tokens. However, packets sending low-liquidity, low-market-cap tokens will be greatly disadvantaged. They will either have to pay an exorbitant fee or their packets may not get relayed at all.

Suppose I create adityaCoin and even set up a small, very lightly-used liquidity pool for it to trade against ATOM. But no one cares about having adityaCoin except you. I should be able to send you adityaCoin over IBC and incentivize a relayer to relay it using ATOM as a fee. Even with the AMM, a relayer will not accept adityaCoin. I believe the AMM will cause relayers to accept fees in any well-traded coin, but not from arbitrary denominations.

From a user perspective, I want my packets relayed and treated the same regardless of what denomination my amount is in and am willing to pay my fee in ATOM or ETH to get my adityaCoin relayed.
From a relayer perspective, I want to be paid in my denomination(s) of choice OR in a denomination that is easily swappable for my preferred denomination (little to no slippage).

Thus, I think having a different denom fee is a must have even for MVP and especially because it will be used in a DEX where denominations with wildly different liquidities/desirability/market-cap are going to be sent around and they all need to be relayed just the same.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting point

- `amount - (fee || 0)` is the total amount to be sent to the `receiver` on the receiving chain
- `fee || 0` is the total amount to be sent to the relayer account (`signer`)

Defining `amount + fee` to be escrowed on the sending chain would potentially cause lost tokens if `fee` were set in the packet sender, but the recipient ignored the field.
Copy link
Member

Choose a reason for hiding this comment

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

Yes, however this is fixable if all of the fee payout gets processed on the sender chain correct?

In the case where the acknowledgement does not contain receivePacket relayer, we simply refund the receive_fee

@AdityaSripal
Copy link
Member

Created a rough proposal for general fees here: #578

It builds on sender-chain processing logic I described above. Would like to get some feedback on it

@mpoke
Copy link
Contributor

mpoke commented Apr 11, 2022

Hi @ethanfrey. What's the status of this work. Is this PR still relevant given that ICS29 is merged?

@ethanfrey
Copy link
Contributor Author

This can be closed in light of the general fee handling protocol

@mpoke mpoke closed this Apr 11, 2022
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.

6 participants