Auction slot tutorial: improve structure

This commit is contained in:
mDuo13
2024-05-08 17:20:42 -07:00
parent 8b687e98ea
commit 169e5349ec
5 changed files with 264 additions and 194 deletions

View File

@@ -0,0 +1,9 @@
---
metadata:
indexPage: true
---
# Trade On-Ledger
Use the XRP Ledger's built-in Decentralized Exchange (DEX) to trade assets.
{% child-pages /%}

View File

@@ -30,14 +30,18 @@ At a high level, the steps involved in using an AMM auction slot to save money o
1. Check the current XRP Ledger state to estimate how much your desired trade would cost in AMM trading fees.
2. Compare against the cost to win the current auction slot.
3. If winning the auction slot is cheaper, use AMMDeposit to acquire some LPTokens and then use AMMBid to spend those tokens on winning the auction slot.
4. Make the intended trade using an OfferCreate transaction. (You could also use a cross-currency Payment transaction, but this tutorial uses OfferCreate.)
4. Make the intended trade using an OfferCreate transaction.
For simplicity, this tutorial assumes that you have XRP, you want to acquire a fixed amount of TST in a single trade, and that the entire trade will execute using the AMM. Real-life situations are more complicated. For example, part of your trade may execute by consuming Offers rather than using the AMM, or you may want to do a series of trades over a period of time. If one or both of the assets you are trading has a transfer fee or tick size set, those details can also affect the calculations.
### Source Code
See {% repo-link path="_code-samples/auction-slot/js/" %}Code Samples: Auction Slot{% /repo-link %} for the full source code for this tutorial.
### 1. Setup
For this use case, you need a high-precision number library such as Bignumber.js for correctly performing calculations on currency amounts you may find in the ledger.
For this use case, you need a high-precision number library such as [Bignumber.js](https://mikemcl.github.io/bignumber.js/) for correctly performing calculations on currency amounts you may find in the ledger.
The following `package.json` file lists the necessary dependencies:
@@ -47,7 +51,9 @@ After copying this file, run `npm install` from the same folder to download the
Start your JavaScript file with the following code to import dependencies:
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" before="/* Convert" /%}
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" before="async function main()" /%}
You should also create the `amm-formulas.js` file, which defines several AMM-related helper functions. See the [Appendix](#appendix-amm-formulas) for the implementations of these functions.
After that, you should connect to the network and set up a `Wallet` instance in the usual way. For example:
@@ -58,64 +64,52 @@ After that, you should connect to the network and set up a `Wallet` instance in
To determine if your trade could benefit from the reduced fees of the AMM auction slot, you must first look up the current state of the AMM. To get the latest information, use the `amm_info` method and query the `current` (pending) ledger version.
**Caution:** The `current` ledger incorporates recently-sent transactions that are likely to be confirmed; it is the most up-to-date picture of the ledger state, but the details may change when the ledger is validated. You can also use the `validated` ledger, which returns only the latest confirmed data.
{% admonition type="warning" name="Caution" %}The `current` ledger incorporates recently-sent transactions that are likely to be confirmed; it is the most up-to-date picture of the ledger state, but the details may change when the ledger is validated. You can also use the `validated` ledger, which returns only the latest confirmed data.{% /admonition %}
The following code snippet reads the `amm_info` result and saves some of the details for later use:
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="// Look up AMM status" before="// Calculate price in XRP" /%}
### 3. Estimate the cost of AMM trading fees
Estimating the cost of AMM trading fees can be tricky and the details vary depending on the type of trade you are performing. For example, a "buy" trade that stops after receiving a target amount of an asset should be calculated differently than a "sell" trade, which continues until a target amount of an asset has been spent.
This tutorial shows how to estimate the cost, in XRP, to buy a fixed amount of TST using the AMM. The calculations are different for other types of trades, such as a "sell" trade that buys as much TST as possible with a fixed amount of XRP, or for assets with other complications such as transfer fees.
This tutorial shows how to estimate the cost, in XRP, to buy TST using the AMM. First, define the target amount and check that the AMM can even fulfill the trade:
First, define the target amount of TST and check that the AMM can even fulfill the trade:
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="// Calculate price in XRP" before="// Use AMM's SwapOut formula" /%}
Then, you use the _Swap Out_ formula, defined in the XRPL-0030 specification as formula 10, to estimate how much of one asset you have to swap in to the AMM to receive a target amount out of the other asset. The following function implements the formula:
Then, you use the AMM _SwapOut_ formula to calculate how much XRP you need to pay to receive the target amount of TST out. See [SwapOut in the Appendix](#swapout) for the implementation of this formula.
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="/* Implement the AMM SwapOut formula" before="/* Compute the quadratic formula" /%}
The following helper functions are also needed for Swap Out and other formulas later in the tutorial:
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="/* Convert a trading fee to a value that" before="/* Implement the AMM SwapOut formula" /%}
Then, to estimate the cost of trading fees, calculate the Swap Out value twice: once with the full fee, and once with the discounted fee of the auction slot. The difference between the two results represents the maximum possible savings from the auction slot for this trade, not including the costs of winning the auction slot.
To estimate the cost of trading fees, call SwapOut twice: once with the full fee, and once with the discounted fee of the auction slot. The difference between the two represents the maximum possible savings from the auction slot for this trade, not including the costs of winning the auction slot.
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="// Use AMM's SwapOut formula" before="// Calculate the cost of winning" /%}
**Note:** For illustrative purposes, this code assumes that the entire trade will execute using the AMM and not by consuming Offers. In reality, a trade can use both in combination to achieve a better rate.
{% admonition type="info" name="Note" %}For illustrative purposes, this code assumes that the entire trade will execute using the AMM and not by consuming Offers. In reality, a trade can use both in combination to achieve a better rate.{% /admonition %}
### 4. Calculate the cost of winning the auction slot
The cost to win the auction slot depends on how long the current holder has held it and how much they paid, but it's always denominated in LP tokens. If you currently only have XRP and you want to win the auction slot, you must first deposit some of your XRP to get LP Tokens.
The price of winning the auction slot is defined in XLS-0030 section 4.1.1. However, the minimum bid scales with the number of LP Tokens issued. If you calculate the auction price and _then_ deposit exactly enough to pay for it, the auction price increases proportionally to the new LP Tokens you gained, so you need to invert the formula.
The price of winning the auction slot is defined in XLS-0030 section 4.1.1. However, the minimum bid scales with the number of LP Tokens issued. If you calculate the auction price and _then_ deposit exactly enough to pay for it, the auction price increases proportionally to the new LP Tokens you gained.
This is similar to cases where you want to deliver exactly $100 after subtracting a 3% fee. If you calculate $100 + (0.03 * $100) = $103, only $99.91 will arrive because the extra $3 is also subject to the fee. Instead, you divide 100 ÷ 0.97 ≈ $103.10 (rounding up to make sure).
The following function represents the inverted formula, which calculates the total amount of LP Tokens you need to receive to match the auction price:
The _AuctionDeposit_ formula represents the inverted form of the auction price formula such so that you can calulate how much to deposit to match the auction price. See [Appendix: AuctionDeposit](#auctiondeposit) for the implementation.
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="/* Calculate how much to deposit" before="async function main()" /%}
Then, you call the function like this:
You use the function like this:
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="// Calculate the cost of winning the auction slot" before="// Calculate how much XRP to deposit" /%}
### 5. Compare the costs and savings
The previous step gives a cost for the auction slot in the form of LP Tokens. To compare against your potential savings, you need to convert this to the XRP cost of the deposit. If the XRP cost of making the deposit and winning the auction slot is greater than your savings, then you should not go through with it.
To do the conversion, you use the AMM _Asset In_ formula, which is implemented as follows:
You use the AMM _AssetIn_ formula to estimate how much XRP you have to deposit to receive the target amount of TST. See [Appendix: AssetIn](#assetin) for the implementation.
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="/* Implement the AMM single-asset deposit" before="/* Calculate the necessary bid" /%}
In addition to the `feeMult(t)` and `feeMultHalf(t)` helper functions defined earlier, this formula needs to solve the quadratic equation. (You may remember the quadratic formula from high-school mathematics.) The following code implements a helper function for this:
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="/* Compute the quadratic formula." before="/* Implement the AMM single-asset deposit" /%}
The following code uses the Asset In formula to estimate the cost of the deposit:
The following code uses AssetIn to estimate the cost of the deposit:
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="// Calculate how much XRP to deposit" before="// Optional. Allow for costs" /%}
@@ -127,7 +121,8 @@ Finally, you take the slippage-adjusted cost in XRP, add the transaction costs i
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="// Compare price of deposit+bid" before="// Do a single-asset deposit" /%}
**Tip:** You may still be able to save money if you plan to do additional trades for a larger total amount. Also, if the auction slot is currently occupied, the cost of outbidding the current slot holder decreases over 24 hours, so you can wait and try again later.
{% admonition type="success" name="Tip" %} You may still be able to save money if you plan to do additional trades for a larger total amount. Also, if the auction slot is currently occupied, the cost of outbidding the current slot holder decreases over 24 hours, so you can wait and try again later.{% /admonition %}
### 6. Send an AMMDeposit transaction to get LP Tokens
@@ -139,13 +134,15 @@ The "One Asset LP Token" deposit type is most convenient here since you can spec
After the transaction is (or isn't) confirmed by the consensus process, the code displays the results to the console.
### 7. Send an AMMBid transaction to win the auction slot
Assuming the previous transaction was successful, the next step is to use the LP Tokens to bid on the auction slot. To do this, you send an [AMMBid transaction][] with the slippage-adjusted bid amount you calculated earlier in the `BidMax` field, as in the following code:
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="// Actually bid" before="// Trade using the discount" /%}
**Tip:** The amounts that LP Tokens get rounded can be surprising. If you don't plan on holding LP Tokens after bidding, you should set `BidMin` to the same as `BidMax` so that you aren't left with a trust line that contains a very tiny amount of LP Tokens that weren't spent on the auction price, and you don't have to meet the XRP reserve for that trust line.
{% admonition type="success" name="Tip" %}The amounts that LP Tokens get rounded can be surprising. If you don't plan on holding LP Tokens after bidding, you should set `BidMin` to the same as `BidMax` so that you aren't left with a trust line that contains a very tiny amount of LP Tokens that weren't spent on the auction price, and you don't have to meet the XRP reserve for that trust line.{% /admonition %}
### 8. Trade using the discount
@@ -153,7 +150,66 @@ If your previous transaction was successful, you should now be the auction slot
{% code-snippet file="/_code-samples/auction-slot/js/auction-slot.js" language="js" from="// Trade using the discount" before="// Done" /%}
**Tip:** If you are outbid before the auction slot expires, you'll get some of your LP Tokens refunded based on how much time you had left. You can use an [AMMWithdraw transaction][] to convert those to additional XRP, TST, or both as desired.
{% admonition type="success" name="Tip" %}If you are outbid before the auction slot expires, you'll get some of your LP Tokens refunded based on how much time you had left. You can use an [AMMWithdraw transaction][] to convert those to additional XRP, TST, or both as desired.{% /admonition %}
## Appendix: AMM Formulas
The above sample code shows how to use various AMM-related formulas in a particular workflow. Your code must also have implementations of those formulas, which can be in the same file or imported from a separate one as you desire.
The file {% repo-link path="_code-samples/auction-slot/js/amm-formulas.js" %}`amm-formulas.js`{% /repo-link %} contains the source code for all these formulas.
### AssetIn
The _AssetIn_ formula calculates how much of an asset must be deposited to receive a target amount of LP Tokens.
The following function implements AssetIn in JavaScript:
{% code-snippet file="/_code-samples/auction-slot/js/amm-formulas.js" language="js" from="/* Implement the AMM single-asset deposit" before="/* Calculate how much to deposit" /%}
This function depends on the `feeMult`, `feeMultHalf`, and `solveQuadraticEq` helper functions.
### AuctionDeposit
The _AuctionDeposit_ function is an inverted form of the formula for the AMM's auction price, taking into account how the minimum bid value changes as LP Tokens are issued. AuctionDeposit calculates the total amount of LP Tokens you need to receive in a deposit if you want to match the auction price:
{% code-snippet file="/_code-samples/auction-slot/js/amm-formulas.js" language="js" from="/* Calculate how much to deposit" before="/* Calculate the necessary bid" /%}
### AuctionPrice
The _AuctionPrice_ function calculates the cost of the auction slot for current LP Token holders. **It is not used in this tutorial,** which assumes the user does not hold LP Tokens, but is presented here for completeness:
{% code-snippet file="/_code-samples/auction-slot/js/amm-formulas.js" language="js" from="/* Calculate the necessary bid" before="module.exports =" /%}
### SwapOut
The _SwapOut_ formula, defined in the XRPL-0030 specification as formula 10, calculates how much of one asset you have to swap in to the AMM to receive a target amount of the other asset out from the AMM.
The following function implements SwapOut in JavaScript:
{% code-snippet file="/_code-samples/auction-slot/js/amm-formulas.js" language="js" from="/* Implement the AMM SwapOut formula" before="/* Compute the quadratic formula" /%}
### feeDecimal, feeMult, and feeMultHalf
These helper functions are used in other AMM formulas to convert from a trading fee value in the ledger (integer from 0 to 1000) to a decimal representation that can be multiplied by a total to apply the fee.
The following functions implement `feeMult`, `feeMultHalf`, and `feeDecimal` in JavaScript:
{% code-snippet file="/_code-samples/auction-slot/js/amm-formulas.js" language="js" from="/* Convert a trading fee to a value that" before="/* Implement the AMM SwapOut formula" /%}
The AssetIn and SwapOut functions depend on these helper functions.
### solveQuadraticEq
This helper function is solves the quadratic equation, which you may remember from high-school mathematics.
The following function implements the quadratic equation in JavaScript:
{% code-snippet file="/_code-samples/auction-slot/js/amm-formulas.js" language="js" from="/* Compute the quadratic formula." before="/* Implement the AMM single-asset deposit" /%}
The AssetIn formula depends on this.
## Conclusion