> For the complete documentation index, see [llms.txt](https://moonsdust.gitbook.io/rcpswap/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://moonsdust.gitbook.io/rcpswap/advanced-topics/pricing.md).

# Pricing

## How are prices determined? <a href="#how-are-prices-determined" id="how-are-prices-determined"></a>

As we learned in [Protocol Overview](/rcpswap/protocol-overview/how-uniswap-works.md), each pair on Uniswap is actually underpinned by a liquidity pool. Liquidity pools are smart contracts that hold balances of two unique tokens and enforces rules around depositing and withdrawing them. The primary rule is the [constant product formula](/rcpswap/protocol-overview/glossary.md#erc20). When a token is withdrawn (bought), a proportional amount must be deposited (sold) to maintain the constant. The ratio of tokens in the pool, in combination with the constant product formula, ultimately determine the price that a swap executes at.

## How Uniswap handles prices <a href="#how-uniswap-handles-prices" id="how-uniswap-handles-prices"></a>

In Uniswap V1, trades are always executed at the “best possible” price, calcuated at execution time. Somewhat confusingly, this calculation is actually accomplished with one of two different formulas, depending on whether the trade specifies an exact *input* or *output* amount. Functionally, the difference between these two functions is miniscule, but the very existence of a difference increases conceptual complexity. Initial attempts to support both functions in V2 proved inelegant, and the decision was made to **not provide any pricing functions in the core**. Instead, pairs directly check whether the invariant was satisfied (accounting for fees) after every trade. This means that rather than relying on a pricing function to *also* enforce the invariant, V2 pairs simply and transparently ensure their own safety, a nice separation of concerns. One downstream benefit is that V2 pairs will more naturally support other flavors of trades which may emerge, (e.g. trading to a specific price at execution time).

At a high level, in Uniswap V2, *trades must be priced in the periphery*. The good news is that the [library](/rcpswap/protocol-overview/smart-contract/library.md) provides a variety of functions designed to make this quite simple, and all swapping functions in the [router](/rcpswap/protocol-overview/smart-contract/router02.md) are designed with this in mind.

## Pricing Trades <a href="#pricing-trades" id="pricing-trades"></a>

When swapping tokens on Uniswap, it’s common to want to receive as many output tokens as possible for an *exact input amount*, or to pay as few input tokens as possible for an *exact output amount*. In order to calculate these amounts, a contract must look up the *current reserves* of a pair, in order to understand what the current price is. However, it is *not safe to perform this lookup and rely on the results without access to an external price*.

Say a smart contract naively wants to send 10 DAI to the DAI/WETH pair and receive as much WETH as it can get, given the current reserve ratio. If, when called, the native smart contract simply looks up the current price and executes the trade, it is *vulnerable to front-running and will likely suffer an economic loss*. To see why, consider a malicious actor who seees this transaction before it is confirmed. They could execute a swap which dramatically changes the DAI/WETH price immediately before the naive swap goes through, wait for the naive swap to execute at a bad rate, and then swap to change the price back to what it was before the naive swap. This attack is fairly cheap and low-risk, and can typically be performed for a profit.

To prevent these types of attacks, it’s vital to submit swaps *that have access to knowledge about the “fair” price their swap should execute at*. In other words, swaps need access to an *oracle*, to be sure that the best execution they can get from Uniswap is close enough to what the oracle considers the “true” price. While this may sound complicated, the oracle can be as simple as an *off-chain observation of the current market price of a pair*. Because of arbitrage, it’s typically the case that the ratio of the intra-block reserves of a pair is close to the “true” market price. So, if a user submits a trade with this knowledge in mind, they can ensure that the losses due to front-running are tightly bounded. This is how, for example, the Uniswap frontend ensure trade safety. It calculates the optimal input/output amounts given observed intra-block prices, and uses the router to perform the swap, which guarantees the swap will execute at a rate no less that `x`% worse than the observed intra-block rate, where `x` is a user-specified slippage tolerance (0.5% by default).

There are, of course, other options for oracles, including [native Uniswap V2 oracles](/rcpswap/core-concepts/oracles.md).

### Exact Input <a href="#exact-input" id="exact-input"></a>

If you’d like to send an exact amount of input tokens in exchange for as many output tokens as possible, you’ll want to use [getAmountsOut](/rcpswap/protocol-overview/smart-contract/router02.md#getamountsin). The equivalent SDK function is [getOutputAmount](/rcpswap/protocol-overview/smart-contract/router02.md), or [minimumAmountOut](/rcpswap/protocol-overview/smart-contract/router02.md) for slippage calculations.

### Exact Output <a href="#exact-output" id="exact-output"></a>

If you’d like to receive an exact amount of output tokens for as few input tokens as possible, you’ll want to use [getAmountsIn](/rcpswap/protocol-overview/smart-contract/router02.md#getamountsin). The equivalent SDK function is [getInputAmount](/rcpswap/protocol-overview/smart-contract/router02.md), or [maximumAmountIn](/rcpswap/protocol-overview/smart-contract/router02.md) for slippage calculations.

### Swap to Price <a href="#swap-to-price" id="swap-to-price"></a>

For more this more advanced use case see [ExampleSwapToPrice.sol](https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleSwapToPrice.sol)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://moonsdust.gitbook.io/rcpswap/advanced-topics/pricing.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
