Skip to content

Commit e6481ab

Browse files
authored
Merge pull request #316 from liberhe/dev
add perp amm code analysis
2 parents d470633 + 8228196 commit e6481ab

File tree

9 files changed

+657
-147
lines changed

9 files changed

+657
-147
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535

3636
## 准备工作 - Preparatory Work
3737

38-
**阅读[《精通以太坊》](https://github.com/inoutcode/ethereum_book)理解 **以太坊** 的基本原理和 阅读 [Solidity官方文档](https://docs.soliditylang.org/) 熟悉 **Solidity** 智能合约语言
38+
阅读[《精通以太坊》](https://github.com/inoutcode/ethereum_book)理解 **以太坊** 的基本原理和 阅读 [Solidity官方文档](https://docs.soliditylang.org/) 熟悉 **Solidity** 智能合约语言
3939

4040
- 以太坊原理书: <https://ethbook.abyteahead.com/howto.html>
4141
- 以太坊黄皮书: <https://github.com/ethereum/yellowpaper>
@@ -79,6 +79,7 @@
7979
## 基础任务 - Basic Tasks
8080

8181
通过以下基础任务,了解开发 Dapp 的基本工具和开发知识。完成20个task,可以升级关注项目任务。
82+
DAPP架构请参考文章--[从架构维度看Web2.0与Web3.0应用之别](https://zhuanlan.zhihu.com/p/414635679?utm_source=wechat_session&utm_medium=social&utm_oi=778564687968092160&s_r=0)
8283

8384
01. [use web3.js deploy contract](basic/01-web3js-deploy/README.md)
8485
02. [use web3.js create transaction](basic/02-web3js-transaction/README.md)

basic/05-ethersjs-erc20/.env.example

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
PRIVATE_KEY=xxxxxxxxxxxxxxxx
1+
PRIVATE_KEY=xxxxxxxxxxxxxxxx
2+
INFURA_ID=yyyyyyyy

basic/23-erc865-and-erc875/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
### ERC777 (todo)
1414

1515
### ERC1155 (todo)
16+
17+
### EIP-2929(todo)
18+
https://eips.ethereum.org/EIPS/eip-2929
19+
1620
## 测试步骤
1721
- 安装依赖
1822
```

basic/31-dune-analytics-nansen/readme.md

+8-7
Original file line numberDiff line numberDiff line change
@@ -278,16 +278,17 @@ SELECT DISTINCT(tablename) FROM pg_catalog.pg_tables
278278

279279
## 参考链接
280280

281-
视频:https://www.bilibili.com/video/BV1ZK4y137Ce
281+
- 视频:https://www.bilibili.com/video/BV1ZK4y137Ce
282+
- nansen说明书: https://github.com/rebase-network/Dapp-Learning-Arsenal/blob/main/papers/7-tool/nansen中文说明书.pdf
282283

283-
https://qiita.com/shooter/items/3b66fc6400bc49854ffe
284+
- https://qiita.com/shooter/items/3b66fc6400bc49854ffe
284285

285-
https://learnblockchain.cn/article/1746
286+
- https://learnblockchain.cn/article/1746
286287

287-
https://docs.duneanalytics.com/data-tables/data-tables/raw-data/ethereum-data
288+
- https://docs.duneanalytics.com/data-tables/data-tables/raw-data/ethereum-data
288289

289-
https://duneanalytics.com/browse/queries?user_name=shooter
290+
- https://duneanalytics.com/browse/queries?user_name=shooter
290291

291-
https://app.flipsidecrypto.com/velocity
292+
- https://app.flipsidecrypto.com/velocity
292293

293-
https://glassnode.com/
294+
- https://glassnode.com/

defi/Curve/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
- <https://github.com/curvefi/curve-contract/tree/master/contracts>
33
- <https://curve.fi/files/crypto-pools-paper.pdf>
44
- <https://github.com/curvefi/curve-crypto-contract/tree/master/contracts/matic>
5+
- curve投票 https://tokenbrice.xyz/crv-wars/#sdvecrv-vs-cvxcrv
6+

defi/Perpetual-V1/amm.md

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
2+
## Perpetual V1
3+
4+
## AMM代码解析
5+
6+
`IAMM`合约
7+
8+
// 交易方向:
9+
enum Dir { ADD_TO_AMM, REMOVE_FROM_AMM }
10+
11+
// 开仓时将quoteAsset(usdc)转换成 baseAsset(eth)
12+
```
13+
function swapInput(
14+
Dir _dir,
15+
Decimal.decimal calldata _quoteAssetAmount,
16+
Decimal.decimal calldata _baseAssetAmountLimit
17+
) external returns (Decimal.decimal memory);
18+
```
19+
// 关仓时候将baseAsset(eth)转换成 quoteAsset(usdc)
20+
function swapOutput(
21+
Dir _dir,
22+
Decimal.decimal calldata _baseAssetAmount,
23+
Decimal.decimal calldata _quoteAssetAmountLimit,
24+
bool _skipFluctuationCheck
25+
) external returns (Decimal.decimal memory);
26+
27+
**view 方法**
28+
```
29+
//功能: 获取池子当前的现货价格; reserveA/reserveB
30+
- function getSpotPrice() external view returns (Decimal.decimal memory);
31+
32+
//功能: 获取池子当前的现货价格;
33+
- function getInputTwap(Dir _dir, Decimal.decimal calldata _quoteAssetAmount)
34+
external
35+
view
36+
returns (Decimal.decimal memory);
37+
38+
//根据TWAP价格获取quoteAsset数量
39+
- function getOutputTwap(Dir _dir, Decimal.decimal calldata _baseAssetAmount)
40+
external
41+
view
42+
returns (Decimal.decimal memory);
43+
44+
// 根据池子的储备以及quoteAsset的数量计算出baseAsset数量。 swapInput的实现函数。
45+
- function getInputPriceWithReserves(
46+
Dir _dir,
47+
Decimal.decimal memory _quoteAssetAmount,
48+
Decimal.decimal memory _quoteAssetPoolAmount,
49+
Decimal.decimal memory _baseAssetPoolAmount
50+
) external pure returns (Decimal.decimal memory);
51+
52+
// 根据池子的储备以及baseAsset的数量计算出quoteAsset数量。 swapOutput的实现函数。
53+
- function getOutputPriceWithReserves(
54+
Dir _dir,
55+
Decimal.decimal memory _baseAssetAmount,
56+
Decimal.decimal memory _quoteAssetPoolAmount,
57+
Decimal.decimal memory _baseAssetPoolAmount
58+
) external pure returns (Decimal.decimal memory);
59+
60+
// 计算TWAP价格(方便计算pnl),两种方式:
61+
// RESERVE_ASSET means price comes from quoteAssetReserve/baseAssetReserve , 即时价格
62+
// INPUT_ASSET means getInput/Output price with snapshot's reserve //交易价格
63+
- function calcTwap(TwapPriceCalcParams memory _params, uint256 _interval)
64+
65+
66+
//根据TWAP价格用usdc换取eth,
67+
//计算持仓价值用positionNotional, 以及未实现盈利unrealizedPnl。
68+
//(unrealizedPnlForLongPosition = positionNotional - openNotional)
69+
- function getInputTwap(Dir _dirOfQuote, Decimal.decimal memory _quoteAssetAmount)
70+
71+
//根据TWAP价格用eth换取usdc
72+
- function getOutputTwap(Dir _dirOfBase, Decimal.decimal memory _baseAssetAmount)
73+
public
74+
75+
```
76+
77+
78+
**event:**
79+
```
80+
event SwapInput(Dir dir, uint256 quoteAssetAmount, uint256 baseAssetAmount);
81+
event SwapOutput(Dir dir, uint256 quoteAssetAmount, uint256 baseAssetAmount);
82+
83+
event ReserveSnapshotted(uint256 quoteAssetReserve, uint256 baseAssetReserve, uint256 timestamp);
84+
event LiquidityChanged(uint256 quoteReserve, uint256 baseReserve, int256 cumulativeNotional);
85+
```
86+
87+
88+
89+
### AMM合约其他函数
90+
1. 初始化函数
91+
```
92+
function initialize(
93+
uint256 _quoteAssetReserve,
94+
uint256 _baseAssetReserve,
95+
uint256 _tradeLimitRatio,
96+
uint256 _fundingPeriod,
97+
IPriceFeed _priceFeed,
98+
bytes32 _priceFeedKey,
99+
address _quoteAsset,
100+
uint256 _fluctuationLimitRatio,
101+
uint256 _tollRatio,
102+
uint256 _spreadRatio
103+
)
104+
```
105+
106+
2.cumulativeNotional:
107+
cumulativeNotional即累加的_quoteAssetAmount;
108+
```
109+
cumulativeNotional = cumulativeNotional.addD(_quoteAssetAmount);
110+
```
111+
112+
**settleFunding**
113+
```
114+
function settleFunding() external override onlyOpen onlyCounterParty returns (SignedDecimal.signedDecimal memory) {
115+
require(_blockTimestamp() >= nextFundingTime, "settle funding too early");
116+
117+
// premium = twapMarketPrice - twapIndexPrice
118+
// timeFraction = fundingPeriod(1 hour) / 1 day
119+
// premiumFraction = premium * timeFraction
120+
Decimal.decimal memory underlyingPrice = getUnderlyingTwapPrice(spotPriceTwapInterval);
121+
SignedDecimal.signedDecimal memory premium =
122+
MixedDecimal.fromDecimal(getTwapPrice(spotPriceTwapInterval)).subD(underlyingPrice);
123+
SignedDecimal.signedDecimal memory premiumFraction = premium.mulScalar(fundingPeriod).divScalar(int256(1 days));
124+
125+
// update funding rate = premiumFraction / twapIndexPrice
126+
updateFundingRate(premiumFraction, underlyingPrice);
127+
128+
// in order to prevent multiple funding settlement during very short time after network congestion
129+
uint256 minNextValidFundingTime = _blockTimestamp().add(fundingBufferPeriod);
130+
131+
// floor((nextFundingTime + fundingPeriod) / 3600) * 3600
132+
uint256 nextFundingTimeOnHourStart = nextFundingTime.add(fundingPeriod).div(1 hours).mul(1 hours);
133+
134+
// max(nextFundingTimeOnHourStart, minNextValidFundingTime)
135+
nextFundingTime = nextFundingTimeOnHourStart > minNextValidFundingTime
136+
? nextFundingTimeOnHourStart
137+
: minNextValidFundingTime;
138+
139+
// DEPRECATED only for backward compatibility before we upgrade ClearingHouse
140+
// reset funding related states
141+
baseAssetDeltaThisFundingPeriod = SignedDecimal.zero();
142+
143+
return premiumFraction;
144+
}
145+
```
146+
147+
**查询AMM状态**
148+
```
149+
function getAmmStates(address _amm) external view returns (AmmStates memory) {
150+
Amm amm = Amm(_amm);
151+
(bool getSymbolSuccess, bytes memory quoteAssetSymbolData) =
152+
address(amm.quoteAsset()).staticcall(abi.encodeWithSignature("symbol()"));
153+
(Decimal.decimal memory quoteAssetReserve, Decimal.decimal memory baseAssetReserve) = amm.getReserve();
154+
155+
bytes32 priceFeedKey = amm.priceFeedKey();
156+
return
157+
AmmStates({
158+
quoteAssetReserve: quoteAssetReserve.toUint(),
159+
baseAssetReserve: baseAssetReserve.toUint(),
160+
//每次交易最大比率
161+
tradeLimitRatio: amm.tradeLimitRatio(),
162+
// 资金费率周期
163+
fundingPeriod: amm.fundingPeriod(),
164+
//喂价
165+
priceFeed: address(amm.priceFeed()),
166+
//
167+
priceFeedKey: priceFeedKey,
168+
quoteAssetSymbol: getSymbolSuccess ? abi.decode(quoteAssetSymbolData, (string)) : "",
169+
baseAssetSymbol: bytes32ToString(priceFeedKey)
170+
});
171+
}
172+
173+
```
174+
175+
### 质押
176+
177+
178+
## 参考链接
179+
头等仓:https://mp.weixin.qq.com/s/Oq7g3_AjRP4Of__K9Gp_bw

0 commit comments

Comments
 (0)