btc20271457 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/.idea/Web3-Financial-Engineering-Courses-main.iml +9 -0
  2. package/.idea/git_toolbox_prj.xml +15 -0
  3. package/.idea/modules.xml +8 -0
  4. package/.idea/vcs.xml +6 -0
  5. package/0.web3_financial_infrastructure/dex_protocol/dex.sol +29 -0
  6. package/0.web3_financial_infrastructure/dex_protocol/dexInfra/AMMData.sol +150 -0
  7. package/0.web3_financial_infrastructure/dex_protocol/dexInfra/Algorithm.sol +97 -0
  8. package/0.web3_financial_infrastructure/dex_protocol/dexInfra/Idatastore.sol +120 -0
  9. package/0.web3_financial_infrastructure/dex_protocol/dexInfra/datastorage.sol +383 -0
  10. package/0.web3_financial_infrastructure/dex_protocol/dexInfra/lptoken.sol +33 -0
  11. package/0.web3_financial_infrastructure/dex_protocol/dexInfra/swap.sol +550 -0
  12. package/0.web3_financial_infrastructure/dex_protocol/dex_protocol.md +51 -0
  13. package/0.web3_financial_infrastructure/liquidity_protocol/bank.sol +258 -0
  14. package/0.web3_financial_infrastructure/liquidity_protocol/bank0.sol +29 -0
  15. package/0.web3_financial_infrastructure/liquidity_protocol/bank1.sol +58 -0
  16. package/0.web3_financial_infrastructure/liquidity_protocol/bank2.sol +124 -0
  17. package/0.web3_financial_infrastructure/liquidity_protocol/bank3.sol +210 -0
  18. package/0.web3_financial_infrastructure/liquidity_protocol/liquidity_protocol.md +58 -0
  19. package/0.web3_financial_infrastructure/liquidity_protocol/product.md +33 -0
  20. package/LICENSE +21 -0
  21. package/README.md +113 -0
  22. package/package.json +26 -0
  23. package/tea.yaml +96 -0
  24. package/tranpack.sh +23 -0
@@ -0,0 +1,550 @@
1
+ // SPDX-License-Identifier: MIT
2
+ /*
3
+ to do list
4
+ 1.after swap userreserve slope 交易后的变化率问题
5
+ 2.k线利息的理想积分模型
6
+ 3.清算过程
7
+ */
8
+
9
+ import "./Idatastore.sol";
10
+ import "./lptoken.sol";
11
+ import "./Algorithm.sol";
12
+
13
+ pragma solidity ^0.8.20;
14
+
15
+ //to do list pay liquidity
16
+
17
+ contract swap{
18
+
19
+ IERC20 WETH;
20
+ receive() payable external {}
21
+ Idatastore datastore;
22
+
23
+ modifier reEntrancyMutex() {
24
+ bool _reEntrancyMutex;
25
+
26
+ require(!_reEntrancyMutex,"FUCK");
27
+ _reEntrancyMutex = true;
28
+ _;
29
+ _reEntrancyMutex = false;
30
+
31
+ }
32
+
33
+ constructor(address store){
34
+ datastore = Idatastore(store);
35
+ }
36
+
37
+ //贷款业务
38
+ function isWhiteListPair(address tokenA,address tokenB) public view returns(bool)
39
+ {
40
+ if(datastore.whiteListToken(tokenA) && datastore.whiteListToken(tokenB))
41
+ {
42
+ return true;
43
+ }else {
44
+ return false;
45
+ }
46
+ }
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+ //业务合约
55
+ //添加流动性
56
+
57
+
58
+
59
+
60
+ function addLiquidity(address _token0, address _token1, uint _amount0,uint _amount1) public returns (uint shares) {
61
+
62
+ //lptoken lptoken;//lptoken接口,为了mint 和 burn lptoken
63
+
64
+ require(_amount0 > 0 ,"require _amount0 > 0 && _amount1 >0");
65
+ require(_token0 != _token1, "_token0 == _token1");
66
+ IERC20 token0 = IERC20(_token0);
67
+ IERC20 token1 = IERC20(_token1);
68
+
69
+ //token1.transferFrom(msg.sender, address(this), _amount1);
70
+ address lptokenAddr;
71
+
72
+ /*
73
+ How much dx, dy to add?
74
+ xy = k
75
+ (x + dx)(y + dy) = k'
76
+ No price change, before and after adding liquidity
77
+ x / y = (x + dx) / (y + dy)
78
+ x(y + dy) = y(x + dx)
79
+ x * dy = y * dx
80
+ x / y = dx / dy
81
+ dy = y / x * dx
82
+ */
83
+ //问题:
84
+ /*
85
+ 如果项目方撤出所有流动性后会存在问题
86
+ 1.添加流动性按照比例 0/0 会报错
87
+
88
+ 解决方案:
89
+ 每次添加至少n个token
90
+ 且remove流动性至少保留n给在amm里面
91
+
92
+ */
93
+
94
+
95
+ if (datastore.getLpToken(_token0,_token1) == address(0)) {
96
+ //当lptoken = 0时,创建lptoken
97
+ shares = Algorithm._sqrt(_amount0 * _amount1);
98
+
99
+ createPair(_token0,_token1);
100
+
101
+ lptokenAddr = datastore.getLpToken(_token0,_token1);
102
+ //lptoken = LPToken(lptokenAddr);//获取lptoken地址
103
+ datastore.pairCreator(lptokenAddr,msg.sender);
104
+
105
+ token0.transferFrom(msg.sender, address(this), _amount0);
106
+ token1.transferFrom(msg.sender, address(this), _amount1);
107
+
108
+
109
+ } else {
110
+ lptokenAddr = datastore.getLpToken(_token0,_token1);
111
+ //lptoken = LPToken(lptokenAddr);//获取lptoken地址
112
+ shares = Algorithm._min(
113
+ (_amount0 * lptoken(lptokenAddr).totalSupply()) / datastore.getReserve(lptokenAddr,_token0),
114
+ (_amount1 * lptoken(lptokenAddr).totalSupply()) / datastore.getReserve(lptokenAddr,_token1)
115
+ );
116
+ _amount1 = datastore.getReserve(lptokenAddr,_token1) * _amount0 / datastore.getReserve(lptokenAddr,_token0);
117
+ token0.transferFrom(msg.sender, address(this), _amount0);
118
+ token1.transferFrom(msg.sender, address(this), _amount1);
119
+ /*
120
+ if(_token0 > _token1)
121
+ {
122
+ userlpdata[msg.sender][lptokenAddr].tokenaAmount += _amount0;
123
+ userlpdata[msg.sender][lptokenAddr].tokenbAmount += _amount1;
124
+ }else {
125
+ userlpdata[msg.sender][lptokenAddr].tokenbAmount += _amount0;
126
+ userlpdata[msg.sender][lptokenAddr].tokenaAmount += _amount1;
127
+
128
+ }*/
129
+ //获取lptoken地址
130
+ }
131
+ require(shares > 0, "shares = 0");
132
+ lptoken(lptokenAddr).mint(msg.sender,shares);
133
+
134
+
135
+ update(msg.sender,lptokenAddr,_token0,_token1,_amount0,_amount1);
136
+
137
+
138
+
139
+ //_update(lptokenAddr,_token0, _token1, datastore.reseve(lptokenAddr,_token0) + _amount0, datastore.reseve(lptokenAddr,_token1) + _amount1);
140
+ }
141
+
142
+ function update(address user,address lptokenAddr,address _token0, address _token1, uint _amount0,uint _amount1) internal
143
+ {
144
+
145
+ datastore.reserve(lptokenAddr,_token0,datastore.getReserve(lptokenAddr,_token0)+_amount0);
146
+ datastore.reserve(lptokenAddr,_token1,datastore.getReserve(lptokenAddr,_token1)+_amount1);
147
+
148
+ datastore.userReserve(user,lptokenAddr,_token0,datastore.getUserReserve(user,lptokenAddr,_token0)+_amount0);
149
+ datastore.userReserve(user,lptokenAddr,_token1,datastore.getUserReserve(user,lptokenAddr,_token1)+_amount1);
150
+
151
+ }
152
+
153
+ function update2(address user,address lptokenAddr,address _token0, address _token1, uint _amount0,uint _amount1) internal
154
+ {
155
+
156
+ datastore.reserve(lptokenAddr,_token0,datastore.getReserve(lptokenAddr,_token0)+_amount0);
157
+ datastore.reserve(lptokenAddr,_token1,datastore.getReserve(lptokenAddr,_token1)+_amount1);
158
+
159
+ datastore.userReserve(user,lptokenAddr,_token0,datastore.getReserve(lptokenAddr,_token0)-_amount0);
160
+ datastore.userReserve(user,lptokenAddr,_token1,datastore.getReserve(lptokenAddr,_token1)-_amount1);
161
+
162
+ }
163
+
164
+ function borrowAsset(address asset,uint amount) public
165
+ {
166
+
167
+ bool j;
168
+ for(uint i; i < datastore.getWhiteListTokenList().length;i++)
169
+ {
170
+ if(datastore.getWhiteListTokenList()[i] == asset){
171
+ j = true;
172
+ }
173
+ }
174
+ require(j,"invalid asset");
175
+ uint leftingBorrowAmount;
176
+
177
+ leftingBorrowAmount = datastore.calUserTokenReserve(msg.sender,asset) / 2 - datastore.getUserWhiteListBorrowed(msg.sender,asset);
178
+
179
+ require(leftingBorrowAmount > amount,"amount too big");
180
+ datastore.userWhiteListBorrowed(msg.sender,asset,datastore.getUserBorrowedAmount(msg.sender) + amount);
181
+ datastore.whiteListBorrowed(asset,datastore.getWhiteListBorrowed(asset) + amount);
182
+
183
+ IERC20 token = IERC20(asset);
184
+ token.transfer(msg.sender,amount);
185
+
186
+
187
+
188
+ }
189
+
190
+ function getUserLeftingBorrowAmount(address user, address asset) public view returns(uint)
191
+ {
192
+ uint leftingBorrowAmount = datastore.calUserTokenReserve(user,asset) / 2 - datastore.getUserWhiteListBorrowed(user,asset);
193
+ return leftingBorrowAmount;
194
+ }
195
+
196
+
197
+ function payDebt(address asset,uint amount) public
198
+ {
199
+ require(datastore.getUserWhiteListBorrowed(msg.sender,asset)>0,"you are no in debt");
200
+
201
+ IERC20 token = IERC20(asset);
202
+ token.transferFrom(msg.sender,address(this),amount);
203
+
204
+ datastore.userWhiteListBorrowed(msg.sender,asset,datastore.getUserBorrowedAmount(msg.sender) - amount);
205
+ datastore.whiteListBorrowed(asset,datastore.getWhiteListBorrowed(asset) - amount);
206
+
207
+ }
208
+
209
+
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+
220
+ function removeLiquidity(
221
+ address _token0,
222
+ address _token1,
223
+ uint _shares
224
+ ) public returns (uint amount0, uint amount1) {
225
+
226
+ require(datastore.getUserBorrowedAmount(msg.sender) < 100,"you are in debt");
227
+ //LPToken lptoken;//lptoken接口,为了mint 和 burn lptoken
228
+ IERC20 token0 = IERC20(_token0);
229
+ IERC20 token1 = IERC20(_token1);
230
+ address lptokenAddr = datastore.getLpToken(_token0,_token1);
231
+
232
+ //lptoken = LPToken(lptokenAddr);
233
+ /*
234
+
235
+ if(datastore.pairCreator(lptokenAddr) == msg.sender)
236
+ {
237
+ require(lptoken(lptokenAddr).balanceOf(msg.sender) - _shares > 100 ,"paieCreator should left 100 wei lptoken in pool");
238
+ }
239
+ */
240
+
241
+ amount0 = (_shares * datastore.getReserve(lptokenAddr,_token0)) / lptoken(lptokenAddr).totalSupply();//share * totalsuply/bal0
242
+ amount1 = (_shares * datastore.getReserve(lptokenAddr,_token1)) / lptoken(lptokenAddr).totalSupply();
243
+ require(amount0 > 0 && amount1 > 0, "amount0 or amount1 = 0");
244
+
245
+ lptoken(lptokenAddr).burn(msg.sender, _shares);
246
+ //_update(lptokenAddr,_token0, _token1, datastore.reseve(lptokenAddr,_token0) - amount0, datastore.reseve(lptokenAddr,_token1) - amount1);
247
+
248
+
249
+ token0.transfer(msg.sender, amount0);
250
+ token1.transfer(msg.sender, amount1);
251
+ update(msg.sender,lptokenAddr,_token0,_token1,amount0,amount1);
252
+ //update(msg.sender,lptokenAddr,_token0,_token1, datastore.reseve(lptokenAddr,_token0) - amount0, datastore.reseve(lptokenAddr,_token1) - amount1);
253
+ }
254
+
255
+ //交易
256
+
257
+
258
+
259
+
260
+
261
+
262
+ /*
263
+
264
+ function swapByPath(uint _amountIn, uint _disirSli,address [] memory _path) public {
265
+ uint amountIn = _amountIn;
266
+ for(uint i; i < _path.length - 1; i ++ ){
267
+ (address tokenIn,address tokenOut) = (_path[i],_path[i + 1]);
268
+ amountIn = swapByLimitSli(tokenIn, tokenOut, amountIn, _disirSli);
269
+ }
270
+ }
271
+ */
272
+
273
+ function swap1(address _tokenIn, address _tokenOut, uint _amountIn) public returns(uint amountOut){
274
+ require(
275
+ datastore.getLpToken(_tokenIn,_tokenOut) != address(0),
276
+ "invalid token"
277
+ );
278
+ require(_amountIn > 0, "amount in = 0");
279
+ require(_tokenIn != _tokenOut);
280
+ //require(_amountIn >= 1000, "require amountIn >= 1000 wei token");
281
+
282
+ IERC20 tokenIn = IERC20(_tokenIn);
283
+ IERC20 tokenOut = IERC20(_tokenOut);
284
+ address lptokenAddr = datastore.getLpToken(_tokenIn,_tokenOut);
285
+ uint reserveIn = datastore.getReserve(lptokenAddr,_tokenIn);
286
+ uint reserveOut = datastore.getReserve(lptokenAddr,_tokenOut);
287
+
288
+ tokenIn.transferFrom(msg.sender, address(this), _amountIn);
289
+
290
+
291
+ //交易税收
292
+ uint amountInWithFee = (_amountIn * (100000-datastore.getLpFee()-datastore.getFundFee())) / 100000;
293
+ if(datastore.getFundFee() > 0){
294
+ tokenIn.transfer(datastore.getFundAddr(),datastore.getFundFee() * _amountIn / 100000);
295
+ }
296
+ amountOut = (reserveOut * amountInWithFee) / (reserveIn + amountInWithFee);
297
+
298
+ //检查滑点
299
+ //setSli(amountInWithFee,reserveIn,reserveOut,_disirSli);
300
+
301
+
302
+ tokenOut.transfer(msg.sender, amountOut);
303
+ uint totalReserve0 = datastore.getReserve(lptokenAddr,_tokenIn) + _amountIn;
304
+ uint totalReserve1 = datastore.getReserve(lptokenAddr,_tokenOut) - amountOut;
305
+
306
+ datastore.reserve(lptokenAddr,_tokenIn,totalReserve0);
307
+ datastore.reserve(lptokenAddr,_tokenOut,totalReserve1);
308
+
309
+ //uint profit = lpFee * _amountIn / 100000;
310
+
311
+ //_lpProfit[lptokenAddr] += profit;
312
+
313
+ //_update(lptokenAddr,_tokenIn, _tokenOut, totalReserve0, totalReserve1);
314
+
315
+ }
316
+
317
+ function swap2(address _tokenIn, address _tokenOut, uint _amountIn) public returns(uint amountOut){
318
+ address lptokenAddr = datastore.getLpToken(_tokenIn,_tokenOut);
319
+ require(
320
+ lptokenAddr != address(0),
321
+ "invalid token"
322
+ );
323
+ require(_amountIn > 0, "amount in = 0");
324
+ require(_tokenIn != _tokenOut);
325
+ //require(_amountIn >= 1000, "require amountIn >= 1000 wei token");
326
+
327
+ IERC20 tokenIn = IERC20(_tokenIn);
328
+ IERC20 tokenOut = IERC20(_tokenOut);
329
+
330
+ uint reserveIn = datastore.getReserve(lptokenAddr,_tokenIn);
331
+ uint reserveOut = datastore.getReserve(lptokenAddr,_tokenOut);
332
+
333
+ tokenIn.transferFrom(msg.sender, address(this), _amountIn);
334
+
335
+
336
+ //交易税收
337
+ uint amountInWithFee = (_amountIn * (100000-datastore.getLpFee()-datastore.getFundFee())) / 100000;
338
+ /*if(datastore.getFundFee() > 0){
339
+ tokenIn.transfer(datastore.getFundAddr(),datastore.getFundFee() * _amountIn / 100000);
340
+ }
341
+ */
342
+ amountOut = (reserveOut * amountInWithFee) / (reserveIn + amountInWithFee);
343
+
344
+ //检查滑点
345
+ //setSli(amountInWithFee,reserveIn,reserveOut,_disirSli);
346
+
347
+
348
+ tokenOut.transfer(msg.sender, amountOut);
349
+ uint totalReserve0 = datastore.getReserve(lptokenAddr,_tokenIn) + _amountIn;
350
+ uint totalReserve1 = datastore.getReserve(lptokenAddr,_tokenOut) - amountOut;
351
+
352
+ datastore.reserve(lptokenAddr,_tokenIn,totalReserve0);
353
+ datastore.reserve(lptokenAddr,_tokenOut,totalReserve1);
354
+
355
+ //uint profit = lpFee * _amountIn / 100000;
356
+
357
+ //_lpProfit[lptokenAddr] += profit;
358
+
359
+ //_update(lptokenAddr,_tokenIn, _tokenOut, totalReserve0, totalReserve1);
360
+
361
+ }
362
+ /*
363
+ function swapByLimitSli(address _tokenIn, address _tokenOut, uint _amountIn, uint _disirSli) public returns(uint amountOut){
364
+ require(
365
+ datastore.getLpToken(_tokenIn,_tokenOut) != address(0),
366
+ "invalid token"
367
+ );
368
+ require(_amountIn > 0, "amount in = 0");
369
+ require(_tokenIn != _tokenOut);
370
+ //require(_amountIn >= 1000, "require amountIn >= 1000 wei token");
371
+
372
+ IERC20 tokenIn = IERC20(_tokenIn);
373
+ IERC20 tokenOut = IERC20(_tokenOut);
374
+ address lptokenAddr = datastore.getLpToken(_tokenIn,_tokenOut);
375
+ uint reserveIn = datastore.getReserve(lptokenAddr,_tokenIn);
376
+ uint reserveOut = datastore.getReserve(lptokenAddr,_tokenOut);
377
+
378
+ tokenIn.transferFrom(msg.sender, address(this), _amountIn);
379
+
380
+
381
+ //交易税收
382
+ uint amountInWithFee = (_amountIn * (100000-datastore.getLpFee()-datastore.getFundFee())) / 100000;
383
+ if(datastore.getFundFee() > 0){
384
+ tokenIn.transfer(datastore.getFundAddr(),datastore.getFundFee() * _amountIn / 100000);
385
+ }
386
+ amountOut = (reserveOut * amountInWithFee) / (reserveIn + amountInWithFee);
387
+
388
+ //检查滑点
389
+ setSli(amountInWithFee,reserveIn,reserveOut,_disirSli);
390
+
391
+
392
+ tokenOut.transfer(msg.sender, amountOut);
393
+ uint totalReserve0 = datastore.getReserve(lptokenAddr,_tokenIn) + _amountIn;
394
+ uint totalReserve1 = datastore.getReserve(lptokenAddr,_tokenOut) - amountOut;
395
+
396
+ datastore.reserve(lptokenAddr,_tokenIn,totalReserve0);
397
+ datastore.reserve(lptokenAddr,_tokenOut,totalReserve1);
398
+
399
+ //uint profit = lpFee * _amountIn / 100000;
400
+
401
+ //_lpProfit[lptokenAddr] += profit;
402
+
403
+ //_update(lptokenAddr,_tokenIn, _tokenOut, totalReserve0, totalReserve1);
404
+
405
+ }*/
406
+ /*
407
+ function swapByLimitSli2(address _tokenIn, address _tokenOut, uint _amountIn, uint _disirSli) public returns(uint amountOut){
408
+ require(
409
+ findLpToken[_tokenIn][_tokenOut] != address(0),
410
+ "invalid token"
411
+ );
412
+ require(_amountIn > 0, "amount in = 0");
413
+ require(_tokenIn != _tokenOut);
414
+ //require(_amountIn >= 1000, "require amountIn >= 1000 wei token");
415
+
416
+ IERC20 tokenIn = IERC20(_tokenIn);
417
+ //IERC20 tokenOut = IERC20(_tokenOut);
418
+ address lptokenAddr = findLpToken[_tokenIn][_tokenOut];
419
+ uint reserveIn = reserve[lptokenAddr][_tokenIn];
420
+ uint reserveOut = reserve[lptokenAddr][_tokenOut];
421
+
422
+ tokenIn.transferFrom(msg.sender, address(this), _amountIn);
423
+
424
+
425
+ //交易税收
426
+ uint amountInWithFee = (_amountIn * (100000-lpFee-fundFee)) / 100000;
427
+ if(getFundFee() > 0){
428
+ tokenIn.transfer(fundAddr,fundFee * _amountIn / 100000);
429
+ }
430
+ amountOut = (reserveOut * amountInWithFee) / (reserveIn + amountInWithFee);
431
+
432
+ //检查滑点
433
+ setSli(amountInWithFee,reserveIn,reserveOut,_disirSli);
434
+
435
+
436
+ //tokenOut.transfer(msg.sender, amountOut);
437
+ uint totalReserve0 = reserve[lptokenAddr][_tokenIn] + _amountIn;
438
+ uint totalReserve1 = reserve[lptokenAddr][_tokenOut] - amountOut;
439
+
440
+ uint profit = lpFee * _amountIn / 100000;
441
+
442
+ _lpProfit[lptokenAddr] += profit;
443
+
444
+ _update(lptokenAddr,_tokenIn, _tokenOut, totalReserve0, totalReserve1);
445
+
446
+ }*/
447
+ //pair op
448
+ /*
449
+
450
+ function getUserAllLpInfo(address user) public view returns(address [] memory, uint [] memory)
451
+ {
452
+
453
+ uint [] memory balanceList;
454
+ for(uint i; i< userPairList[user].length; i++){
455
+ balanceList[i] = lptoken(userPairList[user][i]).balanceOf(user);
456
+ }
457
+ }
458
+
459
+ */
460
+
461
+ //依赖方法
462
+ //creatpair
463
+
464
+ function createPair(address addrToken0, address addrToken1) internal returns(address){
465
+ bytes32 _salt = keccak256(
466
+ abi.encodePacked(
467
+ addrToken0,addrToken1
468
+ )
469
+ );
470
+
471
+ address lptokenAddr = address(new lptoken{
472
+ salt : bytes32(_salt)
473
+ }
474
+ (addrToken0,addrToken1));
475
+
476
+ //检索lptoken
477
+ //_lpTokenAddressList.push(lptokenAddr);
478
+ datastore.lpToken(addrToken0,addrToken1,lptokenAddr);
479
+ //getLpToken[addrToken1][addrToken0] = lptokenAddr;
480
+ datastore.lpToken(addrToken1,addrToken0,lptokenAddr);
481
+
482
+
483
+ //_lpInfo[lptokenAddr] = [addrToken0,addrToken1];
484
+
485
+ return lptokenAddr;
486
+ }
487
+
488
+
489
+
490
+ function getBytecode() internal pure returns(bytes memory) {
491
+ bytes memory bytecode = type(lptoken).creationCode;
492
+ return bytecode;
493
+ }
494
+
495
+ function getAddress(bytes memory bytecode, bytes32 _salt)
496
+ internal
497
+ view
498
+ returns(address)
499
+ {
500
+ bytes32 hash = keccak256(
501
+ abi.encodePacked(
502
+ bytes1(0xff), address(this), _salt, keccak256(bytecode)
503
+ )
504
+ );
505
+
506
+ return address(uint160(uint(hash)));
507
+ }
508
+
509
+
510
+
511
+
512
+ //数据更新
513
+
514
+
515
+ //数学库
516
+
517
+
518
+
519
+
520
+
521
+ function setSli(uint dx, uint x, uint y, uint _disirSli) private pure returns(uint){
522
+
523
+
524
+ uint amountOut = (y * dx) / (x + dx);
525
+
526
+ uint dy = dx * y/x;
527
+ /*
528
+ loseAmount = Idea - ammOut
529
+ Sli = loseAmount/Idea
530
+ Sli = [dx*y/x - y*dx/(dx + x)]/dx*y/x
531
+ */
532
+ uint loseAmount = dy - amountOut;
533
+
534
+ uint Sli = loseAmount * 10000 /dy;
535
+
536
+ require(Sli <= _disirSli, "Sli too large");
537
+ return Sli;
538
+
539
+ }
540
+
541
+
542
+
543
+
544
+
545
+
546
+
547
+
548
+
549
+
550
+ }
@@ -0,0 +1,51 @@
1
+
2
+ <h1 align="center">
3
+ <span style="font-size: 32px;"> dex 协议 </span>
4
+
5
+ </h1>
6
+
7
+
8
+ # dex类型
9
+ ## AMM类型 (类uniswap)
10
+ - 全做市交易所
11
+ - 价格由算法来规范
12
+ - 价格算法双边平等
13
+ ## 关键功能
14
+ ### 添加流动性
15
+ - 添加条件
16
+ - 判断是否为第一次添加
17
+ ### 如果是
18
+ - 创建新的lptoken
19
+ - 写入相关数据
20
+ - 计算lptoken数(用平方根方法计算 )
21
+ - 第一次添加流动性
22
+
23
+ - $$lpAmount = \sqrt{token_A * token_B}$$
24
+ - 该算法只是其中之一,具体看需求,会影响到做市商。
25
+
26
+
27
+ - 发送token到合约
28
+ ### 如果不是
29
+ - 写入相关数据
30
+ - 计算lptoken数
31
+ - 发送token到合约
32
+ - 给用户mint lptoken
33
+ - 更新数据
34
+ ### 交易
35
+
36
+ - 条件
37
+ - 计算能兑换出多少token
38
+ - $$amountOut = (reserveOut * amountInWithFee) / (reserveIn + amountInWithFee)$$
39
+ - 兑换
40
+ - 更新数据
41
+
42
+ ### 移除流动性
43
+ - 要求
44
+ - 计算
45
+ - $$amount0 = (_shares * datastore.getReserve(lptokenAddr,_token0)) / lptoken(lptokenAddr).totalSupply()$$
46
+ - $$amount1 = (_shares * datastore.getReserve(lptokenAddr,_token1)) / lptoken(lptokenAddr).totalSupply()$$
47
+ - 兑换
48
+ - 更新
49
+ ## orderbook类型
50
+
51
+