# [Technical Reference編] UniswapV3のドキュメントを読んでみよう！

> Uniswap V3は、多くのライブラリで構成されたバイナリスマートコントラクトシステムで、これらのライブラリはCore（コア）とPeriphery（周辺）を形成しています。

- URL: https://cardene.dev/articles/b5a4293f85fd1a
- 公開日: 2023-09-11
- 更新日: 2023-09-11
- トピック: Blockchain
- タグ: solidity, ethereum, smartcontract, defi

# はじめに

初めまして。
**CryptoGames**というブロックチェーンゲーム企業でエンジニアをしている **cardene（かるでね）** です！
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームは**クリプトスペルズ**というブロックチェーンゲームです。

https://cryptospells.jp/

今回は**Uniswap V3**の公式ドキュメント内の**Technical Reference**の章を翻訳・補足しながらまとめていきたいと思います。

公式ドキュメントは以下になります。

https://docs.uniswap.org/contracts/v3/reference/overview

# 概要

**Uniswap V3**は、多くのライブラリで構成されたバイナリスマートコントラクトシステムで、これらのライブラリは**Core**（コア）と**Periphery**（周辺）を形成しています。

**Core**コントラクトは、**Uniswap**のプール生成のロジック、プール自体、それらのアセットに関与する対話のロジックを定義します。

**Periphery**コントラクトは、1つまたは複数の**Core**コントラクトと対話しますが、コアの一部ではありません。
コアとやり取りする機能を提供し、クラリティとユーザーの安全性を向上させるために設計されています。

外部の呼び出し時は主に**Periphery**インターフェースを呼び出します。
外部から利用可能な関数は、リファレンスドキュメントで確認できます。
一方、内部関数は**Uniswap V3**のGitHubリポジトリで確認できます。

## コア

- [**Coreのソースコード](https://github.com/Uniswap/v3-core)

コア（**Core**）は、単一のファクトリ（**Factory**）、プールデプロイヤー（**Pool Deployer**）、およびファクトリが生成する多くのプールで構成されています。

コアコントラクトでは、ガスの最適化を行った結果V2に比べてすべてのプロトコルのやり取りにおけるガスコストが大幅に削減されましたが、コーそが複雑になりました。

### ファクトリ

- [**Factory Reference**](https://docs.uniswap.org/contracts/v3/reference/core/UniswapV3Factory)

ファクトリ（**Factory**）は、プールを生成するためのロジックを定義します。

:::message
プールは2つのトークンで定義され、これらのトークンはアセットペアを構成し、手数料（**fee**）も指定されます。
同じアセットペアに対して複数のプールが存在できますが、それらは唯一の違いとしてスワップ手数料（**swap fee**）で区別されます。
:::

### プール

- [**Pool Reference**](https://docs.uniswap.org/contracts/v3/reference/core/UniswapV3Pool)

プールは、主にペアとなるアセットの自動マーケットメーカーとして機能します。
さらに、価格オラクルデータを公開し、フラッシュトランザクションのアセットソースとして使用できます。

:::message
プールは2つの異なるアセットを取り扱う市場を自動的に形成し、ユーザーがアセットを交換できるようにします。
また、プールは市場の価格情報を提供し、他のスマートコントラクトが価格情報を利用できるようにします。
さらに、プールはフラッシュトランザクションの時にアセットの供給元として機能し、トークンの取引を効率的に行うのに役立ちます。
:::

## Periphery

コアとのドメイン固有のやり取りをサポートするために設計された一連のスマートコントラクト。
**Uniswap**プロトコルはパーミッションレスシステムであるため、以下で説明するコントラクトには特別な権限を持たず、コアと連携して特定の操作を行うために使用さます。

### SwapRouter

- [**Swap Router Reference**](https://docs.uniswap.org/contracts/v3/reference/periphery/SwapRouter)

- [**Swap Router Interface**](https://docs.uniswap.org/contracts/v3/reference/periphery/interfaces/ISwapRouter)

**SwapRouter**は、取引を提供するフロントエンドの基本的な要件をすべてサポートしています。
シングル取引（`x→y`）とマルチホップ取引（`x→y→z`など）をネイティブにサポートしています。

### Nonfungible Position Manager

- [Nonfungible Position Manager Reference](https://docs.uniswap.org/contracts/v3/reference/periphery/NonfungiblePositionManager)

- [Nonfungible Position Manager Interface](https://docs.uniswap.org/contracts/v3/reference/periphery/interfaces/INonfungiblePositionManager)

ポジション・マネジャーは、ポジションの作成、調整、または終了を含むロジック・ トランザクションを処理します。

### Oracle

- [Oracle Reference](https://docs.uniswap.org/contracts/v3/reference/core/libraries/Oracle)

オラクルは、さまざまなシステム設計に役立つ価格と流動性のデータを提供し、すべてのプールで利用できます。

### Periphery Libraries

- [Periphery Libraries](https://docs.uniswap.org/contracts/v3/reference/periphery/libraries/Base64)

ライブラリーは、プールアドレスの計算や安全な転送関数など、開発者が必要とする様々なヘルパー関数を提供します。

# Core

## UniswapV3Factory

**Uniswap V3**プールをデプロイし、プールプロトコル料金の所有権と管理権を管理します。

### createPool

```solidity
function createPool(
	address tokenA,
	address tokenB,
	uint24 fee
) external returns (address pool)
```

与えられた2つのトークンと料金のプールを作成する関数。

`tokenA`と`tokenB`は、`token0/token1`または`token1/token0`のいずれかの順序で渡される。
プールが既に存在する場合、料金が無効な場合、またはトークン引数が無効な場合、実行は失敗します。

**パラメータ**

| 名前 | 型 | 説明 |
|-----|-------|------|
| `tokenA` | address  | プール内のアセットの1つ。 |
| `tokenB` | address  | プール内のもう1つのアセット。 |
| `fee` | uint24 | プールで望む手数料。 |

**戻り値**

| 名前 | 型 | 説明 |
|-----|-------|------|
| `pool` | address | 新しく作成されたプールのアドレス。 |


### setOwner

```solidity
function setOwner(
	address _owner
) external
```

ファクトリーオーナーを更新する関数。

現在の所有者のみ実行できます。

**パラメータ**

| 名前 | 型 | 説明 |
|-----|-------|------|
| `_owner` | address | 新しいオーナーのアドレス。 |

### enableFeeAmount

```solidity
function enableFeeAmount(
	uint24 fee,
	int24 tickSpacing
) public
```

指定された`tickSpacing`で手数料を有効にする関数。

手数料は一度有効にすると削除できません。

**パラメータ**

| 名前 | 型 | 説明 |
|-----|-------|------|
| `fee` | uint24 | プールに設定する手数料の金額。`bip`の百分の一で表されます（つまり、`1e-6`）。 |
| `tickSpacing` | int24 | 指定された手数料で作成されたすべてのプールに対して強制される、トック間のスペーシング（間隔）。 |

## UniswapV3Pool

### _blockTimestamp

```solidity
function _blockTimestamp(
) internal view virtual returns (uint32)
```

ブロック・タイムスタンプを`32`ビットに切り詰めたもので、`mod 2**32`を返す関数。

### snapshotCumulativesInside

```solidity
function snapshotCumulativesInside(
	int24 tickLower,
	int24 tickUpper
) external view override noDelegateCall returns (int56 tickCumulativeInside, uint160 secondsPerLiquidityInsideX128, uint32 secondsInside)
```

ティック累積、流動性ごとの秒数、ティック範囲内の秒数のスナップショットを返す関数。

スナップショットは、ポジションが存在する期間にわたって取得された他のスナップショットとのみ比較できます。
つまり、最初のスナップショットが取得されると、2番目のスナップショットが取得されるまでの期間にポジションが保持されていない場合、スナップショットを比較することはできません。

以下は表形式でパラメータと返り値を示したものです：

**パラメータ**

| 名前          | 型   | 説明                        |
|---------------|----------|-----------------------------|
| `tickLower`     | int24    | レンジの下限となるtick。      |
| `tickUpper`     | int24    | レンジの上限となるtick。       |

**戻り値**

| 名前                          | 型     | 説明                                      |
|-------------------------------|------------|-------------------------------------------|
| `tickCumulativeInside`          | int56      | レンジのtickアキュムレータのスナップショット。   |
| `secondsPerLiquidityInsideX128` | uint160    | レンジの流動性あたりの秒数のスナップショット。 |
| `secondsInside`                 | uint32     | レンジの内部の秒数のスナップショット。         |

### observe

```solidity
function observe(
	uint32[] secondsAgos
) external view override noDelegateCall returns (int56[] tickCumulatives, uint160[] secondsPerLiquidityCumulativeX128s)
```

現在のブロックタイムスタンプから指定された秒数前の各タイムスタンプにおける累積tickと流動性を返す関数。

時間加重平均`tick`または範囲内の流動性を取得するには、2つの値を使用して呼び出す必要があります。
1つは期間の開始を表し、もう1つは期間の終了を表します。
例えば、最後の1時間の時間加重平均`tick`を取得するには、`secondsAgos = [3600, 0]`として呼び出す必要があります。
時間加重平均`tick`は、プールの幾何学的な時間加重平均価格を表し、`log base sqrt(1.0001)`で`token1 / token0`の比率を表します。
**TickMath**ライブラリを使用して、`tick`値から比率に変換することができます。

**パラメータ**

| 名前         | 型     | 説明                                       |
|--------------|------------|--------------------------------------------|
| `secondsAgos`  | uint32[]   | 各累積tickと流動性値を取得するための経過秒数。 |

**戻り値**

| 名前                                  | 型     | 説明                                                  |
|---------------------------------------|------------|-------------------------------------------------------|
| `tickCumulatives`                       | int56[]    | 各`secondsAgos`からの現在のブロックタイムスタンプでの累積tick値。 |
| `secondsPerLiquidityCumulativeX128s`    | uint160[]  | 各`secondsAgos`からの現在のブロックタイムスタンプでの累積流動性インレンジの秒数値。 |

### increaseObservationCardinalityNext

```solidity
function increaseObservationCardinalityNext(
	uint16 observationCardinalityNext
) external override lock noDelegateCall
```

このプールが保持する価格と流動性の観測値の最大数を増やす関数。

ただし、プールが既に引数の`observationCardinalityNext`以上の`observationCardinalityNext`を持っている場合、何も実行されません。
既に必要な数以上の観測値を保持している場合には、何も変更されないということです。

**パラメータ**

| 名前         | 型     | 説明                                       |
|--------------|------------|--------------------------------------------|
| `observationCardinalityNext`  | uint16   | 保存するプールに必要な最小観測数。 |

### initialize

```solidity
function initialize(
	uint160 sqrtPriceX96
) external override
```

プールの初期価格を設定する関数。
初期化時はロックされていない状態で初期化されます。

**パラメータ**

| 名前           | 型     | 説明                                        |
|----------------|------------|---------------------------------------------|
| `sqrtPriceX96`   | uint160    | プールの初期平方根価格          |

### mint

```solidity
function mint(
	address recipient,
	int24 tickLower,
	int24 tickUpper,
	uint128 amount,
	bytes data
) external override lock returns (uint256 amount0, uint256 amount1)
```

指定された受取アドレス（`recipient`）、ポジションの下限（`tickLower`）、上限（`tickUpper`）に対して流動性を追加する関数。

**パラメータ**

| 名前        | 型     | 説明                                              |
|-------------|------------|---------------------------------------------------|
| `recipient`   | address    | 流動性が作成される受取アドレス。                  |
| `tickLower`   | int24      | 流動性を追加するポジションの下限となるtick。        |
| `tickUpper`   | int24      | 流動性を追加するポジションの上限となるtick 。       |
| `amount`      | uint128    | 生成する流動性の量。                                |
| `data`        | bytes      | コールバックに渡すべき任意のデータ。               |

**戻り値**

| 名前        | 型     | 説明                                              |
|-------------|------------|---------------------------------------------------|
| `amount0`     | uint256    | 指定した流動性の生成に使用されたtoken0の量。コールバック内の値と一致します。 |
| `amount1`     | uint256    | 指定した流動性の生成に使用されたtoken1の量。コールバック内の値と一致します。 |

### collect

```solidity
function collect(
	address recipient,
	int24 tickLower,
	int24 tickUpper,
	uint128 amount0Requested,
	uint128 amount1Requested
) external override lock returns (uint128 amount0, uint128 amount1)
```

ポジションに支払われるべきトークンを収集する関数。
ポジションの所有者によってのみ実行されます。

**パラメータ**

| 名前                 | 型     | 説明                                                     |
|----------------------|------------|----------------------------------------------------------|
| `recipient`            | address    | 収集した料金を受け取るアドレス。                              |
| `tickLower`            | int24      | 料金を収集するポジションの下限tick。                          |
| `tickUpper`            | int24      | 料金を収集するポジションの上限tick。                          |
| `amount0Requested`     | uint128    | 料金からトークン0を引き出す金額（トークン0の料金）。           |
| `amount1Requested`     | uint128    | 料金からトークン1を引き出す金額（トークン1の料金）。           |

**戻り値**

| 名前        | 型     | 説明                                              |
|-------------|------------|---------------------------------------------------|
| `amount0`     | uint128    | トークン0で収集された料金の量。                   |
| `amount1`     | uint128    | トークン1で収集された料金の量。                   |

### burn

```solidity
function burn(
	int24 tickLower,
	int24 tickUpper,
	uint128 amount
) external override lock returns (uint256 amount0, uint256 amount1)
```

指定された範囲内の流動性を消費して、実行アドレスに送付する関数。

**パラメータ**

| 名前             | 型     | 説明                                              |
|------------------|------------|---------------------------------------------------|
| `tickLower`    | int24      | 流動性を消費するポジションの下限tick。           |
| `tickUpper`    | int24      | 流動性を消費するポジションの上限tick。          |
| `amount`       | uint128    | 消費する流動性の量。                          |

**戻り値**

| 名前        | 型     | 説明                                              |
|-------------|------------|---------------------------------------------------|
| `amount0`     | uint256    | 受信者に送信されるトークン0の量。             |
| `amount1`     | uint256    | 受信者に送信されるトークン1の量。            |

### swap

```solidity
function swap(
	address recipient,
	bool zeroForOne,
	int256 amountSpecified,
	uint160 sqrtPriceLimitX96,
	bytes data
) external override noDelegateCall returns (int256 amount0, int256 amount1)
```

トークン0をトークン1に交換するか、トークン1をトークン0に交換する関数。

**パラメータ**

| 名前             | 型     | 説明                                              |
|------------------|------------|---------------------------------------------------|
| `recipient`        | address    | 交換の出力を受け取るアドレス。              |
| `zeroForOne`       | bool       | 交換の方向。トークン0からトークン1への場合は`true`、トークン1からトークン0への場合は`false`。 |
| `amountSpecified`  | int256     | 交換の量。正の値の場合は入力を正確に指定し、負の値の場合は出力を正確に指定します。 |
| `sqrtPriceLimitX96` | uint160   | **Q64.96**の平方根価格制限。`zeroForOne`が`true`の場合、交換後の価格はこの値未満にならない。`zeroForOne`が`false`の場合、交換後の価格はこの値を超えない。 |
| `data`             | bytes      | コールバックに渡すべき任意のデータ。               |

**戻り値**

| 名前        | 型     | 説明                                              |
|-------------|------------|---------------------------------------------------|
| `amount0`     | int256     | プールのトークン0の残高の変化。負の値の場合、正確。正の値の場合、最小。                    |
| `amount1`     | int256     | プールのトークン1の残高の変化。負の値の場合、正確。正の値の場合、最小。                    |

### flash

```solidity
function flash(
	address recipient,
	uint256 amount0,
	uint256 amount1,
	bytes data
) external override lock noDelegateCall
```

トークン0と/またはトークン1を受け取り、コールバック内で手数料を含めて返金する関数。

**パラメータ**

| 名前             | 型     | 説明                                              |
|------------------|------------|---------------------------------------------------|
| `recipient`        | address    | トークン0とトークン1の量を受け取るアドレス。   |
| amount0          | uint256    | 送信するトークン0の量。                      |
| amount1          | uint256    | 送信するトークン1の量。                    |
| data             | bytes      | コールバックに渡すべき任意のデータ。       |


### setFeeProtocol

```solidity
function setFeeProtocol(
	uint8 feeProtocol0,
	uint8 feeProtocol1
) external override lock onlyFactoryOwner
```

プロトコルが受け取る手数料の割合を設定する関数。

**パラメータ**

| 名前             | 型     | 説明                                              |
|------------------|------------|---------------------------------------------------|
| `feeProtocol0`     | uint8      | プールのトークン0の新しいプロトコル手数料。         |
| `feeProtocol1`     | uint8      | プールのトークン1の新しいプロトコル手数料。         |

### collectProtocol

```solidity
function collectProtocol(
	address recipient,
	uint128 amount0Requested,
	uint128 amount1Requested
) external override lock onlyFactoryOwner returns (uint128 amount0, uint128 amount1)
```

プールに蓄積されたプロトコル手数料を収集する関数。

**パラメータ**

| 名前                 | 型     | 説明                                                    |
|----------------------|------------|---------------------------------------------------------|
| `recipient`            | address    | 収集されたプロトコル手数料を送信するアドレス。                   |
| `amount0Requested`     | uint128    | 送信するトークン0の最大額、トークン1のみで手数料を収集する場合は0にできます。   |
| `amount1Requested`     | uint128    | 送信するトークン1の最大額、トークン0のみで手数料を収集する場合は0にできます。   |

**戻り値**

| 名前     | 型     | 説明                    |
|----------|------------|-------------------------|
| `amount0`  | uint128    | トークン0で収集されたプロトコル手数料。 |
| `amount1`  | uint128    | トークン1で収集されたプロトコル手数料。 |


## UniswapV3PoolDeployer

### deploy

```solidity
function deploy(
	address factory,
	address token0,
	address token1,
	uint24 fee,
	int24 tickSpacing
) internal returns (address pool)
```

指定されたパラメータでプールをデプロイする関数。
プールのデプロイ後、パラメータのストレージスロットを一時的に設定し、プールのデプロイが完了した後クリアします。

**パラメータ:**

| 名前          | 型     | 説明                                      |
|---------------|------------|-------------------------------------------|
| `factory`       | address    | **Uniswap V3**ファクトリのコントラクトアドレス。    |
| `token0`        | address    | アドレス順に並べたときのプールの最初のトークン。 |
| `token1`        | address    | アドレス順に並べたときのプールの2番目のトークン。 |
| `fee`           | uint24     | プール内の各スワップで徴収される手数料（bipの1/100）。 |
| `tickSpacing`   | int24      | 使用可能なティック間のスペーシング。               |

## インターフェース

### IUniswapV3Factory

#### owner

```solidity
function owner() external view returns (address)
```

現在のファクトリのオーナー（所有者）を返す関数。
オーナーは`setOwner`を通じて変更できます。

**戻り値**

| 型     | 説明                |
|------------|---------------------|
| `address`    | ファクトリのオーナーのアドレス。 |

#### feeAmountTickSpacing

```solidity
function feeAmountTickSpacing(
	uint24 fee
) external view returns (int24)
```

指定された手数料額に対するティック間隔を返す関数。
手数料が有効に設定されている場合はその値を返し、無効の場合は`0`を返します。

**パラメータ**

| 名前  | 型   | 説明                                      |
|-------|----------|-------------------------------------------|
| `fee`   | uint24   | 手数料の額（bipの1/100）。無効な場合は`0`を返す。 |

**戻り値**

| 型 | 説明               |
|--------|--------------------|
| `int24`  | ティック間隔。       |

#### getPool

```solidity
function getPool(
	address tokenA,
	address tokenB,
	uint24 fee
) external view returns (address pool)
```

指定されたトークンペアと手数料に対するプールのアドレスを返す関数。
プールが存在しない場合はアドレス`0`を返します。

トークンAとトークンBは、`token0/token1`の順序または`token1/token0`の順序のどちらでも渡すことができます。

**パラメータ**

| 名前    | 型   | 説明                                      |
|---------|----------|-------------------------------------------|
| `tokenA`  | address  | トークン0またはトークン1のコントラクトアドレス。   |
| `tokenB`  | address  | もう一方のトークンのコントラクトアドレス。   |
| `fee`     | uint24   | 手数料（bipの1/100）。                       |

**戻り値**

| 名前 | 型   | 説明           |
|------|----------|----------------|
| `pool` | address  | プールのアドレス。 |


### IUniswapV3PoolDeployer

プールを構築するコントラクトは、プールに引数を渡すために以下の機能を実装する必要があります。
これにより、プールコントラクト内にコンストラクタ引数を持たないようにできます。
その結果、プールのイニシャライザのコードハッシュが一定になり、プールの**CREATE2**アドレスをコストをかけずにオンチェーンで計算できるようになります。

#### parameters

```solidity
function parameters() external view returns (address factory, address token0, address token1, uint24 fee, int24 tickSpacing)
```

プールの構築に使用されるパラメーターを取得する関数。

**戻り値**

| 名前           | 型    | 説明                                                 |
| -------------- | --------- | ---------------------------------------------------- |
| `factory`        | アドレス  | ファクトリーのアドレス。                               |
| `token0`         | アドレス  | アドレス順にソートされたプールの最初のトークン。     |
| `token1`         | アドレス  | アドレス順にソートされたプールの2番目のトークン。    |
| `fee`            | uint24    | プール内の各スワップで徴収される手数料。BIPの百分の一で表されます。 |
| `tickSpacing`    | int24     | 初期化されたティック間の最小ティック数。               |

### IUniswapV3FlashCallback

#### uniswapV3FlashCallback

```solidity
function uniswapV3FlashCallback(
	uint256 fee0,
	uint256 fee1,
	bytes data
) external
```

**IUniswapV3Pool**の`flash`から受け取ったトークンと計算された手数料を返す関数。
呼び出し元が「**UniswapV3Factory**」によってデプロイされた「**UniswapV3Pool**」であることを確認する必要があります。

**パラメータ**

| 名前 | 型     | 説明                                                         |
| -------------- | -------- | ------------------------------------------------------------ |
| `fee0`           | uint256 | flashの終了時にプールに支払われるトークン0の手数料金額。          |
| `fee1`           | uint256 | flashの終了時にプールに支払われるトークン1の手数料金額。          |
| `data`           | bytes   | IUniswapV3PoolActions#flash呼び出し元から渡される任意のデータ。 |

### IUniswapV3MintCallback

#### uniswapV3MintCallback

```solidity
function uniswapV3MintCallback(
	uint256 amount0Owed,
	uint256 amount1Owed,
	bytes data
) external
```

**IUniswapV3Pool**の`mint`関数を実行してポジションに流動性をミントした後、`msg.sender`によって呼び出される関数。

`mint`された流動性に対してプールに支払うためのトークンを支払う必要があります。
この関数の呼び出し元は、**UniswapV3Factory**によって展開された**UniswapV3Pool**であることを確認する必要があります。

**パラメータ**

| 名前          | 型 | 説明                                                             |
|---------------|-----------|------------------------------------------------------------------|
| `amount0Owed`   | uint256   | mintされた流動性に対してプールに支払うためのトークン0の金額。   |
| `amount1Owed`   | uint256   | mintされた流動性に対してプールに支払うためのトークン1の金額。   |
| `data`          | bytes     | IUniswapV3PoolActions#mint呼び出し時に呼び出し元から渡されるデータ。 |

### IUniswapV3SwapCallback

#### uniswapV3SwapCallback

```solidity
function uniswapV3SwapCallback(
	int256 amount0Delta,
	int256 amount1Delta,
	bytes data
) external
```

**IUniswapV3Pool**の`swap`関数を通じてスワップを実行した後に、`msg.sender`によって呼び出される関数。

スワップによってプールに支払われるトークンを返済する必要があります。
呼び出し元が「**UniswapV3Factory**」によってデプロイされた「**UniswapV3Pool**」であることを確認する必要があります。


| 名前          | 型     | 説明                                         |
|---------------|--------|----------------------------------------------|
| `amount0Delta`  | int256 | スワップの終了時にプールによって送信された（負の値）または受け取られる（正の値）トークン0の量。正の値の場合、コールバックはその量のトークン0をプールに送信する必要があります。 |
| `amount1Delta`  | int256 | スワップの終了時にプールによって送信された（負の値）または受け取られる（正の値）トークン1の量。正の値の場合、コールバックはその量のトークン1をプールに送信する必要があります。 |
| `data`          | bytes  | IUniswapV3PoolActions#swap呼び出し時に呼び出し元によって渡された任意のデータ。             |

### Pool

以下を参考にしてください。

https://zenn.dev/cryptogames/articles/61ee19994743fd#uniswapv3pool

## ライブラリ

### BitMath

符号なし整数のビットプロパティを計算する機能を提供するライブラリ。

#### mostSignificantBit

```solidity
function mostSignificantBit(
	uint256 x
) internal pure returns (uint8 r)
```

指定された数値の最も有効なビット（最も左の1のビット）のインデックスを返す関数。
最も右のビットのインデックスは`0`で、最も左のビットのインデックスは`255`です。

この関数は次の条件を満たします。
`x >= 2^mostSignificantBit(x)`および`x < 2^(mostSignificantBit(x)+1)`。

:::message
与えられた数値の最も有効なビットが何ビット目かを返し、そのビットが`1`であることを示します
最も有効なビットは最も大きな値を持っており、それより下位のビットはすべて`0`です。
:::

:::message
**有効なビット**
二進数表現において、値が`1`であるビットのことを指します。
例えば、整数`10`を二進数で表すと「`1010`」です。
この場合、左から3番目と左から1番目のビットが有効なビットであり、値が`1`です。残りのビット（左から2番目と左から0番目）は`0`です。

最も有効なビットは、最も左に位置し、値が`1`であるビットです。
最も有効なビットが`1`であるかどうかによって、数値の大小や性質が決まることがあります。
最も有効なビットの位置を特定することは、数値の特性を理解するために重要な役割を果たし、「**最も左の1のビット**」とも呼ばれます。
:::

**パラメータ**

| 名前       | 型      | 説明                                        |
|------------|---------|---------------------------------------------|
| `x`          | uint256 | 最も有意なビットを計算する値、0より大きい必要があります。 |

**戻り値：**

| 名前 | 型     | 説明                                      |
|------|--------|-------------------------------------------|
| `r`    | unit8  | 最も有意なビットのインデックス。          |

#### leastSignificantBit

```solidity
function leastSignificantBit(
	uint256 x
) internal pure returns (uint8 r)
```

与えられた数値の最も右側（最下位）のビットのインデックスを返す関数。
最も右側のビットはインデックス`0`にあり、最も左側のビットはインデックス`255`にあります。

この関数は、与えられた数値`x`に対して次の性質が満たされることを確認します。

1. `(x & 2^leastSignificantBit(x)) != 0`
`x`の2進数表現において最も右側のビット（最下位ビット）が`1`に設定されているかどうかを確認します。
2. `(x & (2^(leastSignificantBit(x)) - 1)) == 0`
最も右側のビット以外のすべてのビットが`0`に設定されているかどうかを確認します。

この関数は`x`内の最も右側（最下位）の`1`ビットの位置を見つけるのに役立ちます。

もちろんです。以下は、指定された関数のパラメータと戻り値を表形式で示したものです。

申し訳ありません、指示に従い修正いたします。

**パラメータ**

| 名前       | 型         | 説明                                                     |
|------------|------------|----------------------------------------------------------|
| `x`          | uint256    | 最も右側のビットを計算するための値。0より大きい必要があります。 |

**戻り値**

| 名前       | 型         | 説明                                                     |
|------------|------------|----------------------------------------------------------|
| `r`          | uint8      | 最も右側（最下位）のビットのインデックス。                |

### FullMath

中間値のオーバーフローが発生しても精度を損なわずに乗算と除算を行うライブラリ。

:::message
`256`ビットを超える中間値のオーバーフローを処理し、正確な結果を得ることができます。
これを「**ファントムオーバーフロー**」と呼びます。
通常の整数演算ではオーバーフローが発生してしまうような大きな計算でも、このライブラリを使用することで正確な計算結果を得ることができます。
:::

#### mulDiv

```solidity
function mulDiv(
	uint256 a,
	uint256 b,
	uint256 denominator
) internal pure returns (uint256 result)
```

完全な精度で`floor(a×b÷denominator)`を計算する関数。
ただし、計算結果が`uint256`をオーバーフローする場合や`denominator`が`0`の場合にはエラーを返します。

与えられた`a`と`b`の値を掛け合わせて、`denominator`で割った結果を小数点以下を切り捨てて計算します。

**パラメータ**
| 名前          | 型         | 説明                                 |
|---------------|------------|--------------------------------------|
| `a`           | uint256    | 乗数となる値。                       |
| `b`           | uint256    | 乗数となる値。                       |
| `denominator` | uint256    | 除数となる値。                       |

**戻り値**
| 名前      | 型         | 説明                     |
|-----------|------------|--------------------------|
| `result`  | uint256    | 256ビットの計算結果。   |


#### mulDivRoundingUp

```solidity
function mulDivRoundingUp(
	uint256 a,
	uint256 b,
	uint256 denominator
) internal pure returns (uint256 result)
```

完全な精度で`ceil(a×b÷denominator)`を計算する関数。
ただし、計算結果が`uint256`をオーバーフローする場合や`denominator`が`0`の場合にはエラーを返します。

:::message
`ceil(a×b÷denominator)`は、小数点以下を切り上げて最も近い整数値を求める計算を行います。
:::

**パラメータ**

| 名前          | 型      | 説明                       |
| ------------- | ------- | -------------------------- |
| `a`             | uint256 | 乗数。                     |
| `b`             | uint256 | 乗数。                     |
| `denominator`   | uint256 | 除数。                     |

**戻り値**

| 名前        | 型      | 説明                         |
| ----------- | ------- | ---------------------------- |
| `result`      | uint256 | 256ビットの計算結果。切り捨て。 |


### LiquidityMath

#### addDelta

```solidity
function addDelta(
	uint128 x,
	int128 y
) internal pure returns (uint128 z)
```

「**署名付き流動性デルタ**」を流動性に追加する関数。
オーバーフローまたはアンダーフローが発生した場合は処理を取り消します。

**Parameters**

| 名前           | 型      | 説明                          |
|----------------|---------|-------------------------------|
| `x`            | `uint128` | 変更前の流動性。                |
| `y`            | `int128`  | 流動性を変更するデルタ。           |

**Return Values:**

| 名前           | 型      | 説明                          |
|----------------|---------|-------------------------------|
| `z`            | `uint128` | 流動性のデルタ。                  |

### LowGasSafeMath

#### add

```solidity
function add(
	uint256 x,
	uint256 y
) internal pure returns (uint256 z)
```

2つの整数`x`と`y`を受け取り、それらを足し合わせた結果を返す関数。

**パラメータ**

| 名前 | 型       | 説明              |
| ---- | -------- | ----------------- |
| `x`  | `uint256` | 足される値。     |
| `y`  | `uint256` | 加算する値。     |

**戻り値:**

| 名前 | 型       | 説明                 |
| ---- | -------- | -------------------- |
| `z`  | `uint256` | `x`と`y`の合計値。 |


#### sub

```solidity
function sub(
	uint256 x,
	uint256 y
) internal pure returns (uint256 z)
```

2つの整数`x`と`y`を受け取り、それらを引いた結果を返す関数。

**パラメータ**

| 名前 | 型       | 説明              |
| ---- | -------- | ----------------- |
| `x`  | `uint256` | 引かれる値。     |
| `y`  | `uint256` | 減算する値。     |

**戻り値:**

| 名前 | 型       | 説明                 |
| ---- | -------- | -------------------- |
| `z`  | `uint256` | `x`と`y`の差。 |

#### mul

```solidity
function mul(
	uint256 x,
	uint256 y
) internal pure returns (uint256 z)
```

2つの整数`x`と`y`を受け取り、それらをかけわせた結果を返す関数。

**パラメータ**

| 名前 | 型       | 説明              |
| ---- | -------- | ----------------- |
| `x`  | `uint256` | かけられる値。     |
| `y`  | `uint256` | かける値。     |

**戻り値:**

| 名前 | 型       | 説明                 |
| ---- | -------- | -------------------- |
| `z`  | `uint256` | `x`と`y`の積。 |

#### add

```solidity
function add(
	uint256 x,
	uint256 y
) internal pure returns (uint256 z)
```

2つの整数`x`と`y`を受け取り、それらを足し合わせた結果を返す関数。
オーバーフローかアンダーフローした場合は`revert`する。

**パラメータ**

| 名前 | 型       | 説明              |
| ---- | -------- | ----------------- |
| `x`  | `uint256` | 足される値。     |
| `y`  | `uint256` | 加算する値。     |

**戻り値:**

| 名前 | 型       | 説明                 |
| ---- | -------- | -------------------- |
| `z`  | `uint256` | `x`と`y`の合計値。 |


#### sub

```solidity
function sub(
	uint256 x,
	uint256 y
) internal pure returns (uint256 z)
```

2つの整数`x`と`y`を受け取り、それらを引いた結果を返す関数。
オーバーフローかアンダーフローした場合は`revert`する。

**パラメータ**

| 名前 | 型       | 説明              |
| ---- | -------- | ----------------- |
| `x`  | `uint256` | 引かれる値。     |
| `y`  | `uint256` | 減算する値。     |

**戻り値:**

| 名前 | 型       | 説明                 |
| ---- | -------- | -------------------- |
| `z`  | `uint256` | `x`と`y`の差。 |

### Oracle

この機能は、さまざまなシステム設計に役立つ価格と流動性のデータを提供します。

**observations（観測値）** と呼ばれる、格納されたオラクルデータのインスタンスは、オラクル配列に収集されます。
すべてのプールは、オラクル配列の長さが`1`で初期化されます。
誰でも、オラクル配列の最大長さを増やすために`SSTORE`（ストレージにデータを格納するためのガスコストを伴う操作）を支払うことができます。
オラクル配列が完全に埋められると、新しいスロットが追加されます。
**observations**がオラクル配列の最大長さまで埋められると、**observations**は上書きされます。
オラクル配列の長さに関係なく、最も最近の観測値は、`observe()`に`0`を渡すことで取得できます。

#### initialize

```solidity
function initialize(
	struct Oracle.Observation[65535] self,
	uint32 time
) internal returns (uint16 cardinality, uint16 cardinalityNext)
```

オラクル配列を初期化し、最初のスロットにデータを書き込む関数。
この関数は、**observations**配列のライフサイクル中に1回だけ呼び出されます。

**パラメータ**

| **名前**       | **型**                          | **説明**                                                |
| -------------- | ------------------------------- | ------------------------------------------------------- |
| `self`           | struct Oracle.Observation[65535] | 格納されたオラクル配列。                               |
| `time`           | uint32                          | オラクルの初期化時刻。これは`block.timestamp`を`uint32`に切り詰めたものです。 |

**Return Values:**

| **名前**       | **型**   | **説明**                                     |
| -------------- | -------- | -------------------------------------------- |
| `cardinality`    | uint16   | オラクル配列内の要素数。                    |
| `cardinalityNext`| uint16   | 要素数に関係なく、オラクル配列の新しい長さ。|

#### write

```solidity
function write(
	struct Oracle.Observation[65535] self,
	uint16 index,
	uint32 blockTimestamp,
	int24 tick,
	uint128 liquidity,
	uint16 cardinality,
	uint16 cardinalityNext
) internal returns (uint16 indexUpdated, uint16 cardinalityUpdated)
```

オラクルの観測結果を配列に書き込む関数。

1ブロックにつき1回だけ書き込みが許可されます。
配列内のインデックスは、最後に書き込まれた要素を表します。
`cardinality`（要素数）と`index`（現在のインデックス位置）は外部でトラッキングする必要があります。
もし`index`が許容された配列長（`cardinality`に基づく）の最後にあり、次の`cardinality`が現在の`cardinality`よりも大きい場合、`cardinality`を増やすことができます。
この制限は順序を保つために導入されています。

以下は、指定された条件に基づいて整形された日本語のマークダウン表です。

**パラメータ**
| 名前            | 型         | 説明                                                   |
|-----------------|------------|--------------------------------------------------------|
| `self`          | `struct Oracle.Observation[65535]` | 格納されたオラクル配列。                            |
| `index`         | `uint16`   | 最も最近に更新された観測の位置。                 |
| `blockTimestamp`| `uint32`   | 新しい観測のタイムスタンプ。                     |
| `tick`          | `int24`    | 新しい観測時のアクティブなタイック。             |
| `liquidity`     | `uint128`  | 新しい観測時の合計範囲内の流動性。           |
| `cardinality`   | `uint16`   | オラクル配列内の要素の数。                        |
| `cardinalityNext`| `uint16`  | ポピュレーションに独立したオラクル配列の新しい長さ。|

**戻り値**
| 名前                 | 型         | 説明                                                   |
|----------------------|------------|--------------------------------------------------------|
| `indexUpdated`       | `uint16`   | オラクル配列内で最も最近書かれた要素の新しいインデックス。 |
| `cardinalityUpdated` | `uint16`   | オラクル配列の新しいカーディナリティ。                   |

#### grow

```solidity
function grow(
	struct Oracle.Observation[65535] self,
	uint16 current,
	uint16 next
) internal returns (uint16)
```
次の**observations**までを格納するオラクル配列を準備する関数。

**パラメータ**
| 名前     | 型             | 説明                                           |
|----------|----------------|------------------------------------------------|
| `self`   | struct Oracle.Observation[65535] | 保存されたオラクル配列。 |
| `current`| uint16         | オラクル配列の現在の次のカーディナリティ。          |
| `next`   | uint16         | オラクル配列にポピュレートされる提案された次のカーディナリティ。 |

**戻り値**
| 名前          | 型      | 説明                                           |
|---------------|---------|------------------------------------------------|
| `next`       | uint16  | オラクル配列にポピュレートされる次のカーディナリティ。 |

:::message
**ポピュレート**
新しい要素がオラクル配列に追加されるということです。
	
オラクル配列に新しい要素が追加された時に、その配列の要素数がどれくらい増加するかを指します。
**カーディナリティ**は、オラクル配列内の要素の数を表すもので、新しい要素が追加されるたびに増加します。

例えば現在のカーディナリティが`10`であり、新しい要素をオラクル配列に追加すると、次のカーディナリティが`11`になります。新しい要素がさらに追加されると、次のカーディナリティは`12`となります。
つまり、カーディナリティは、オラクル配列内の要素がどれだけ増加したかを示す数値です。
:::

#### observe

```solidity
function observe(
	struct Oracle.Observation[65535] self,
	uint32 time,
	uint32[] secondsAgos,
	int24 tick,
	uint16 index,
	uint128 liquidity,
	uint16 cardinality
) internal view returns (int56[] tickCumulatives, uint160[] liquidityCumulatives)
```

与えられた時間から一定の時間（**seconds ago**）前のアキュムレータの値を、`secondsAgos`という配列内の指定された時間ごとに返す関数。
最も古い観測時刻を超える`secondsAgos`が指定された場合にエラーを返します。

:::message
あるオラクルが1分ごとにデータを記録していると仮定し、`secondsAgos`が`[30, 60, 90]`のような配列で与えられた場合を考えます。

- **seconds ago**が`30`秒の場合、与えられた時間から`30`秒前のアキュムレータの値を返します。
- **seconds ago**が`60`秒の場合、与えられた時間から`60`秒前のアキュムレータの値を返します。
- **seconds ago**が`90`秒の場合、与えられた時間から`90`秒前のアキュムレータの値を返します。

ただし、最も古い観測時刻を超える`secondsAgos`が指定された場合、つまり過去のデータを取得しすぎた場合、エラーが発生します。
:::

**パラメータ**
| 名前           | 型               | 説明                                           |
|----------------|------------------|------------------------------------------------|
| `self`         | struct Oracle.Observation[65535] | 保存されたオラクル配列。 |
| `time`         | uint32           | 現在のブロックのタイムスタンプ。                 |
| `secondsAgos`  | uint32[]         | 過去の観測を取得するための時間間隔（秒単位）の配列。各要素は、観測を取得する際の遡る時間を示します。 |
| `tick`         | int24            | 現在のタイックの値。                             |
| `index`        | uint16           | オラクル配列内の特定の観測の位置。               |
| `liquidity`    | uint128          | 現在の範囲内プールの流動性。                   |
| `cardinality`  | uint16           | オラクル配列内に格納された要素の数。           |

**戻り値**
| 名前                | 型            | 説明                                                        |
|---------------------|---------------|-------------------------------------------------------------|
| `tickCumulatives`   | int56[]       | プールが初めて初期化されてからの、各`secondsAgo`ごとのタイム経過に対するタイック * タイムの累積値。 |
| `liquidityCumulatives`| uint160[]    | プールが初めて初期化されてからの、各`secondsAgo`ごとのタイム経過に対する流動性 * タイムの累積値。 |

### Position

ポジションは所有者のアドレスの、下限と上限のタイック境界間の流動性を表します。

:::message
ある所有者（アドレス）が、特定の取引の流動性を持っていることを示しています。
この流動性は、ある特定の価格範囲（下限と上限のタイック境界）内で提供されています。
つまり、ポジションは、所有者が特定の価格範囲で提供している流動性の情報を表すものです。
:::

ポジションは、ポジションに支払われるべき手数料を追跡するための追加の状態を保持します。

:::message
ポジションが、そのポジションに関連する手数料を正確に追跡するための情報を保持していることを示しています。
取引や流動性提供に関連する手数料が、このポジションに対してどのように蓄積されているかを追跡し、管理します。
:::

#### get

```solidity
function get(
	mapping(bytes32 => struct Position.Info) self,
	address owner,
	int24 tickLower,
	int24 tickUpper
) internal view returns (struct Position.Info position)
```

指定された所有者とポジションの境界をもとに、ポジションの情報（`Info`構造体）を返す関数。

以下は、指定された条件に従って整形されたパラメータと戻り値の表です。

**パラメータ**
| 名前           | 型              | 説明                                           |
|----------------|-----------------|------------------------------------------------|
| `self`         | mapping(bytes32 => struct Position.Info) | すべてのユーザーポジションを含むマッピング。 |
| `owner`        | address         | ポジションの所有者のアドレス。                |
| `tickLower`    | int24           | ポジションの下限タイック境界。               |
| `tickUpper`    | int24           | ポジションの上限タイック境界。               |

**戻り値**
| 名前              | 型                | 説明                                    |
|-------------------|-------------------|-----------------------------------------|
| `position`        | struct Position.Info | 指定された所有者のポジションの情報構造体。 |

#### update

```solidity
function update(
	struct Position.Info self,
	int128 liquidityDelta,
	uint256 feeGrowthInside0X128,
	uint256 feeGrowthInside1X128
) internal
```

ユーザーのポジションに蓄積された手数料を与える関数。

:::message
ユーザーが所有する特定のポジションに対して、これまでに蓄積された手数料を加算する操作を指します。
取引やその他の活動から発生した手数料が、ユーザーのポジションに追加されて、そのポジションの価値に影響を与えることを意味します。
手数料がポジションにクレジット（加算）されることで、ポジションの利益や損失が変動する可能性があります。
:::

**パラメータ**
| 名前                  | 型                 | 説明                                                    |
|-----------------------|--------------------|---------------------------------------------------------|
| `self`                | struct Position.Info | すべてのユーザーポジションを含むマッピング。         |
| `liquidityDelta`      | int128             | ポジションの更新によるプールの流動性の変化。           |
| `feeGrowthInside0X128`| uint256            | ポジションのタイック境界内での`token0`の累積手数料成長率（流動性単位あたり）。 |
| `feeGrowthInside1X128`| uint256            | ポジションのタイック境界内での`token1`の累積手数料成長率（流動性単位あたり）。 |

### SafeCast

型を安全にキャストします。

#### toUint160

```solidity
function toUint160(
	uint256 y
) internal pure returns (uint160 z)
```

`uint256`を`uint160`にキャストする関数。
オーバーフローが起きると`revert`します。

**パラメータ**
| 名前  | 型       | 説明                            |
|-------|----------|---------------------------------|
| `y`   | uint256  | ダウンキャストされる`uint256`値。  |

**戻り値**
| 名前  | 型       | 説明                            |
|-------|----------|---------------------------------|
| `z`   | uint160  | ダウンキャスト後の整数、型は`uint160`になります。  |

#### toInt128

```solidity
function toInt128(
	int256 y
) internal pure returns (int128 z)
```

`int256`を`int128`にキャストする関数。
オーバーフローまたはアンダーフロー時には`revert`します。

**パラメータ**
| 名前  | 型       | 説明                            |
|-------|----------|---------------------------------|
| `y`   | int256   | ダウンキャストされる`int256`値。   |

**戻り値**
| 名前  | 型       | 説明                            |
|-------|----------|---------------------------------|
| `z`   | int128   | ダウンキャスト後の整数、型は`int128`になります。  |

#### toInt256

```solidity
function toInt256(
	uint256 y
) internal pure returns (int256 z)
```

`uint256`を`int256`にキャストする関数。
オーバーフロー時に`revert`します。

**パラメータ**
| 名前  | 型       | 説明                            |
|-------|----------|---------------------------------|
| `y`   | uint256  | キャストされる`uint256`値。        |

**戻り値**
| 名前  | 型       | 説明                            |
|-------|----------|---------------------------------|
| `z`   | int256   | キャスト後の整数、型は`int256`になります。  |

### SecondsOutside

特定のマッピングに関連する方法について説明しています。
このマッピングは、`tick`（価格の区間を表す整数）から`32`ビットのタイムスタンプ値へのマッピングを保持しており、特に`tick`外での取引時間を追跡するために使用されます。

このマッピングでは、キーとして`int24`（24ビットの整数）を使用されていて、1つのワードには8つ（`2^3`）の値が収められています。
このマッピングは、特定の`tick`値から、その`tick`外での取引時間を記録するのに役立ちます。

重要なポイントとして、「`tick`外での取引時間」は常に相対的な測定であり、下限`tick`と上限`tick`の合計流動性が`0`より大きい期間に限り一貫して有効です。
流動性が`0`になると、この測定は無効になる可能性があることに注意する。

:::message
**`tick`外での取引時間**
特定の価格範囲を表す整数である「`tick`」の範囲外で取引した時間のことを指します。
この時間は通常、あるプロトコルやシステム内で特定の価格範囲に対するトランザクションや操作が行われた際に記録されます。

例えば、あるトレーディングプラットフォームでは、特定の価格範囲内で取引が行われており、ユーザーがその価格範囲外で取引を行うことは制限されています。
したがって、ユーザーがこの制限を破り、価格範囲外で取引を行った場合、その取引が行われた時間や期間が「**`tick`外での取引時間**」として記録されます。

この情報は、トレーディングの遵守規則を監視し、違反があった場合に制裁を課すために使用されることがあります。
また、市場の流動性や価格の変動と関連付けて、特定の価格範囲での取引活動を分析する際にも役立つ情報です。
:::

:::message
あるトレーディングプラットフォームで、特定の価格範囲を「`tick`」と呼び、それに関連する「**取引時間**」を記録する必要があります。
この「**取引時間**」は、特定の価格範囲外で取引が行われた時間を表します。

例えば、以下のような状況を考えてみます。

- プラットフォームでは価格が`-100`から`100`までの範囲を「`tick`」として扱います（これが「`tick`」の範囲です）。
- ユーザーAが特定の時間帯で、`-50`から`0`までの価格範囲で取引を行いました。
- ユーザーBが同じ時間帯で、`0`から`50`までの価格範囲で取引を行いました。

この場合、ユーザーAとユーザーBの「**取引範囲外の値**」は、それぞれの取引が価格範囲外で過ごした時間を表します。
例えば、ユーザーAの「**取引範囲内の値**」は、`-100`から`-50`までの範囲および`0`から`100`までの範囲で取引が行われた秒数を合計したものになります。
同様に、ユーザーBの「**取引範囲外の値**」は、`-100`から`0`までの範囲および`50`から`100`までの範囲で取引が行われた秒数を合計したものになります。
:::

:::message
流動性が0の場合、価格範囲での取引や操作が行われていないため、「**取引範囲外の値**」は無効になります。
:::

#### initialize

```solidity
function initialize(
	mapping(int24 => uint256) self,
	int24 tick,
	int24 tickCurrent,
	int24 tickSpacing,
	uint32 time
) internal
```

`tick`が初めて使用され、`tick`外での取引時間を設定する関数。
`tick`が初期化されていないと仮定します。

**パラメータ**
| 名前             | 型                      | 説明                                                    |
|------------------|-------------------------|---------------------------------------------------------|
| `self`           | mapping(int24 => uint256) | `tick`から`tick`外取引時間
の値へのマッピング。                 |
| `tick`           | int24                   | 初期化されるべき`tick`。                                |
| `tickCurrent`    | int24                   | 現在の`tick`。                                       |
| `tickSpacing`    | int24                   | 利用可能な`tick`間の間隔。                          |
| `time`           | uint32                  | 現在のタイムスタンプ。                                  |

#### clear

```solidity
function clear(
	mapping(int24 => uint256) self,
	int24 tick,
	int24 tickSpacing
) internal
```

`tick`が使用されなくなったときに呼び出され、`tick`外で取引時間値をクリアする関数。

**パラメータ**
| 名前             | 型                      | 説明                                                    |
|------------------|-------------------------|---------------------------------------------------------|
| `self`           | mapping(int24 => uint256) | `tick`外での取引時間へのマッピング。                 |
| `tick`           | int24                   | クリアするべき`tick`。                                    |
| `tickSpacing`    | int24                   | 利用可能な`tick`間の間隔。                          |


#### cross

```solidity
function cross(
	mapping(int24 => uint256) self,
	int24 tick,
	int24 tickSpacing,
	uint32 time
) internal
```

初期化された`tick`がクロスされたときに呼び出され、その`tick`外での取引時間を更新する関数。
初期化された`tick`がクロスされるたびに呼び出す必要があります。


:::message
**クロス**
「`tick`」（価格範囲を表す要素）がある境界を越えたときに呼び出される操作を指しています。
具体的には、価格範囲の「`tick`」が初期化され、その範囲をクロスした場合に「取引範囲外の値」を更新する操作です。
:::

**パラメータ**
| 名前             | 型                      | 説明                                                    |
|------------------|-------------------------|---------------------------------------------------------|
| `self`           | mapping(int24 => uint256) | `tick`から`tick`外での取引時間へのマッピング。                 |
| `tick`           | int24                   | クロスされるべき`tick`。                                |
| `tickSpacing`    | int24                   | 利用可能な`tick`間の間隔。                          |
| `time`           | uint32                  | 現在のブロックのタイムスタンプを32ビットに切り詰めたもの。 |

#### get

```solidity
function get(
	mapping(int24 => uint256) self,
	int24 tick,
	int24 tickSpacing
) internal view returns (uint32)
```

初期化された`tick`外の取引時間を取得する関数。
初期化された`tick`のみ取得できます。

**パラメータ**
| 名前             | 型                      | 説明                                                    |
|------------------|-------------------------|---------------------------------------------------------|
| `self`           | mapping(int24 => uint256) | `tick`から`tick`外での取引時間の値へのマッピング。                 |
| `tick`           | int24                   | 取引時間の値を取得したい`tick`。                          |
| `tickSpacing`    | int24                   | 利用可能なタイック間の間隔。                          |

**戻り値**
| 型               | 説明                                                    |
|------------------|---------------------------------------------------------|
| uint32           | 指定した`tick`外の取引時間。                  |

#### secondsInside

```solidity
function secondsInside(
	mapping(int24 => uint256) self,
	int24 tickLower,
	int24 tickUpper,
	int24 tickCurrent,
	int24 tickSpacing
) internal view returns (uint32)
```

`tickLower`と`tickUpper`の両方が初期化されていると仮定して、`tick`範囲内の取引時間を取得する関数。

**パラメータ**
| 名前             | 型                      | 説明                                                     |
|------------------|-------------------------|----------------------------------------------------------|
| `self`           | mapping(int24 => uint256) | `tick`から`tick`外での取引時間値へのマッピング。                  |
| `tickLower`      | int24                   | 取得したい下限tick。                     |
| `tickUpper`      | int24                   | 取得したい上限tick。                     |
| `tickCurrent`    | int24                   | 現在の`tick`。                                          |
| `tickSpacing`    | int24                   | 利用可能な`tick`間の間隔。                           |

**戻り値**
| 名前             | 型                      | 説明                                                     |
|------------------|-------------------------|----------------------------------------------------------|
| `a`              | uint32                  | スナップショットを取り、後のスナップショットと比較するための相対的な`tick`内での取引時間の値。|

### SqrtPriceMath

価格の平方根を**Q64.96**として使用し、流動性を用いてデルタを計算します。

#### getNextSqrtPriceFromAmount0RoundingUp

```solidity
function getNextSqrtPriceFromAmount0RoundingUp(
	uint160 sqrtPX96,
	uint128 liquidity,
	uint256 amount,
	bool add
) internal pure returns (uint160)
```

特定の条件下で「`token0`」の変化量に基づいて次の平方根価格を取得する方関数。
- **常に切り上げ**
	- この計算では、常に値を切り上げることが行われます。
	- なぜなら、2つのケース、つまり価格が上昇する場合（正確な出力の場合）と価格が下降する場合（正確な入力の場合）の両方で、適切な操作を実行するために常に切り上げが必要だからです。
- **具体的な計算方法**
	- 平方根価格を計算するための最も正確な数式は以下です。
	- ただし、オーバーフローの問題がある場合は、別の方法で計算します。
	- 正確な計算
		- `liquidity * sqrtPX96 / (liquidity +- amount * sqrtPX96)`
	- オーバーフローの場合
		- `liquidity / (liquidity / sqrtPX96 +- amount)`

:::message
1. **価格が上昇する場合（正確な出力の場合）**
    - 価格が上昇する場合、正確な出力を得るためには、価格を少なくとも一つ上の価格に移動させる必要があります。
    - この場合、切り上げが行われています。

2. **価格が下降する場合（正確な入力の場合）**
    - 価格が下降する場合、正確な入力を行うためには、価格を一つ下の価格に移動させるだけで十分です。
    - この場合も、切り上げが行われています。
:::

**パラメータ**
| 名前             | 型                      | 説明                                                     |
|------------------|-------------------------|----------------------------------------------------------|
| `sqrtPX96`       | uint160                 | 開始価格、つまり「`token0`」の変化を考慮する前の価格。 |
| `liquidity`      | uint128                 | 利用可能な流動性の量。                                 |
| `amount`         | uint256                 | 仮想リザーブから追加または削除する「token0」の量。     |
| `add`            | bool                    | 「`amount`」を追加するか削除するかを示すブール値。      |

**戻り値**
| 型               | 説明                                                    |
|------------------|---------------------------------------------------------|
| uint160          | 「`amount`」を追加または削除した後の価格。              |


#### getNextSqrtPriceFromAmount1RoundingDown

特定の条件下で「`token1`」の変化量に基づいて次の平方根価格を取得する方関数。

- **常に切り捨て**
	- この計算では、常に値を切り捨てることが行われます。
	- なぜなら、正確な出力の場合（価格が下降する場合）では、望む出力量を得るために少なくとも価格を指定距離移動する必要があるためです。
	- 正確な入力の場合（価格が上昇する場合）では、過剰な出力を送信しないために価格を少なく移動する必要があるためです。
- **計算式の正確性**
	- この計算の公式は、損失のないバージョンからわずかに（`1 wei`未満で）外れる可能性があるが、非常に正確な計算であることが強調されています。
	- 計算式は以下の通りです。
		- `sqrtPX96 +- amount / liquidity`。

**パラメータ**
| 名前             | 型                      | 説明                                                     |
|------------------|-------------------------|----------------------------------------------------------|
| `sqrtPX96`       | uint160                 | 開始価格、つまり「`token1`」の変化を考慮する前の価格。 |
| `liquidity`      | uint128                 | 利用可能な流動性の量。                                 |
| `amount`         | uint256                 | 仮想リザーブから追加または削除する「token1」の量。     |
| `add`            | bool                    | 「`amount`」を追加または削除するかを示すブール値。      |

**戻り値**
| 型               | 説明                                                    |
|------------------|---------------------------------------------------------|
| uint160          | 「`amount`」を追加または削除した後の価格。              |

#### getNextSqrtPriceFromInput

```solidity
function getNextSqrtPriceFromInput(
	uint160 sqrtPX96,
	uint128 liquidity,
	uint256 amountIn,
	bool zeroForOne
) internal pure returns (uint160 sqrtQX96)
```

`token0`または`token1`の入力量を指定して、次の`sqrt`価格を取得する関数。

価格または流動性が`0`であるか、次の価格が許容範囲外である場合にエラーを投げます。

**パラメータ**
| 名前             | 型                      | 説明                                                     |
|------------------|-------------------------|----------------------------------------------------------|
| `sqrtPX96`       | uint160                 | 開始価格、つまり入力量を考慮する前の価格。           |
| `liquidity`      | uint128                 | 利用可能な流動性の量。                                 |
| `amountIn`       | uint256                 | トークン0またはトークン1の入力量。                     |
| `zeroForOne`     | bool                    | 入力量がトークン0かトークン1かを示すブール値。         |

**戻り値**
| 名前             | 型                      | 説明                                                    |
|------------------|-------------------------|---------------------------------------------------------|
| `sqrtQX96`       | uint160                 | 入力量をトークン0またはトークン1に追加した後の価格。 |

#### getNextSqrtPriceFromOutput

```solidity
function getNextSqrtPriceFromOutput(
	uint160 sqrtPX96,
	uint128 liquidity,
	uint256 amountOut,
	bool zeroForOne
) internal pure returns (uint160 sqrtQX96)
```

`token0`または`token1`の出力量を指定して、次の`sqrt`価格を取得する関数。

価格または流動性が`0`であるか、次の価格が許容範囲外である場合にエラーを投げます。


**パラメータ**
| 名前             | 型                      | 説明                                                     |
|------------------|-------------------------|----------------------------------------------------------|
| `sqrtPX96`       | uint160                 | 開始価格、つまり出力量を考慮する前の価格。           |
| `liquidity`      | uint128                 | 利用可能な流動性の量。                                 |
| `amountOut`      | uint256                 | トークン0またはトークン1の出力量。                     |
| `zeroForOne`     | bool                    | 出力量がトークン0かトークン1かを示すブール値。         |

**戻り値**
| 名前             | 型                      | 説明                                                    |
|------------------|-------------------------|---------------------------------------------------------|
| `sqrtQX96`       | uint160                 | 出力量をトークン0またはトークン1から削除した後の価格。 |

#### getAmount0Delta

```solidity
function getAmount0Delta(
	uint160 sqrtRatioAX96,
	uint160 sqrtRatioBX96,
	uint128 liquidity,
	bool roundUp
) internal pure returns (uint256 amount0)
```

2つの価格間の金額0デルタを取得する関数。

```
liquidity / sqrt(lower) - liquidity / sqrt(upper), i.e. liquidity * (sqrt(upper) - sqrt(lower)) / (sqrt(upper) * sqrt(lower))
```

上記を計算します。

**パラメータ**
| 名前             | 型                      | 説明                                                     |
|------------------|-------------------------|----------------------------------------------------------|
| `sqrtRatioAX96`  | uint160                 | 1つ目の平方根価格。                                      |
| `sqrtRatioBX96`  | uint160                 | 2つ目の平方根価格。                                      |
| `liquidity`      | uint128                 | 利用可能な流動性の量。                                 |
| `roundUp`        | bool                    | 量を切り上げるか切り捨てるかを示すブール値。           |

**戻り値**
| 名前             | 型                      | 説明                                                    |
|------------------|-------------------------|---------------------------------------------------------|
| `amount0`        | uint256                 | 2つの平方根価格の間で指定された流動性サイズをカバーするのに必要なトークン0の量。 |

#### getAmount1Delta

```solidity
function getAmount1Delta(
	uint160 sqrtRatioAX96,
	uint160 sqrtRatioBX96,
	uint128 liquidity,
	bool roundUp
) internal pure returns (uint256 amount1)
```

2つの価格間の金額1デルタを取得する関数。

`liquidity * (sqrt(upper) - sqrt(lower))`計算します。

**パラメータ**
| 名前             | 型                      | 説明                                                     |
|------------------|-------------------------|----------------------------------------------------------|
| `sqrtRatioAX96`  | uint160                 | 1つ目の平方根価格。                                      |
| `sqrtRatioBX96`  | uint160                 | 2つ目の平方根価格。                                      |
| `liquidity`      | uint128                 | 利用可能な流動性の量。                                 |
| `roundUp`        | bool                    | 量を切り上げるか切り捨てるかを示すブール値。           |

**戻り値**
| 名前             | 型                      | 説明                                                    |
|------------------|-------------------------|---------------------------------------------------------|
| `amount1`        | uint256                 | 2つの平方根価格の間で指定された流動性サイズをカバーするのに必要なトークン1の量。 |


#### getAmount0Delta

```solidity
function getAmount0Delta(
	uint160 sqrtRatioAX96,
	uint160 sqrtRatioBX96,
	int128 liquidity
) internal pure returns (int256 amount0)
```

署名された`token0`のデルタを取得するヘルパー関数。

**パラメータ**
| 名前             | 型                      | 説明                                                     |
|------------------|-------------------------|----------------------------------------------------------|
| `sqrtRatioAX96`  | uint160                 | 1つ目の平方根価格。                                      |
| `sqrtRatioBX96`  | uint160                 | 2つ目の平方根価格。                                      |
| `liquidity`      | int128                  | 計算するための流動性の変化。                           |

**戻り値**
| 名前             | 型                      | 説明                                                    |
|------------------|-------------------------|---------------------------------------------------------|
| `amount0`        | int256                  | 指定された2つの平方根価格間の「liquidityDelta」に対応するトークン0の量。 |

#### getAmount1Delta

```solidity
function getAmount1Delta(
	uint160 sqrtRatioAX96,
	uint160 sqrtRatioBX96,
	int128 liquidity
) internal pure returns (int256 amount1)
```
署名された`token1`のデルタを取得するヘルパー関数。

**パラメータ**
| 名前             | 型                      | 説明                                                     |
|------------------|-------------------------|----------------------------------------------------------|
| `sqrtRatioAX96`  | uint160                 | 1つ目の平方根価格。                                      |
| `sqrtRatioBX96`  | uint160                 | 2つ目の平方根価格。                                      |
| `liquidity`      | int128                  | 計算するための流動性の変化。                           |

**戻り値**
| 名前             | 型                      | 説明                                                    |
|------------------|-------------------------|---------------------------------------------------------|
| `amount0`        | int256                  | 指定された2つの平方根価格間の「liquidityDelta」に対応するトークン0の量。 |

### SwapMath

1`tick`の価格範囲、すなわち1`tick`内でのスワップ結果を計算します。

#### computeSwapStep

```solidity
function computeSwapStep(
	uint160 sqrtRatioCurrentX96,
	uint160 sqrtRatioTargetX96,
	uint128 liquidity,
	int256 amountRemaining,
	uint24 feePips
) internal pure returns (uint160 sqrtRatioNextX96, uint256 amountIn, uint256 amountOut, uint256 feeAmount)
```

特定のパラメータに基づいて、スワップ操作における一定のトークン量を入れ替えた結果を計算する関数。

- スワップ操作のパラメータに基づいて、一定のトークン量を入れ替える結果を計算します。
- 手数料と入力量の合計は、スワップの`amountSpecified`（指定された金額）が正の値である場合、残りの量を超えないことが保証されています。
	- スワップ操作が予定通りに行われ、不正確な取引が防がれるためのセキュリティメカニズムです。

以下は、指定された条件に従って整形されたパラメータと戻り値の表です。

**パラメータ**
| 名前                     | 型                      | 説明                                                     |
|--------------------------|-------------------------|----------------------------------------------------------|
| `sqrtRatioCurrentX96`    | uint160                 | プールの現在の平方根価格。                                 |
| `sqrtRatioTargetX96`     | uint160                 | 超えてはならない価格。スワップの方向を示すために使用されます。 |
| `liquidity`              | uint128                 | 利用可能な流動性。                                       |
| `amountRemaining`        | int256                  | 交換する残りの入力または出力量。                          |
| `feePips`                | uint24                  | 入力量から取られる手数料（百分率）。                        |

**戻り値**
| 名前                   | 型                      | 説明                                                         |
|------------------------|-------------------------|--------------------------------------------------------------|
| `sqrtRatioNextX96`     | uint160                 | 入力または出力量をスワップした後の価格。価格ターゲットを超えないように設定されます。 |
| `amountIn`             | uint256                 | スワップインする量（トークン0またはトークン1）を示す値。スワップの方向に基づいて計算されます。 |
| `amountOut`            | uint256                 | 受け取る量（トークン0またはトークン1）を示す値。スワップの方向に基づいて計算されます。 |
| `feeAmount`            | uint256                 | 手数料として取られる入力量。                                 |

### Tick

#### tickSpacingToMaxLiquidityPerTick

```solidity
function tickSpacingToMaxLiquidityPerTick(
	int24 tickSpacing
) internal pure returns (uint128)
```

与えられた`tickSpacing`から`tick`ごとの最大流動性を導き出す関数。

**パラメータ**
| 名前             | 型          | 説明                                                  |
|------------------|-------------|-------------------------------------------------------|
| `tickSpacing`    | int24       | 必要なティックの間隔。ティック間隔の倍数で実現されます。例: `tickSpacing`が`3`の場合、`tick`は`3tick`ごとに初期化される必要があります。`-6、-3、0、3、6、...`と続きます。 |

**戻り値**
| 型        | 説明                                      |
|-----------|-------------------------------------------|
| uint128   | 各ティックごとの最大流動性。                   |


#### getFeeGrowthInside

```solidity
function getFeeGrowthInside(
	mapping(int24 => struct Tick.Info) self,
	int24 tickLower,
	int24 tickUpper,
	int24 tickCurrent,
	uint256 feeGrowthGlobal0X128,
	uint256 feeGrowthGlobal1X128
) internal view returns (uint256 feeGrowthInside0X128, uint256 feeGrowthInside1X128)
```

増加した手数料データを取得する関数。

**パラメータ**
| 名前                      | 型                         | 説明                                               |
|---------------------------|----------------------------|----------------------------------------------------|
| `self`                    | mapping(int24 => struct Tick.Info) | 初期化された`tick`情報を含むマッピング。               |
| `tickLower`               | int24                      | ポジションの下限`tick`境界。                          |
| `tickUpper`               | int24                      | ポジションの上限`tick`境界。                          |
| `tickCurrent`             | int24                      | 現在の`tick`。                                     |
| `feeGrowthGlobal0X128`    | uint256                    | トークン0の全体の手数料成長率、単位流動性あたり。             |
| `feeGrowthGlobal1X128`    | uint256                    | トークン1の全体の手数料成長率、単位流動性あたり。             |

**戻り値**
| 名前                          | 型                         | 説明                                                    |
|-------------------------------|----------------------------|---------------------------------------------------------|
| `feeGrowthInside0X128`        | uint256                    | ポジションの`tick`境界内での、単位流動性あたりのトークン0の累積手数料成長率。 |
| `feeGrowthInside1X128`        | uint256                    | ポジションの`tick`境界内での、単位流動性あたりのトークン1の累積手数料成長率。 |

#### update

```solidity
function update(
	mapping(int24 => struct Tick.Info) self,
	int24 tick,
	int24 tickCurrent,
	int128 liquidityDelta,
	uint256 feeGrowthGlobal0X128,
	uint256 feeGrowthGlobal1X128,
	bool upper,
	uint128 maxLiquidity
) internal returns (bool flipped)
```

`tick`を更新し、`tick`が初期化から非初期化、またはその逆に反転した場合に`ture`を返す関数。

**パラメータ**
| 名前                      | 型                         | 説明                                                 |
|---------------------------|----------------------------|------------------------------------------------------|
| `self`                    | mapping(int24 => struct Tick.Info) | 初期化された`tick`情報を含むマッピング。                   |
| `tick`                    | int24                      | 更新される`tick`。                                   |
| `tickCurrent`             | int24                      | 現在の`tick`。                                     |
| `liquidityDelta`          | int128                     | `tick`が左から右にまたは右から左にクロスされたときに追加（または減少）される新しい流動性の量。 |
| `feeGrowthGlobal0X128`    | uint256                    | トークン0の全体の手数料成長率、単位流動性あたり。               |
| `feeGrowthGlobal1X128`    | uint256                    | トークン1の全体の手数料成長率、単位流動性あたり。               |
| `upper`                   | bool                       | ポジションの上限`tick`を更新する場合は true、下限`tick`を更新する場合は false。          |
| `maxLiquidity`            | uint128                    | 単一`tick`の最大流動性割り当て。                         |

**戻り値**
| 名前       | 型    | 説明                                                                                      |
|------------|-------|-------------------------------------------------------------------------------------------|
| `flipped`  | bool  | `tick`が初期化済みから初期化されていない状態に切り替わったか、またはその逆になった場合は true。 |


#### clear

```solidity
function clear(
	mapping(int24 => struct Tick.Info) self,
	int24 tick
) internal
```

`tick`データを初期化する。

**パラメータ**
| 名前                      | 型                         | 説明                                                 |
|---------------------------|----------------------------|------------------------------------------------------|
| `self`                    | mapping(int24 => struct Tick.Info) | 初期化された`tick`情報を含むマッピング。                   |
| `tick`                    | int24                      | クリアされる`tick`。                                 |

#### cross

```solidity
function cross(
	mapping(int24 => struct Tick.Info) self,
	int24 tick,
	uint256 feeGrowthGlobal0X128,
	uint256 feeGrowthGlobal1X128
) internal returns (int128 liquidityNet)
```

価格の動きに応じて次の`tick`に移行する関数。

**パラメータ**
| 名前                      | 型                         | 説明                                                 |
|---------------------------|----------------------------|------------------------------------------------------|
| `self`                    | mapping(int24 => struct Tick.Info) | 初期化された`tick`情報を含むマッピング。                   |
| `tick`                    | int24                      | 遷移の対象となる`tick`。                               |
| `feeGrowthGlobal0X128`    | uint256                    | トークン0の全体の手数料成長率、単位流動性あたり。               |
| `feeGrowthGlobal1X128`    | uint256                    | トークン1の全体の手数料成長率、単位流動性あたり。               |

**戻り値**
| 名前           | 型     | 説明                                                               |
|----------------|--------|--------------------------------------------------------------------|
| `liquidityNet` | int128 | `tick`が左から右にまたは右から左にクロスされたときに追加（または減少）される流動性の量。 |


### TickBitmap

`tick`のインデックスとその初期化状態のパックされたマッピングを格納します。

`tick`は`int24`で表現され、1ワードあたり`256(2^8)`個の値があるため、マッピングではキーに`int16`を使用する。

#### flipTick

```solidity
function flipTick(
	mapping(int16 => uint256) self,
	int24 tick,
	int24 tickSpacing
) internal
```

指定された`tick`の初期化された状態を`false`から`true`、またはその逆にする関数。

**パラメータ**
| 名前            | 型                  | 説明                                                             |
|-----------------|---------------------|------------------------------------------------------------------|
| `self`          | mapping(int16 => uint256) | `tick`を反転させるマッピング。                                       |
| `tick`          | int24               | 反転する`tick`。                                                 |
| `tickSpacing`   | int24               | 使用可能な`tick`間の間隔。                                           |


#### nextInitializedTickWithinOneWord

```solidity
function nextInitializedTickWithinOneWord(
	mapping(int16 => uint256) self,
	int24 tick,
	int24 tickSpacing,
	bool lte
) internal view returns (int24 next, bool initialized)
```

指定された`tick`の左（以下）または右（以上）にある`tick`と同じワード（または隣接するワード）に含まれる次の初期化された`tick`を返す関数。

**パラメータ**
| 名前            | 型                  | 説明                                                             |
|-----------------|---------------------|------------------------------------------------------------------|
| `self`          | mapping(int16 => uint256) | 次に初期化される`tick`を計算するためのマッピング。                |
| `tick`          | int24               | 開始`tick`。                                                     |
| `tickSpacing`   | int24               | 使用可能な`tick`間の間隔。                                           |
| `lte`           | bool                | 開始`tick`よりも小さいか等しい次の初期化されたtickを検索するかどうか。         |

**戻り値**
| 名前            | 型       | 説明                                                                   |
|-----------------|----------|------------------------------------------------------------------------|
| `next`          | int24    | 現在の`tick`から最大256 `tick`先までの次の初期化または未初期化のtick。         |
| `initialized`   | bool     | 関数は最大256 `tick`内でのみ検索するため、次の`tick`が初期化されているかどうか。 |

#### TickMath

サイズ1.0001の`tick`、すなわち`sqrt(1.0001^tick)`を固定小数点**Q64.96**数として`sqrt`価格を計算します。
`2-128`から`2128`までの価格をサポート。

#### getSqrtRatioAtTick

```solidity
function getSqrtRatioAtTick(
	int24 tick
) internal pure returns (uint160 sqrtPriceX96)
```
`sqrt(1.0001^tick) * 2^96`を計算する関数。

もし`tick` > 最大`tick`ならエラーを投げます。

#### getTickAtSqrtRatio

```solidity
function getTickAtSqrtRatio(
	uint160 sqrtPriceX96
) internal pure returns (int24 tick)
```

`getRatioAtTick(tick) <= ratio`となる最大の`tick`値を計算する関数。

`sqrtPriceX96 < MIN_SQRT_RATIO`の場合にエラーを投げます。
`MIN_SQRT_RATIO`は、`getRatioAtTick`が返す可能性のある最低値です。

以下は、指定された条件に従って整形されたパラメータと戻り値の表です。

**パラメータ**
| 名前            | 型      | 説明                                               |
|-----------------|---------|----------------------------------------------------|
| `tick`          | int24   | 上記の数式に使用する入力`tick`。                             |

**戻り値**
| 名前             | 型        | 説明                                                         |
|------------------|-----------|--------------------------------------------------------------|
| `sqrtPriceX96`   | uint160   | 2つのアセットの比率（`token1/token0`）の平方根を表す固定小数点の**Q64.96**数。 |

### TransferHelper

以下を参考にしてください。

https://zenn.dev/cryptogames/articles/197e0f1ed053ac#transferhelper

### UnsafeMath

一般的な数学関数を実行するしますが、オーバーフローやアンダーフローのチェックは行いません。

#### divRoundingUp

```solidity
function divRoundingUp(
	uint256 x,
	uint256 y
) internal pure returns (uint256 z)
```

`ceil(x / y)`を返す関数。

`y`が`0`の時エラーを投げます。

**パラメータ**
| 名前 | 型      | 説明                   |
|------|---------|------------------------|
| `x`  | uint256 | 割られる数（被除数）。 |
| `y`  | uint256 | 割る数（除数）。       |

**戻り値**
| 名前 | 型      | 説明                                           |
|------|---------|------------------------------------------------|
| `z`  | uint256 | 商。`ceil(x / y)`のように、切り上げで計算されます。 |


# Governance

**Uniswap**プロトコルでの運営とアップデートは**UNI**トークンを持つユーザー
によって行われています。
このプロトコルの運営には、**UNI**トークン、ガバナンスモジュール、および**Timelock**という3つの要素が重要です。

- **UNIトークン**
	- **UNI**トークンは**Uniswap**のネットワークで使われるトークンで、プロトコルのガバナンスデーキーとなる役割を果たしています。
	- **UNI**トークンを持っている人々がプロトコルに変更を提案し、投票する権利を持っています。
- **ガバナンスモジュール**
	- **Uniswap**のガバナンスを管理するためのソフトウェア。
	- **UNI**トークンを一定数量（**2.5百万UNI**、総供給の0.25％以上）持つアカウントは、このモジュールを使用してプロトコルの変更提案を行うことができます。
	- 提案は実行可能なコードを含むものです。
- **Timelock**
	- **Timelock**は、提案が実行される前に待機する期間を管理する機能です。
	- 提案が投票で承認された場合、**Timelock**は最低でも2日間の待機期間を設け、その後に提案を実行します。
	- これにより、コミュニティが提案内容をよく考えるための時間が確保されます。

プロセスは以下のように進行します。
1. **UNI**トークンを持つ人が変更提案を作成します。
2. コミュニティ全体が提案について7日間の投票期間を持ち、賛成票が多ければ提案が承認されます。
3. 承認された提案は**Timelock**にキューイングされ、最低2日後に実行されます。

## Timelock

![Timelockの図](https://storage.googleapis.com/zenn-user-upload/d241813f729c-20230911.png)
引用: https://docs.uniswap.org/contracts/v3/reference/governance/overview

**Uniswap**プロトコルでは、システムの設定、ルール、およびプログラムを変更するために、タイムロックという仕組みが使われています。
この仕組みは、「**タイムディレイド（遅延）で選択的に変更**」することを可能にします。

### タイムロックコントラクト
**Uniswap**プロトコル内の重要な変更を管理する特別なスマートコントラクトです。
このコントラクトには、ガバナンスアクション（プロトコルの変更提案）の最小通知期間がハードコードされています。
通常は、提案が行われた瞬間から最低でも2日間の待機期間を設けることが求められます。
これは、コミュニティに変更の内容を知らせ、議論するための時間を確保するためのルールです。

### 遅延期間の変更
ただし、特に重要な変更（例: リスクシステムの変更など）の場合、最大30日間の遅延期間を設定することもできます。
これにより、大規模な変更に対するより長い議論と審査の期間を確保できます。

### ガバナンスモジュールによる制御
タイムロックコントラクトは、**Uniswap**のガバナンスモジュールによって制御されます。
つまり、ガバナンスアクションの提案や遅延期間の設定など、変更についての権限は**Uniswap**のコミュニティにあります。

### 監視と透明性**
タイムロックコントラクトには、保留中および完了したガバナンスアクションに関する情報を提供するダッシュボードがあります。
これにより、コミュニティメンバーは変更の進行状況を監視し、透明性を確保できます。

## 関数・イベント

関数やイベントについては以下の記事を参考にしてください。

https://zenn.dev/cryptogames/articles/ea1fd18d81dc94

# 最後に

今回の記事では、以下の**Technical Reference**の章を翻訳・補足しながらまとめてきました。

https://docs.uniswap.org/contracts/v3/reference/overview

いかがだったでしょうか？

普段はブログやQiitaでブロックチェーンやAIに関する記事を挙げているので、よければ見ていってください！

https://chaldene.net/

https://qiita.com/cardene

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58
