How are prices determined?

As explained in Protocol Overview, each pair on Casperswap is actually underpinned by a liquidity pool.

Liquidity pools are smart contracts that hold balances of two unique tokens, and enforce rules for depositing and withdrawing them.

The primary rule is the constant product formula: 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 CasperSwap handles prices

At a high level, trades in CasperSwap must be priced in the periphery. To this end the library provides a variety of functions specifically designed to make this process quite simple, and all swapping functions in the router are designed with this in mind as well.

Pricing Trades

When swapping tokens on CasperSwap, the common desire is 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, so as to understand what the current price is. However, it is not safe to perform this lookup and rely on the results without reference to an external price.

Say a smart contract naively wants to send 10,000 DAI to the DAI/WETH pair and receive as much WETH as it can get, given the current reserve ratio. If, when called, the naive 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 understand why, consider a malicious actor who sees 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, then wait for the naive swap to execute at a bad rate, and ultimately 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.

In order to prevent these types of attacks, it is vital to submit swaps that are knowledgeable about the "fair" price that the swap should execute at. In other words, swaps need access to an oracle to ensure that the best execution from CasperSwap 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 is common that the ratio of the intra-block reserves of a pair is close to the "true" market price. Thus, if a user submits a trade with this knowledge in mind, they can ensure that the losses due to front-running are tightly bound.

This is how the CasperSwap frontend ensures trade safety: it calculates the optimal input/output amounts given observed intra-block prices, and then uses the router to perform the swap, which in turn guarantees that 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).

Last updated