web3chain041903 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 +115 -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
+