Skip to content

Conversation

@dangell7
Copy link
Contributor

No description provided.

@theotherian
Copy link

theotherian commented Mar 7, 2025

Any chance this would be added to the gateway_balances resource to avoid having to make two trips to the ledger to find out the total supply at an issuer?

@dangell7
Copy link
Contributor Author

dangell7 commented Mar 7, 2025

Any chance this would be added to the gateway_balances resource to avoid having to make two trips to the ledger to find out the total supply at an issuer?

#272 (comment)

@dangell7
Copy link
Contributor Author

Update the spec.

  • Cleaned up some redundancy
  • Added extra information for StateChanges (OutstandingAmount & EscrowedAmount)
  • Added failure for Issuer as Source
  • Added Future Considerations
  • Added Update to Ledger Entry Objects

Open Issues:

Nomenclature for sfEscrowedAmount

bthomee pushed a commit to XRPLF/rippled that referenced this pull request Jun 3, 2025
- Specification: XRPLF/XRPL-Standards#272
- Amendment: `TokenEscrow`
- Enables escrowing of IOU and MPT tokens in addition to native XRP.
- Allows accounts to lock issued tokens (IOU/MPT) in escrow objects, with support for freeze, authorization, and transfer rates.
- Adds new ledger fields (`sfLockedAmount`, `sfIssuerNode`, etc.) to track locked balances for IOU and MPT escrows.
- Updates EscrowCreate, EscrowFinish, and EscrowCancel transaction logic to support IOU and MPT assets, including proper handling of trustlines and MPT authorization, transfer rates, and locked balances.
- Enforces invariant checks for escrowed IOU/MPT amounts.
- Extends GatewayBalances RPC to report locked (escrowed) balances.
@sappenin sappenin self-requested a review June 24, 2025 16:40
@sappenin sappenin merged commit cceb72d into XRPLF:master Jun 24, 2025
2 checks passed
@ckeshava
Copy link

  1. Why is an Issuer forbidden from creating an Escrow with their token? I could not foresee problems that allows this design.

In the current world:

  • Central Banks lend their currency to other banks (or) large infrastructure projects (or) public-spending welfare programs.
  • Corporations reward employees with RSUs. These units have a time-based constraint before they can be EscrowFinish'ed

Both these examples have an Issuer as the creator of the Escrow.

Furthermore, the use of a tem... code (for ex: temNO_PERMISSION) would have failed the transaction faster. It would have also saved the fees consumed by a tecNO_PERMISSION error code. Why did you choose the latter?

  1. The cpp implementation uses sfLockedAmount in two MPT-related ledger-entries. Is that equivalent to the sfEscrowAmount as mentioned in this specification?

It would be very helpful if the documentation could explicitly state that sfLockedAmount is a base-10 specified value (although it uses UINT64 rippled type) and not a base-16 value. (I'm gleaning this based on the usage of SField::sMD_BaseTen in its declaration)

@dangell7
Copy link
Contributor Author

  1. Why is an Issuer forbidden from creating an Escrow with their token? I could not foresee problems that allows this design.

In the current world:

  • Central Banks lend their currency to other banks (or) large infrastructure projects (or) public-spending welfare programs.
  • Corporations reward employees with RSUs. These units have a time-based constraint before they can be EscrowFinish'ed

Both these examples have an Issuer as the creator of the Escrow.

Furthermore, the use of a tem... code (for ex: temNO_PERMISSION) would have failed the transaction faster. It would have also saved the fees consumed by a tecNO_PERMISSION error code. Why did you choose the latter?

  1. The cpp implementation uses sfLockedAmount in two MPT-related ledger-entries. Is that equivalent to the sfEscrowAmount as mentioned in this specification?

It would be very helpful if the documentation could explicitly state that sfLockedAmount is a base-10 specified value (although it uses UINT64 rippled type) and not a base-16 value. (I'm gleaning this based on the usage of SField::sMD_BaseTen in its declaration)

I have updated the spec for the sfLockedAmount and CancelAfter

#292

As for why Issuer cannot create Escrow that was a design decision that was made. I agree it could be valuable for the Issuer to create an escrow but the issuer could also just create a new account, send value and escrow from there.

As for the tecNO_PERMISSION error response you are right, it should have been a tem error as its more of a transaction malformed error than a ledger error.

@ckeshava
Copy link

Do you have thoughts on dealing with "orphaned" escrow ledger-objects? Here's a thought experiment:

  • A (Escrow creator) creates an escrow with USD IOU token to destination B (Escrow Destination). It has the necessary authorization to hold the IOU.
  • After certain time, the Issuer of the USD token decides to remove the trustline-authorization for both A and B.
  • Neither EscrowFinish nor EscrowCancel is feasible at this juncture, because USD tokens cannot be transferred to either parties.
  • The EscrowCreator A is unable to get back its reserve that was taken at the time of escrow-creation.

Is this scenario discussed elsewhere in the comments, I missed it.

@dangell7
Copy link
Contributor Author

Do you have thoughts on dealing with "orphaned" escrow ledger-objects? Here's a thought experiment:

  • A (Escrow creator) creates an escrow with USD IOU token to destination B (Escrow Destination). It has the necessary authorization to hold the IOU.
  • After certain time, the Issuer of the USD token decides to remove the trustline-authorization for both A and B.
  • Neither EscrowFinish nor EscrowCancel is feasible at this juncture, because USD tokens cannot be transferred to either parties.
  • The EscrowCreator A is unable to get back its reserve that was taken at the time of escrow-creation.

Is this scenario discussed elsewhere in the comments, I missed it.

Are you suggesting we add the authorized trustline automatically for the account?

I’m happy to make any changes you would like to recommend.

@ckeshava
Copy link

Are you suggesting we add the authorized trustline automatically for the account?

I wasn't sure if this case was covered in the existing design, so I was seeking more clarity. I'm not making any suggestions at the moment.

What would be ideal behavior in this circumstance ("orphaned escrows")

  1. We could add an authorized trust line. However, that will not help in cases where the Issuer has DeepFrozen the trustlines to the escrow-creator and escrow-destination (after the creation of the Escrow). Furthermore, that solution is not extendable to the case of MPTs.

  2. The Escrow-creator should be able to cancel the escrow by sending the tokens back to the Issuer. This approach will not violate any of the deep-freeze constraints.

  3. Should an Issuer be able to revoke authorization of accounts which are participants to a pending Escrow operation? Perhaps, a safer alternative should be to do EscrowCancel -> Clawback -> DeepFreeze -> Revoke Authorized Trustline on the said accounts.

The scenario that I described in the previous message can be resolved with either of these three alternatives. Perhaps there is a better idea?

@dangell7
Copy link
Contributor Author

dangell7 commented Jun 26, 2025

Are you suggesting we add the authorized trustline automatically for the account?

I wasn't sure if this case was covered in the existing design, so I was seeking more clarity. I'm not making any suggestions at the moment.

What would be ideal behavior in this circumstance ("orphaned escrows")

  1. We could add an authorized trust line. However, that will not help in cases where the Issuer has DeepFrozen the trustlines to the escrow-creator and escrow-destination (after the creation of the Escrow). Furthermore, that solution is not extendable to the case of MPTs.
  2. The Escrow-creator should be able to cancel the escrow by sending the tokens back to the Issuer. This approach will not violate any of the deep-freeze constraints.
  3. Should an Issuer be able to revoke authorization of accounts which are participants to a pending Escrow operation? Perhaps, a safer alternative should be to do EscrowCancel -> Clawback -> DeepFreeze -> Revoke Authorized Trustline on the said accounts.

The scenario that I described in the previous message can be resolved with either of these three alternatives. Perhaps there is a better idea?

So first, the issuer cannot unauthorize an IOU. The account holder has to send all their tokens back to the issuer and then delete their trustline and then re add it for it to be unauthorized.

With MPT though the issuer can unauthorize an account at any time.

So with that in mind, maybe just returning the tokens back to the account on Cancel and then rejecting on Finish just like DeepFreeze is the best option. For IOU we add the trustline in an unauthrized state. For MPT it should remain unauthorized.

And force CancelAfter...

But this actually doesn't solve another issue which is the account just deletes their trustline. (This is guarded for in MPT) so maybe the better solution as you noted is to put something on the trustline that says this account has an escrow or locked tokens and then the trustline can never be deleted therefore never be unauthorized. And the same for MPT where the MPT cannot be unauthorized if there is a LockedAmount.

@ckeshava
Copy link

So first, the issuer cannot unauthorize an IOU.

That is correct, I was considering the case where the Issuer deep-freezes the escrow-creator and/or escrow-destination. A deep-freeze of the trust line will freeze the trust-line balance.

maybe just returning the tokens back to the account on Cancel and then rejecting on Finish just like DeepFreeze is the best option

Are you suggesting returning the tokens back to the issuer in the above line? that seems reasonable, yes.

I endorse your idea of TokenEscrow as "DeletionBlockers", with respect to the Deletion of Trustlines. I also want to draw your attention to an existing issue pertaining to the "default state" of authorized trust lines. I'm hoping you won't be flummoxed by it.

@dangell7
Copy link
Contributor Author

dangell7 commented Jul 1, 2025

So first, the issuer cannot unauthorize an IOU.

That is correct, I was considering the case where the Issuer deep-freezes the escrow-creator and/or escrow-destination. A deep-freeze of the trust line will freeze the trust-line balance.

maybe just returning the tokens back to the account on Cancel and then rejecting on Finish just like DeepFreeze is the best option

Are you suggesting returning the tokens back to the issuer in the above line? that seems reasonable, yes.

I endorse your idea of TokenEscrow as "DeletionBlockers", with respect to the Deletion of Trustlines. I also want to draw your attention to an existing issue pertaining to the "default state" of authorized trust lines. I'm hoping you won't be flummoxed by it.

Technically the issuer is never the account so no, it would go back to the user who held the tokens in the first place. But without authorization they wouldn't be able to do anything with them. However, with the new changes, you can't delete a trustline while having an escrow so you would never be able to remove the auth in the first place.

Removing the ability to remove a trustline if you have an escrow solves most of the issues, same with the MPT side. If you have any tokens escrowed you cannot un auth the MPT.

I think that solves most of the orphan issues.

@dangell7
Copy link
Contributor Author

dangell7 commented Jul 1, 2025

So first, the issuer cannot unauthorize an IOU.

That is correct, I was considering the case where the Issuer deep-freezes the escrow-creator and/or escrow-destination. A deep-freeze of the trust line will freeze the trust-line balance.

maybe just returning the tokens back to the account on Cancel and then rejecting on Finish just like DeepFreeze is the best option

Are you suggesting returning the tokens back to the issuer in the above line? that seems reasonable, yes.

I endorse your idea of TokenEscrow as "DeletionBlockers", with respect to the Deletion of Trustlines. I also want to draw your attention to an existing issue pertaining to the "default state" of authorized trust lines. I'm hoping you won't be flummoxed by it.

Would you like to review this PR or just take a look at the issues and solutions? Did I solve them?

XRPLF/rippled#5523

@mvadari
Copy link
Collaborator

mvadari commented Jul 2, 2025

(In the future let's try to have these conversations before the amendment is released, so that we don't need a separate fix amendment)

@ckeshava
Copy link

ckeshava commented Jul 2, 2025

Would you like to review this PR or just take a look at the issues and solutions? Did I solve them?

Hello Dennis, thanks for working on this issue. Apologies, I cannot commit to reviewing the PR, I am occupied with other tasks at the moment. I'll try to review it by the end of the week.

(In the future let's try to have these conversations before the amendment is released, so that we don't need a separate fix amendment)

I came across this amendment because I started working on the xrpl-py client library implementation. I wasn't aware of its implementation prior to that.

@ximinez
Copy link
Collaborator

ximinez commented Jul 8, 2025

* After certain time, the Issuer of the `USD` token decides to remove the trustline-authorization for both `A` and `B`.

Trust lines can not be "de-authorized" by the issuer. https://xrpl.org/docs/references/protocol/transactions/types/trustset#trustset-flags

The holder could delete their trust line, but that makes it their fault, and their problem to find a resolution.

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.

7 participants