> For the complete documentation index, see [llms.txt](https://docs.hann.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hann.finance/ko/mechanics/deep-dives/stableswap.md).

# StableSwap

두 자산 StableSwap 곡선, 동적 수수료, 체결 한도와 디페그 시 LP 가치.

Hann의 StableSwap 풀은 USDHN과 USDT를 보유합니다. 두 자산의 잔액이 균형에 가까우면 증폭 파라미터가 교환의 가격 영향을 줄입니다. 한쪽 자산이 거래로 줄어들수록 가격 영향이 커집니다. 견적은 현재 준비금, 증폭 파라미터, 수수료 설정, 토큰 정밀도를 반영합니다.

## 준비금과 증폭 파라미터

풀은 두 자산의 불변식을 계산하기 전에 토큰 잔액을 소수점 18자리 기준으로 정규화합니다. USDT는 6자리, USDHN은 18자리를 사용하므로 원시 토큰 수량을 그대로 비교할 수 없습니다.

0보다 큰 정규화 준비금을 `x`, `y`, `currentA()`가 반환하는 값을 `A`, 불변식 값을 `D`라고 둡니다. 정수 반올림을 제외하면 Hann의 계산식은 다음을 만족합니다.

$$
2A(x+y)+D=2AD+\frac{D^3}{4xy}
$$

준비금이 같을 때는 `D = x + y`입니다. 스왑은 입력 자산의 준비금을 늘리고 `D`를 유지하는 출력 자산의 준비금을 계산한 뒤 스왑 수수료와 토큰 단위 반올림을 적용합니다.

증폭 파라미터가 높으면 균형점 근처의 곡선이 평평해집니다. 부족한 출력 자산을 채우거나 디페그 이후에도 1:1 교환을 유지하는 기능은 없습니다. 현재 `A`는 설정된 증폭 파라미터 변경 일정에 따라 달라질 수 있습니다.

## 동적 수수료

기본 스왑 수수료는 `swapFee`, 불균형 배수는 `offpegFeeMultiplier`입니다. 수수료의 기준 분모는 `10,000`bps입니다. `4`bps는 `0.04%`이지만, 앱은 이 예시를 고정 수수료로 쓰지 않고 풀의 현재 수수료를 읽습니다.

배수가 `10,000`을 넘으면 계산에 사용하는 준비금이 균형에서 멀어질수록 동적 수수료가 커집니다. 기본 수수료를 `f`, 배수를 `m`, 기준 분모를 `B = 10,000`, 계산에 사용하는 정규화 잔액을 `x`, `y`라고 하면 연속값 계산식은 다음과 같습니다.

$$
f\_{dynamic}=\frac{mf}{B+(m-B)\frac{4xy}{(x+y)^2}}
$$

`x = y`이면 `4xy/(x+y)^2`가 1이므로 수수료는 `f`가 됩니다. 한쪽 잔액이 작아지면 이 값이 감소하고 수수료는 `mf/B`에 가까워집니다. 컨트랙트는 거래의 잔액을 정수 연산으로 평가하며 견적은 이 계산을 포함합니다. `m ≤ B`이거나 기본 수수료가 0이면 기본 수수료를 사용합니다.

관리 수수료는 스왑 수수료에서 배분되는 몫입니다. 나머지 수수료는 풀의 유동성에 쌓입니다. 풀 비율과 다른 예치에는 LP 수량을 계산하기 전에 불균형 수수료가 적용됩니다.

## 입력 수량 고정과 출력 수량 고정

앱의 USDHN/USDT 경로는 풀 하나를 거칩니다. 다음 두 가지 거래 방식을 지원합니다.

| 거래 방식        | 고정하는 수량 | 온체인에서 확인하는 한도                     |
| ------------ | ------- | --------------------------------- |
| exact input  | 사용할 수량  | 실제 출력이 `amountOutMin` 이상이어야 합니다.  |
| exact output | 받을 수량   | 실제 입력이 `amountInMax`를 넘지 않아야 합니다. |

입력 수량을 고정한 거래의 예상 수령량이 `995`개이고 슬리피지 허용치가 `0.5%`, 즉 `50`bps라면 다음과 같이 계산합니다.

$$
minOut\approx995\left(1-\frac{50}{10{,}000}\right)=990.025
$$

출력 수량을 고정한 거래는 예상 입력 수량에 허용치를 더해 최대 사용량을 계산합니다. 두 한도 모두 해당 토큰의 소수점 정밀도로 변환합니다. 수수료는 이미 견적에 포함되어 있고, 슬리피지 설정은 견적과 체결 사이의 변화를 허용합니다.

라우터는 팩토리 등록, 토큰 순서, 허용 토큰 정책을 검사합니다. 이 정책은 라우터의 견적·스왑·예치에 적용됩니다. 풀을 직접 호출하면 풀 자체의 규칙을 따르며, 라우터의 허용목록이 모든 컨트랙트 호출을 제한하지는 않습니다.

## 거래 기한과 실패

거래 기한은 스왑이나 유동성 트랜잭션을 실행할 수 있는 마지막 시각입니다. 기한 초과, 입력·출력 한도 위반, 풀 일시 정지, 유동성 부족, 지원하지 않는 전송 수수료 토큰은 해당 트랜잭션을 실패시킵니다.

견적은 유동성을 예약하지 않습니다. 실행 전에 다른 거래가 풀 잔액을 바꿀 수 있습니다. 거래 기한은 실행 시간을 제한하고, 최소 수령량·최대 사용량은 허용할 체결 결과를 제한합니다.

실패하면 해당 트랜잭션의 풀 변경과 토큰 전송이 되돌아갑니다. 이전 트랜잭션에서 확정된 승인 권한은 유지되며, 실패한 트랜잭션에도 네트워크 가스가 사용됩니다.

## LP 토큰이 나타내는 지분

LP 토큰은 수수료를 정산한 풀 잔액에 대한 지분입니다. 전체 LP 발행량의 `s`만큼을 보유하면 비례 인출 시 각 가용 준비금의 약 `s`만큼을 받습니다. 토큰 단위 반올림과 사용자가 지정한 최소 수령량이 적용됩니다.

앱의 출금은 LP 토큰을 소각하고 USDHN·USDT를 모두 반환합니다. 컨트랙트의 단일 자산 인출은 곡선과 수수료 효과가 적용되는 별도 작업이며, 앱의 비례 인출에서는 자산 하나를 고를 수 없습니다. 풀이 일시 정지되어도 비례 인출은 허용됩니다.

풀의 가상 가격은 LP 토큰당 `D`에서 계산합니다. 불변식 기준의 정규화 가치를 나타내며 외부 시장의 달러 가격을 나타내지 않습니다. 디페그 상황에서 달러 가치를 보장하지 않습니다.

스테이킹한 LP 토큰도 같은 풀 지분을 유지합니다. RewardStaker는 스테이킹 잔액과 누적 보상을 관리하며, 보상을 수령해도 LP가 나타내는 풀 자산은 바뀌지 않습니다.

## 디페그가 풀을 바꾸는 과정

외부 시장에서 USDHN 가격이 USDT보다 낮아지면 거래자는 더 싼 USDHN을 사서 풀에 팔고 USDT를 받을 수 있습니다. USDHN 준비금은 늘고 USDT 준비금은 줄어듭니다. LP는 가격이 하락한 자산을 더 많이 보유하게 됩니다.

USDHN 가격이 USDT보다 높아지면 거래자는 USDT로 풀의 USDHN을 사서 외부 시장에 팔 수 있습니다. USDHN 준비금은 줄고 USDT 준비금은 늘어납니다. LP는 가격이 상승한 자산을 덜 보유하게 됩니다.

### 두 가지 풀 잔액 예시

처음 풀에 USDHN `1,000,000`개와 USDT `1,000,000`개가 있고 둘 다 `$1`로 평가합니다. LP 지분 `10%`는 각 토큰 `100,000`개를 나타내며 가치는 `$200,000`입니다.

아래 계산은 제시된 최종 잔액과 고정된 `10%` 지분을 사용합니다. 이 잔액은 예시의 입력값이며 곡선으로 유도한 거래 예측값은 아닙니다. 수수료와 다른 LP의 예치·출금은 제외합니다.

| 항목                | USDHN이 `$0.90`으로 하락                         | USDHN이 `$1.05`로 상승                          |
| ----------------- | ------------------------------------------- | ------------------------------------------- |
| 최종 풀 잔액           | USDHN `1,800,000`개 + USDT `200,000`개        | USDHN `200,000`개 + USDT `1,800,000`개        |
| 본인의 `10%` 지분      | USDHN `180,000`개 + USDT `20,000`개           | USDHN `20,000`개 + USDT `180,000`개           |
| 지분 가치             | `180,000 × $0.90 + 20,000 × $1 = $182,000`  | `20,000 × $1.05 + 180,000 × $1 = $201,000`  |
| 원래 토큰을 그대로 보유한 가치 | `100,000 × $0.90 + 100,000 × $1 = $190,000` | `100,000 × $1.05 + 100,000 × $1 = $205,000` |
| 단순 보유 대비 차이       | `−$8,000`                                   | `−$4,000`                                   |

차이는 토큰 구성의 변화에서 발생합니다. 최소 인출 수량은 토큰 수량을 제한하며 시장가격을 제한하지 않습니다. 풀 수수료와 스테이킹 보상도 이 자산 노출과 함께 평가해야 합니다.

실제 앱 사용 순서는 [교환·브리지·유동성 공급](/ko/protocol/stableswap-dex.md)에서, 승인과 유동성 결합 작업은 [Zapper](/ko/protocol/zapper.md)에서 설명합니다.


---

# 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://docs.hann.finance/ko/mechanics/deep-dives/stableswap.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.
