# Uniswap v4 Flash Accounting (/docs/protocols/v4/concepts/flash-accounting)

Understand flash accounting in Uniswap v4 and how deltas reduce transfer overhead.

## Flash Accounting
In previous versions of Uniswap, every time a swap was made - including multi-hop swap - tokens were transferred between Pool contracts for intermediate steps.

This design incurred inefficiencies because transferring tokens with external calls to their smart contracts - especially in a multi-hop swap - is quite expensive. This design was required since each pool was its own contract and token transfers were required to maintain accounting and solvency.

With the singleton architecture, a better design was possible and is referred to as *Flash Accounting*. The design became practical with gas efficiencies of [Transient Storage](https://eips.ethereum.org/EIPS/eip-1153). *Flash Accounting* further reduces the gas cost of trades that cross multiple pools and supports more complex integrations with Uniswap v4.

With *flash accounting*, each balance-changing operation (e.g. swap and liquidity modification) updates an internal net balance known as `delta`. Only the final balance-changes require token transfers.

<img alt="Flash Accounting Step 1" src={__img0} placeholder="blur" />
<img alt="Flash Accounting Step 2" src={__img1} placeholder="blur" />

For example from the above diagrams - let's say you have 20 `USDC` and 20 `USDT` but you want to add liquidity with 15 `USDC` and 25 `USDT`. Previously this would require multiple external calls as tokens were transferred between Pool contracts when swapping from `USDC` to `USDT`. But now with v4's Flash Accounting we only need to keep track of `delta` - thus we can `swap` and `modifyLiquidity` in a single call and only the final balance-changes involve actual token transfers.

In the above example, we are swapping 5 USDC to 5 USDT to create liquidity with 15 USDC and 25 USDT. In between the operations (*swap, modifyLiquidity*), no token transfers are made

## Mechanism
## Locking
To ensure correctness and atomicity in complex operations like a multi-hop swap - v4 uses a locking mechanism. Anytime key actions need to take place within the `PoolManager` - e.g. swaps and liquidity modification - a periphery contract must `unlock` the `PoolManager` first. Then integrators implement the `unlockCallback` and proceed with any of the following actions on the pools:

* swap
* modifyLiquidity
* donate
* take
* settle
* mint
* burn
* sync

*Note that pool initialization can happen outside the context of unlocking the `PoolManager`, as there are no balance-changing operations associated with pool creation.*

The following diagrams visualize how the above steps will be implemented:

1. `unlock` the `PoolManager`
   <img alt="Flash Accounting Locking Mechanism Step 1" src={__img2} placeholder="blur" />

2. Implement `unlockCallback` and proceed with any desired pool actions
   <img alt="Flash Accounting Locking Mechanism Step 2" src={__img3} placeholder="blur" />

3. The actual token transfer happens at the end and the *delta* should be resolved
   <img alt="Flash Accounting Locking Mechanism Step 3" src={__img4} placeholder="blur" />

## Balance delta
Inside `unlockCallback`, a periphery contract performs balance-changing operations i.e. conduct swaps, modify positions, etc. After returning execution context back to `PoolManager`, the core contract checks that balances are resolved - nothing is owed to or from the `PoolManager`.

The balances resolved above is what we refer as the `delta`, a field held in the *transient* state. The value(s) represent the *debts* and *credits* of assets owed to or from the `PoolManager`.

## Swapping
<img alt="Multi-hop swaps on v3 vs v4" src={__img5} placeholder="blur" />

As shown in the above diagram, for example - let's say you want to swap `ETH` for `DAI`. Assuming this requires a multi-hop swap going from `ETH` to `USDC` and then from `USDC` to `DAI`.

## Previously on v3
1. `ETH` is transferred to `ETH <> USDC` pool contract

2. `USDC` is withdrawn from `ETH <> USDC` contract and transferred to `USDC <> DAI` contract

3. `DAI` is withdrawn from `USDC <> DAI` contract and transferred to the user

## Now on v4
1. Call `swap()` on `ETH <> USDC`

2. Call `swap()` on `USDC <> DAI`, with the credit of USDC from above being used as the input amount

3. User *resolves deltas* by paying ETH and receiving DAI

Therefore we can skip the step of actually calling `transfer()` on the USDC contract.

The optimization scales infinitely, any number of arbitrary hops only requires two token transfers - input and output tokens.

## Liquidity Management
The optimization becomes more evident for complex liquidity operations

For example, a user wanted to add liquidity to `ETH <> DAI` but does not have DAI. The user can swap some `ETH` to `DAI` in order to add liquidity with both tokens. In addition, the user can multi-hop swap going from `ETH` to `USDC` to `DAI`. If properly integrated, the user would only need to transfer ETH *once*.

## Developer Resources
To see how unlock callbacks and deltas work in a smart contract, read [Unlock Callback and Deltas](/docs/protocols/v4/guides/unlock-callback-and-deltas).
