diff --git a/defi/Morpho/pictures/adjustAPY.png b/defi/Morpho/pictures/adjustAPY.png
new file mode 100644
index 000000000..eaf5ce3b7
Binary files /dev/null and b/defi/Morpho/pictures/adjustAPY.png differ
diff --git a/defi/Morpho/pictures/borrowAPY2LendAPY.png b/defi/Morpho/pictures/borrowAPY2LendAPY.png
new file mode 100644
index 000000000..e24e942ca
Binary files /dev/null and b/defi/Morpho/pictures/borrowAPY2LendAPY.png differ
diff --git a/defi/Morpho/pictures/borrowCapacity.png b/defi/Morpho/pictures/borrowCapacity.png
new file mode 100644
index 000000000..39e85af1e
Binary files /dev/null and b/defi/Morpho/pictures/borrowCapacity.png differ
diff --git a/defi/Morpho/pictures/borrowDelta.png b/defi/Morpho/pictures/borrowDelta.png
new file mode 100644
index 000000000..48460a29f
Binary files /dev/null and b/defi/Morpho/pictures/borrowDelta.png differ
diff --git a/defi/Morpho/pictures/borrowFlow.png b/defi/Morpho/pictures/borrowFlow.png
new file mode 100644
index 000000000..aa35bdd45
Binary files /dev/null and b/defi/Morpho/pictures/borrowFlow.png differ
diff --git a/defi/Morpho/pictures/borrowOverFlow.png b/defi/Morpho/pictures/borrowOverFlow.png
new file mode 100644
index 000000000..ef95e3e31
Binary files /dev/null and b/defi/Morpho/pictures/borrowOverFlow.png differ
diff --git a/defi/Morpho/pictures/borrowUnmatch.png b/defi/Morpho/pictures/borrowUnmatch.png
new file mode 100644
index 000000000..8f58d45ff
Binary files /dev/null and b/defi/Morpho/pictures/borrowUnmatch.png differ
diff --git a/defi/Morpho/pictures/compoundAPY.png b/defi/Morpho/pictures/compoundAPY.png
new file mode 100644
index 000000000..59c71a2f9
Binary files /dev/null and b/defi/Morpho/pictures/compoundAPY.png differ
diff --git a/defi/Morpho/pictures/depositFlow.png b/defi/Morpho/pictures/depositFlow.png
new file mode 100644
index 000000000..bd18415a0
Binary files /dev/null and b/defi/Morpho/pictures/depositFlow.png differ
diff --git a/defi/Morpho/pictures/morphoAPY.png b/defi/Morpho/pictures/morphoAPY.png
new file mode 100644
index 000000000..49685bb97
Binary files /dev/null and b/defi/Morpho/pictures/morphoAPY.png differ
diff --git a/defi/Morpho/pictures/morphoBorrow.png b/defi/Morpho/pictures/morphoBorrow.png
new file mode 100644
index 000000000..5ee5ee281
Binary files /dev/null and b/defi/Morpho/pictures/morphoBorrow.png differ
diff --git a/defi/Morpho/pictures/morphoSupply.png b/defi/Morpho/pictures/morphoSupply.png
new file mode 100644
index 000000000..5ea28b644
Binary files /dev/null and b/defi/Morpho/pictures/morphoSupply.png differ
diff --git a/defi/Morpho/pictures/repayBalance.png b/defi/Morpho/pictures/repayBalance.png
new file mode 100644
index 000000000..ef95e3e31
Binary files /dev/null and b/defi/Morpho/pictures/repayBalance.png differ
diff --git a/defi/Morpho/pictures/repayBorrowDelta.png b/defi/Morpho/pictures/repayBorrowDelta.png
new file mode 100644
index 000000000..86e9eaaff
Binary files /dev/null and b/defi/Morpho/pictures/repayBorrowDelta.png differ
diff --git a/defi/Morpho/pictures/repayP2P.png b/defi/Morpho/pictures/repayP2P.png
new file mode 100644
index 000000000..4fe0f7cb1
Binary files /dev/null and b/defi/Morpho/pictures/repayP2P.png differ
diff --git a/defi/Morpho/pictures/repaySupplyDelta.png b/defi/Morpho/pictures/repaySupplyDelta.png
new file mode 100644
index 000000000..48460a29f
Binary files /dev/null and b/defi/Morpho/pictures/repaySupplyDelta.png differ
diff --git a/defi/Morpho/pictures/replayMatch.png b/defi/Morpho/pictures/replayMatch.png
new file mode 100644
index 000000000..838739b31
Binary files /dev/null and b/defi/Morpho/pictures/replayMatch.png differ
diff --git a/defi/Morpho/pictures/supplyBorrowBalance.png b/defi/Morpho/pictures/supplyBorrowBalance.png
new file mode 100644
index 000000000..838739b31
Binary files /dev/null and b/defi/Morpho/pictures/supplyBorrowBalance.png differ
diff --git a/defi/Morpho/pictures/supplyDelta.png b/defi/Morpho/pictures/supplyDelta.png
new file mode 100644
index 000000000..48460a29f
Binary files /dev/null and b/defi/Morpho/pictures/supplyDelta.png differ
diff --git a/defi/Morpho/pictures/supplyMatch.png b/defi/Morpho/pictures/supplyMatch.png
new file mode 100644
index 000000000..9e3c667ff
Binary files /dev/null and b/defi/Morpho/pictures/supplyMatch.png differ
diff --git a/defi/Morpho/pictures/targetAPY.png b/defi/Morpho/pictures/targetAPY.png
new file mode 100644
index 000000000..49685bb97
Binary files /dev/null and b/defi/Morpho/pictures/targetAPY.png differ
diff --git a/defi/Morpho/readme.md b/defi/Morpho/readme.md
new file mode 100644
index 000000000..e18453036
--- /dev/null
+++ b/defi/Morpho/readme.md
@@ -0,0 +1,424 @@
+## Morpho 是什么
+Morpho是一个基于以太坊的借贷池优化器,通过点对点的匹配,为贷款人和借款人提供更好的利率。
+在 Morpho 的白皮书中,Morpho 描述自己的产品定位是 “流动性协议优化器”
+
+- 以 Compound 上 ETH 收益为例
+
+
+- 对应的曲线
+可以看到 Borrow 的平均年化收益率 为 0.1%,Supply 平均年化收益率为 2.7%
+
+
+- Morpho 的目标就是降低 Borrow 的年化利率,提高 Supply 的年化利率,就是中间这条蓝色的曲线
+
+
+- 具体操作如下
+ - 对于 Supplier
+ Step1: Supplier 存入资金到 Morpho
+ Step2: Morpho 把资金转存到 Compound
+ Step3: Compound mint cToken 给 Morpho
+
+
+ - 对于 Borrower
+ Step4: 存入抵押品,这一步可以视为 上面 Supplier 的操作
+ Step5、6: Morpho 使用 cToken 换取 Supplier 存入的资金
+ Step7: 把从 Compound 提取出来的资金借给 Borrower
+
+
+ 以上就是 Morpho 的整体流程,像是没有 Supplier 的时候,如果有用户进行 Borrow 需要怎么处理 ?或是 Supplier 和 Borrower 匹配成功后,Supplier 进行 withdraw 的时候需要怎么处理 ? 这些都是在 deposit, borrow, withdraw, repay , liquidate 接口进行的更加细致话的处理
+
+## Deposit
+Deposit 的接口流程伪代码如下
+```
+supply(user, amount):
+ update_Index() // 更新 Index
+ transfer(user, Morpho, amount) // 把用户资金转入到 Morpho 中
+
+ // Peer-to-peer supply
+ //// Promote borrowers
+ matched = matchBorrowers(amount) // 作为 Supplier, 寻找对手方 Borrower 进行匹配,
+ // 返回匹配到的最大资金量
+
+
+ supply_p2p(user) += matched / index_p2p // 更新用户的 p2p supply 基数
+
+
+ amount -= matched // 更新 amount
+
+
+ repay(Morpho, matched) // 把 matched 的资金偿还给 compound pool,因为这部分资金
+ // 开始是 Borrower 从 Compound 池中借出的,
+ // 现在直接和 Supplier 匹配了,就需要偿还这部分资金
+
+ // Pool supply
+ supply_pool(user) += amount / index_pool // 更新用户的 pool supply 基数
+ supply(Morpho, amount) // 把剩余的,未匹配的 amount 存入到 compound 中
+```
+
+
+
+### 关键点解析
+#### Compound 中对于 Supplier 使用汇率的方式计算 Supplier 的本息总额
+ $汇率 = \frac {资产 token 总数} {cToken总数}$
+ $资产token总数 = underlyingBalance + totalBorrowBalance - reserves$
+ $cToken总数 = cTokenSupply$
+ $underlyingBalance : 池子中现货 token 的数量$
+ $totalBalance: 池子中总共借出去的 token 数量,含利息$
+ $reserve: 池子自己的储备金$
+ Compound Supplier 的计算具体可参考 [Compound白皮书的思考](https://learnblockchain.cn/article/3153)
+
+
+#### Compound 中 BorrowerIndex 、totalBorrow 的计算方式
+ $Amount = 用户初始输入的借贷金额$
+ $latestBorrowIndex = borrowIndexInit * (1 + borrowRate(\Delta Blocks) )^{n}$
+ ( 注: 为了简化理解,上述式子中的 borrowIndexInit 可以取 1 )
+ $BorrowAmount = \frac {Amount} {latestBorrowIndex}$
+ $totalBorrow = BorrowAmount * latestBorrowIndex$
+ $n = 经过的块高或是时长( second )$
+ Compound Index 计算具体可参考 [Compound 合约部署](https://github.com/Dapp-Learning-DAO/Dapp-Learning/blob/main/defi/Compound/contract/Compound%E5%90%88%E7%BA%A6%E9%83%A8%E7%BD%B2.md)
+
+#### update_Index 逻辑
+前面说过,Morpho 的目标是求取 Borrow APY ( 代码中使用 poolBorrowGrowthIndex 表示 )、 Supply APY ( 代码中使用 poolSupplyGrowthIndex 表示 ) 以及 target APY ( 代码中使用 p2pGrowthIndex 表示 ) ,以便 Borrower 和 Supplier 都受益。 Morpho 中的 index 就是这个 target APY。
+后面使用 targetIndex 描述 target APY
+
+
+
+对于每一个借贷 Token,会设置一个 p2pIndexCursor 和 reserveFactor。
+- p2pIndexCursor 用于计算 p2pGrowthIndex
+- reserveFactor 设置 Morpho 的 p2p 借贷手续费,这个手续费只在用户进行 p2p 借贷的时候才会收取,如果直接向 compound 借贷是不会收取这个手续费
+```
+struct MarketParameters {
+ uint16 reserveFactor; // Proportion of the interest earned by users sent to the DAO for each market, in basis point (100% = 10 000). The value is set at market creation.
+ uint16 p2pIndexCursor; // Position of the peer-to-peer rate in the pool's spread. Determine the weights of the weighted arithmetic average in the indexes computations ((1 - p2pIndexCursor) * r^S + p2pIndexCursor * r^B) (in basis point).
+ }
+```
+$p2pGrowthIndex = (1 - p2pIndexCursor) * poolSupplyGrowthIndex + p2pIndexCursor * poolBorrowGrowthIndex$
+
+$p2pBorrowGrowthIndex = p2pIndex + (poolBorrowGrowthIndex - p2pIndex ) * reserveFactor$
+
+$p2pSupplyGrowthIndex = p2pIndex - (p2pIndex - poolSupplyGrowthIndex ) * reserveFactor$
+$p2pSupplyIndex = p2pIndex - (p2pIndex - poolSupplyIndex ) * reserveFactor$
+
+
+
+最后,得到 p2pSupplyGrowthIndex 和 p2pBorrowGrowthIndex 后,就可以计算
+$p2pSupplyIndex = p2pSupplyIndex * (1 + p2pSupplyGrowthIndex )$
+$p2pBorrowIndex = p2pBorrowIndex * ( 1 + p2pBorrowGrowthIndex )$
+
+
+#### Index 计算方式,和 $Supply_{p2p}$ , $Supply_{pool}$ 的关系
+- Index 在 Morpho 中用于计算借款利率,贷款利率 和 Compound 中的 borrowIndex 类似
+- 在 Morpho 的黄皮书中, 使用 λ 进行描述,这里为了便于理解统一使用 Index 描述。而且在 Morpho 的合约中,实际也是使用 Index 进行标识的
+- $Supply_{p2p}$ , $Supply_{pool}$ 分别保存用户的 p2p 贷款基数,和 pool 贷款基数
+
+假设 Index 以每天 20% 的速率递增
+| | 操作 | Morpho 状态 |
+| --- | --- | --- |
+| 第 0 天 | | Index = 1 |
+| 第一天 | $User_{A}$ 存入 100 Dai | Index = 1 * ( 1 + 0.2 ) = 1.2 ( 首先更新 Index 后再进行其他计算 )
+$Supply_{pool}[User_{A}]$ = $\frac {100} {1.2}$ = 83.333 |
+| 第二天 | | Index = 1.2 * ( 1 + 0.2 ) = 1.44 ( 首先更新 Index 后再进行其他计算 )
+$Supply_{pool}[User_{A}]$ = 83.333 |
+| 第三天 | $User_{B}$ 存入 200 Dai | Index = 1.44 * ( 1 + 0.2 ) = 1.728 ( 首先更新 Index 后再进行其他计算 )
+$Supply_{pool}[User_{A}]$ = 83.333
+$Supply_{pool}[User_{B}]$ = $\frac {200} {1.728}$ = 115.7407 |
+
+#### Supplier 和 Borrower 队列更新逻辑
+队列按照 Supplier ( 或是 Borrower ) 尚未匹配 p2p 的资金大小进行排序
+| Head | Second | Third | Fourth |
+| --- | --- | --- | --- |
+| User_A ( 100 Dai ) | User_B ( 80 Dai ) | User_C ( 60 Dai ) | User_D ( 20 Dai ) |
+
+队列具体更新逻辑可以参考 [DoubleLinkedList.sol](https://etherscan.io/address/0xe3d7a242614174ccf9f96bd479c42795d666fc81#code)
+
+
+#### 在匹配回路内允许消耗的最大的 gas
+查看用户 deposit 时的接口代码,可以看到,在接口输入中有一个 _maxGasForMatching 参数,用于设置在匹配 Borrower 时允许消耗的 gas 大小
+
+```
+/// @dev Implements supply logic.
+ /// @param _poolToken The address of the pool token the user wants to interact with.
+ /// @param _from The address of the account sending funds.
+ /// @param _onBehalf The address of the account whose positions will be updated.
+ /// @param _amount The amount of token (in underlying).
+ /// @param _maxGasForMatching The maximum amount of gas to consume within a matching engine loop.
+ function supplyLogic(
+ address _poolToken,
+ address _from,
+ address _onBehalf,
+ uint256 _amount,
+ uint256 _maxGasForMatching
+ )
+```
+
+## Borrow
+Borrow 的接口流程伪代码如下
+
+```
+borrow(user, amount):
+ update_Index()
+ if amount * pθ > borrow_capacity(user): // 判断借款金额是否超过抵押品价值
+ return
+
+ transfer(Morpho, user, initialAmount) // 转入用户资金到 Morpho
+ initialAmount = amount
+
+ // Peer-to-peer borrow
+ //// Promote suppliers
+ matched = matchSuppliers(amount) // 作为 Borrow 寻找匹配的 Supplier 对手方
+ // 返回匹配到的最大资金量
+
+ borrow_p2p(user) += matched / index_p2p // 更新用户的 p2p borrow 基数
+
+ amount -= matched // 更新 amount
+
+ withdraw(Morpho, matched) // 把 matched 的资金从 compound pool 中提取出来,
+
+ // Pool borrow
+ borrow_pool(user) += amount / index_pool // 更新用户的 pool borrow 数据
+ borrow(Morpho, amount) // 从 pool 中借出对应的金额
+```
+
+
+### 关键点解析
+- 判断用户的借款金额是否超出它的抵押品价值
+这里在 borrow_capacity 进行判断是否允许用户再次进行
+
+- Borrow 流程
+整体的 Borrow 流程和 Supply 类似,但是中间有一个特殊的处理
+但是随着交易的进行会出现 $P2P_{supply}$ 大于 $P2P_{borrow}$ 的情况,在下面的 repay 接口中会描述如何产生这种情况。
+在这种情况下,这部分 $\Delta {P2P_{supply}}$ 是 Morpho 按照 p2p 的 supply 提供给 supplier 的, 但是实际这部资金 Morpho 又会存入到 Compound 中,按照 pool supply 的利率从 Compound 中收取利息。所以这里就会存在一个利率差
+
+
+
+用户在 Borrow 的时候,Morpho 会首先把这部分资金匹配给 Borrower,以减少损失
+
+## Withdraw
+withdraw 的接口流程伪代码如下
+```
+withdraw(user, amount):
+ update_index()
+ if amount * Fθ * pθ > borrow_capacity(user): // 判断 withdraw 金额是否合法
+ return
+ initialAmount = amount
+
+ // Pool withdraw
+ withdrawnFromPool = min(amount, supply_pool(user) * index_pool ) //优先从 compound pool 中 withdraw
+
+ supply_pool(user) -= withdrawnFromPool / index_pool // 更新用户的 pool supply 记录
+
+ amount -= withdrawnFromPool //更新需要从 p2p pool 中提取的资金
+
+ withdraw(Morpho, withdrawnFromPool) // 从 compound pool 中提取资金
+
+ // Promote suppliers
+ matched = matchSuppliers(amount) // 如果当前 user 作为 supplier 已经匹配了对应的 borrower
+ // 则使用其他的 supplier 替换当前的 user 作为 p2p 的 supplier
+
+ supply_p2p(user) -= matched / index_p2p // 更新用户的 p2p supply 值
+
+ amount -= matched
+
+ withdraw(Morpho, matched) // 提取匹配到的 replace 当前 user 的 supplier 的资金
+
+ // Demote borrowers
+ unmatched = unmatchBorrowers(amount) // 剩余 p2p supply 资金无法找到 replace supplier
+ // 只能把一些 p2p borrower 降级为 pool borrower
+
+ supply_p2p (user) -= unmatched / index_pool // 更新 user 的 p2p supply
+
+ borrow(Morpho, unmatched) // 从 compound 中提取 剩余 p2p supply
+
+ transfer(Morpho, user, initialAmount) // 转移资金给用户
+```
+
+### 关键点解析
+资金 withdraw 顺序
+假设当前进行 withdraw 的用户为 User_A
+- 初始状态时,Morpho 池子处于平衡状态,即所有的 Borrow 都匹配了 p2p
+
+
+- 用户 User_A 有部分资金在 p2p 中,部分资金在 pool 中
+- 当 User_A 进行 withdraw 时,首先提取 User_A 在 pool 中的资金,此时所有的 Borrow 依然全部匹配 p2p
+- 在讲解 Borrow 接口的时候,我们讲到会存在 $\Delta P2P_{supply}$ 的情况,那么用户在 withdraw 的时候,会优先提取这部分的资金,相当于补偿 Morpho protocl 的损失
+
+
+- 之后,User_A 提取剩余 p2p 的资金 ,这里假设为 100 Dai ,同时从 pool 中寻中替代的 supplier 提供 p2p 贷款,此时所有的 Borrow 依然全部匹配 p2p
+- 如果在上一个寻找替代的 p2p supplier 时,只找到 20 Dai ,那么从 Compound 中提取这 20 Dai 还给用户,对于剩余的 80 Dai 进行如下处理。
+
+
+- 尝试对 80 Dai 对应的 Borrower 做 unmatch 处理,即改变这些 borrower 的借款利率,使之从 p2p 模式变为 pool 模式
+
+
+- 在 unmatch 接口中,同样需要传入一个 _maxGasForMatching,用于计算在 unmatch 过程中允许消耗的最大 gas。
+
+ ```solidity
+ /// @notice Unmatches borrowers' liquidity in peer-to-peer for the given `_amount` and moves it to Compound.
+ /// @dev Note: This function expects and peer-to-peer indexes to have been updated.
+ /// @param _poolToken The address of the market from which to unmatch borrowers.
+ /// @param _amount The amount to unmatch (in underlying).
+ /// @param _maxGasForMatching The maximum amount of gas to consume within a matching engine loop.
+ /// @return The amount unmatched (in underlying).
+ function _unmatchBorrowers(
+ address _poolToken,
+ uint256 _amount,
+ uint256 _maxGasForMatching
+ ) internal returns (uint256) {
+ ```
+
+- 如果传入一个很小的值,那么会造成只 unmatch 部分 p2p 资金 ,这里假设 unmatch 了 20 Dai , 那么还剩余 80 - 20 = 60 Dai 的 p2p 资金没有 unmatch。这个时候 Morpho 就会让这 60 Dai 对应的 borrower 继续保持 p2p 借贷的利率,同时记录 delta.p2pBorrowDelta 作为没有匹配到 p2p 的 borrow 资金。
+
+
+- 最后,从 Comound 中借出剩余的 80 Dai 还给用户。这里可以看到,实际这部分 delta.p2pBorrowDelta 是 Morpho 从 Compound 借出来,但是按照 p2p 的利率提供给 Borrow 的,这样中间就会产生一个利率差
+
+## Repay
+repay 的接口流程伪代码如下
+```
+repay(user, amount):
+ update_Index() // 更新 Index
+ if amount > borrow_p2p(user) * index_p2p + borrow_pool(user) * index_pool:
+ return
+
+ transfer(user, Morpho, amount) // 准入用户 repay 资金到 Morpho
+
+ // Pool repay
+ repaidOnPool = min(amount, b_pool(user) * index_pool) // 优先偿还 pool 的借贷资金
+ borrow_pool(user) -= repaidOnPool / index_pool
+ amount -= repaidOnPool
+ repay(Morpho, repaidOnPool)
+
+ // Promote borrowers
+ matched = matchBorrowers(amount) // 如果当前 user 是 p2p 匹配用户
+ borrow_p2p(user) -= matched / index_p2p // 则寻找 replace borrower
+ amount -= matched
+ repay(Morpho, matched)
+
+ // Demote suppliers
+ unmatched = unmatchSuppliers(amount) // 对于剩余的 p2p borrower 资金,
+ borrow_p2p(user) -= unmatched / index_p2p // 如果未找到 replace borrower,
+ supply(Morpho, unmatched) // 则尝试把对应的 p2p supplier 降级为 pool supplier
+```
+
+### 关键点解析
+#### 资金 repay 顺序
+
+- 假设用户 pool borrow 资金为 20 Dai, p2p borrow 资金为 80 Dai。那么用户首先需要偿还 pool borrow 部分的 20 Dai 资金
+
+
+
+- pool borrow 资金偿还后,用户剩下的 borrow 资金就是 p2p 资金,这里为 80 Dai
+
+
+
+- 更新 borrower 的 p2p 资金。
+
+ 这里需要注意的是,borrower 的 p2p 资金更新是在 repay p2p 之前的,因为后面更新 Morpho p2p borrow amount 的时候还需要额外计算一部分利息
+
+ ```solidity
+ borrowerBorrowBalance.inP2P -= Math.min(
+ borrowerBorrowBalance.inP2P,
+ vars.remainingToRepay.div(vars.p2pBorrowIndex)
+ );
+ ```
+
+- 在讲 withdraw 接口的时候,我们提到在 Borrow 这边会存在 $\Delta P2P_{borrow}$ 的情况。那么这里用户进行 repay 的时候,Morpho 会检测是否存在 $\Delta P2P_{borrow}$ ,如果存在,则用户需要优先支付这部分的 borrow 资金 ,这里假设 $\Delta P2P_{borrow}$ 为 10 Dai, 那么剩余需要 repay 的资金为 80 - 10 = 70 Dai。
+
+ 需要注意的是,这里用户偿还 $\Delta P2P_{borrow}$ 时,实际是在补偿 Morpho protocl 的亏损,而不是用户自己的
+
+
+
+- 更新 Morhpo protocl 的 p2pBorrowAmount,p2pSupplyAmount。
+
+ 主意这里更新全局的 p2pBorrowAmount 的时候,会把 $\Delta P2P_{supply}$ 产生的利息差计算进去进行更新
+
+ ```solidity
+
+ // Fee = (p2pBorrowAmount - p2pBorrowDelta) - (p2pSupplyAmount - p2pSupplyDelta).
+ // No need to subtract p2pBorrowDelta as it is zero.
+ vars.feeToRepay = Math.zeroFloorSub(
+ delta.p2pBorrowAmount.mul(vars.p2pBorrowIndex),
+ delta.p2pSupplyAmount.mul(vars.p2pSupplyIndex).zeroFloorSub(
+ delta.p2pSupplyDelta.mul(ICToken(_poolToken).exchangeRateStored())
+ )
+ );
+
+ if (vars.feeToRepay > 0) {
+ uint256 feeRepaid = Math.min(vars.feeToRepay, vars.remainingToRepay);
+ vars.remainingToRepay -= feeRepaid;
+ delta.p2pBorrowAmount -= feeRepaid.div(vars.p2pBorrowIndex);
+ emit P2PAmountsUpdated(_poolToken, delta.p2pSupplyAmount, delta.p2pBorrowAmount);
+ }
+ ```
+
+
+
+- 到这一步的时候,Morpho 池子中消除了原始存在的 $\Delta P2P_{supply}$ 和 $\Delta P2P_{borrow}$ 。
+
+ 和 withdraw 的时候类似,这个时候就是在 $Pool_{borrow}$ 中寻找替代者。
+
+ 但是如果找不到可以提到的 borrower 的时候,又会产生新的 $\Delta P2P_{supplyNew}$
+
+
+
+ - 对于这个 $\Delta P2P_{supplyNew}$ 继续进行处理,最直接的方式就是把这部分的 supplier 降级。这里使用 _unmatchSuppliers 进行降级处理。
+
+ 跟 _unmatchBorrowers 接口一样,调用时会传入一个 _maxGasForMatching,用于计算在 unmatch 过程中允许消耗的最大 gas。所以依然存在 $\Delta P2P_{supplyNew}$ 无法完全消除的情况
+
+ ```solidity
+ /// @notice Unmatches suppliers' liquidity in peer-to-peer up to the given `_amount` and moves it to Compound.
+ /// @dev Note: This function expects Compound's exchange rate and peer-to-peer indexes to have been updated.
+ /// @param _poolToken The address of the market from which to unmatch suppliers.
+ /// @param _amount The amount to search for (in underlying).
+ /// @param _maxGasForMatching The maximum amount of gas to consume within a matching engine loop.
+ /// @return The amount unmatched (in underlying).
+ function _unmatchSuppliers(
+ address _poolToken,
+ uint256 _amount,
+ uint256 _maxGasForMatching
+ ) internal returns (uint256) {
+ ```
+
+ - $\Delta P2P_{supplyNew}$ 无法完全消除时,更新 p2pSupplyDelta 的值,然后把剩余的 repay 资金转入 Compound 并结束此次处理
+
+ ```solidity
+ if (vars.remainingToRepay > 0) {
+ uint256 unmatched = _unmatchSuppliers(
+ _poolToken,
+ vars.remainingToRepay,
+ vars.remainingGasForMatching
+ );
+
+ // Increase the peer-to-peer supply delta.
+ if (unmatched < vars.remainingToRepay) {
+ delta.p2pSupplyDelta += (vars.remainingToRepay - unmatched).div(
+ ICToken(_poolToken).exchangeRateStored() // Exchange rate has already been updated.
+ );
+ emit P2PSupplyDeltaUpdated(_poolToken, delta.p2pSupplyDelta);
+ }
+
+ delta.p2pSupplyAmount -= unmatched.div(vars.p2pSupplyIndex);
+ delta.p2pBorrowAmount -= vars.remainingToRepay.div(vars.p2pBorrowIndex);
+ emit P2PAmountsUpdated(_poolToken, delta.p2pSupplyAmount, delta.p2pBorrowAmount);
+
+ _supplyToPool(_poolToken, underlyingToken, vars.remainingToRepay); // Reverts on error.
+ }
+ ```
+
+
+## Liquidate
+
+liquidate 的接口流程伪代码如下
+
+```solidity
+liquiate(user, amount):
+ update_Index() // 更新 Index
+ liquidationAllowed() // 判断是否可以被清算
+
+ _unsafeRepay() // 调用内部 repay 接口进行 repay
+ _unsafeWithdraw() // 调用内部 withdraw 接口进行 withdraw
+```
+
+### 关键点解析
+
+- 清算逻辑
+Morpho 使用和 Compound 同样的 oracle,closeFactor 和 liquidationIncentive 进行清算,即保持和 Compound 完全相同的清算处理
\ No newline at end of file
diff --git "a/defi/instadapp/InstaDapp\345\220\210\347\272\246\350\247\243\346\236\220.md" "b/defi/instadapp/InstaDapp\345\220\210\347\272\246\350\247\243\346\236\220.md"
new file mode 100644
index 000000000..c5987f42b
--- /dev/null
+++ "b/defi/instadapp/InstaDapp\345\220\210\347\272\246\350\247\243\346\236\220.md"
@@ -0,0 +1,348 @@
+## InstaDapp 是什么
+Instadapp 是 DeFi 的中间件平台,是一个面向用户的去中心化资产管理协议,提供了针对 MakerDAO, Compound, AAVE , Uniswap 等协议 的高效的资产管理功能,其目标是简化 DeFi 的复杂性,最终成为 DeFi 的统一前端。
+
+## InstaDapp 的两个产品
+针对不同的用户群体,推出了两个不同的产品,分别是 InstaDapp Lite 和 InstaDapp Pro.
+
+个人感觉,这两个产品主要的区别在 分险系数 、用户对 Defi 认知度的水平 ( 或用户操作的频率 )
+
+### [InstaDapp Lite](https://lite.instadapp.io/)
+
+
+
+低分险 ( 相对于 InstaDapp Pro ),不频繁操作的用户或是对 Defi 认知水平较低的可以选择这个产品。
+
+根据 [官方文档](https://lite.guides.instadapp.io/getting-started/what-is-instadapp-lite) 的介绍,InstaDapp Lite 有如下特点:
+
+1) POS 奖励放大
+
+Lite 只有一个主要收益策略,那就是通过在 [Lido](https://lido.fi/) 上 stake ETH 赚取收益。就算用户 Deposit Dai, Lite 也会把 Dai 转换为 stETH。“POS 奖励放大” 其实也就是通过集中散户的资金,在 Lido 中达到较高的占比,从而获取更高的收益。
+
+另一个次要收益策略是把 stETH 放到 Compound、AAVE 等借贷协议中进行放贷来赚取双重收益。
+
+
+
+2) 简化 DeFi 策略
+
+利用 DSA ( DeFi Smart Accounts, 后面 InstaDapp Pro 会详细介绍 ) 账户简化和各个 Defi 协议的操作
+
+3) 最小化交易和节省 Gas 成本
+
+这个也是利用了 DSA 的便利性
+
+### [InstaDapp Pro](https://defi.instadapp.io/)
+
+针对这个产品,用户有更多的操作空间,可以利用不同的策略进行杠杆、再融资和转移头寸,同时通过自动化实现回报最大化。
+
+当然这些要求用户具有更加专业的 Defi 知识,能自己控制识别其中的风险。
+
+Pro 页面提供了 Simulation 功能,用户可以在正式使用前,进行模拟操作,熟悉掌握 Pro 的用法
+
+
+
+1) Pro 目前在 Ethereum Mainnet 上集成了 Maker、Compound、Aave V2、Aave V3、Uniswap V3、Liquity、Savings Dai、Morpho、Morpho V3、Spark 这些协议,在其他 L2 上集成的协议较少。比如 Polygon 上, 就只集成了 Aave V2、Aave V3、Compound V3、Uniswap V3
+
+2) 对于用户的账户资金,可以进行如下操作:
+
+- 资产跨链 ( 集成 [Hop.Exchange](http://Hop.Exchange) 实现 )
+- 资产交易 ( swap )
+- Deposit、Withdraw
+
+3)对于用户的杠杆、头寸的操作,Pro 定义为 Strategies,总共有如下 Strategies:
+
+- Refinance , 比如把 Aave V2 的仓位转移到 到 Morpho
+- Leverage / Max mining,最大化杠杆,比如在 Aave 中存入 ETH, 借出 Dai 后再转换为 ETH, 然后在存入 Aave 中,这样循环操作
+- Unwind / Deleverage,降低杠杆,比如 withdraw Aave 中的 ETH 用来偿还从 Aave 中借出的 Dai
+- Collateral Swap, 抵押品转换,例如 withdraw 部分 Aave 中的抵押品 ( ETH ),然后把这部分的 ETH 换成 USDT 后在存入到 Aave 中
+- Debt Swap, 债务转换,比如已经从 Aave 中借出 10 Dai, 那么现在再从 Aave 中借出 5 USDT,把这 5 USDT 转换为 Dai, 偿还 Aave 中的 Dai, 那么最后用户就从 10 Dai 的债务变为 5 Dai、5 USDT 的债务
+- Deposit & Borrow , 存入和借款,就是在一笔交易中完成存入和借款的操作
+- Payback & Withdraw, 偿还和提取,在一笔交易中完成债务偿还和取款的操作
+
+总结,从上面我们可以看到,Pro 的这些 Strategies 其实就是组合了多笔操作,把原先用户需要 2 -3 笔交易才能完成的操作合并为 1 笔交易,同时操作的主要对象还是当前仓位对应的 Defi
+
+## InstaDapp 架构
+
+对于 Lite 和 Pro 都是采用同一套架构,其中主要分为了 3 个角色
+
+- Dapp
+
+ 和 DeFi Smart Layer (DSL) 交互的 Dap,包括 InstaDapp、其他 Dapp 、Wallet ( 如 Metamask 等 )
+
+- DeFi Smart Layer (DSL)
+
+ DeFi 智能层,也是 InstaDapp 的核心逻辑层,这一层又可以细分为 3 个部分
+
+ - Authority: 只有授权的地址才可以操作 **Smart Accounts ,使用 Smart Accounts 中的资金进行操作**
+ - Defi Smart Accounts ( DSA )**:智能账户层 ( 其实就是 solidity 合约 )。**InstaDapp **单独创建一个 solidity 合约作为用户的 Account ,优势在于 InstaDapp 可以在合约中插件式组合各种操作,从而在一笔交易中完成复杂的操作,而这是原生的 address 无法完成的**
+ - Connectors: 连接器层。**Smart Accounts 没有直接和各个 Defi 协议进行交易,而是通过 Connector 进行操作,实现了账户和操作分离的架构。各个开发者或是项目方可以通过实现特定的 Connector ,完美的接入 InstaDapp 中**
+
+
+ 各个链各个 Defi Protocol 对应的 connector 对应官网如下:https://docs.instadapp.io/connectors/mainnet/aave-v2
+
+- Defi Protocol
+
+ 协议层,对应的就是各个 Defi 协议
+
+
+
+
+ 参考来源:https://blog.instadapp.io/introducing-defi-smart-layer/
+
+## Defi Smart Layer 实现
+
+下面将分析 Defi Smart Layer 的具体实现逻辑。
+
+### 创建 Smart Account
+
+从 Defi Smart Layer 的结构中可以看到,用户必须要有一个 Smart Account 才能和各个 Defi 进行交互。而且当用户初次进入 InstaDapp Pro 的时候,会强制要求用户创建一个 DSA
+
+
+
+创建 Smart Account 的具体过程如下:
+
+- 用户调用 InstaIndex 合约的 build 接口
+
+```
+function build(
+ address _owner,
+ uint accountVersion,
+ address _origin
+ ) public returns (address _account) {
+ require(accountVersion != 0 && accountVersion <= versionCount, "not-valid-account");
+ _account = createClone(accountVersion); // 通过 clone 的 方式生成 Smart Account
+ ListInterface(list).init(_account);
+ AccountInterface(_account).enable(_owner);
+ emit LogAccountCreated(msg.sender, _owner, _account, _origin);
+ }
+```
+
+ InstaIndex 合约实现可参考:https://polygonscan.com/address/0xa9b99766e6c676cf1975c0d3166f96c0848ff5ad#code
+
+- InstaIndex 在 build 接口内部通过 clone 的方式生成 Smart Account
+
+```
+function createClone(uint version) internal returns (address result) {
+ bytes20 targetBytes = bytes20(account[version]);
+ // solium-disable-next-line security/no-inline-assembly
+ assembly {
+ let clone := mload(0x40)
+ mstore(clone, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
+ mstore(add(clone, 0x14), targetBytes)
+ mstore(add(clone, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
+ result := create(0, clone, 0x37)
+```
+
+Smart Account 合约实现可参考: https://polygonscan.com/address/0x51cbc90528bf960a6d5728306f0e9fae3cce38ed#code
+
+至此,Smart Account 就创建完成
+
+### Smart Account 的 delegate
+
+Smart Account 内部代码很简洁,所有过来的用户调用最终通过 delegate 的方式调用到真正的业务合约,这里的 delegate 的目标地址为 implementation 地址
+
+```
+contract InstaAccountV2 {
+
+ AccountImplementations public immutable implementations;
+
+ constructor(address _implementations) {
+ implementations = AccountImplementations(_implementations);
+ }
+
+ ...................
+
+ function _fallback(bytes4 _sig) internal {
+ address _implementation = implementations.getImplementation(_sig);
+ require(_implementation != address(0), "InstaAccountV2: Not able to find _implementation");
+ _delegate(_implementation);
+ }
+
+ fallback () external payable {
+ _fallback(msg.sig);
+ }
+
+}
+```
+
+- _delegate 具体实现如下
+
+```
+function _delegate(address implementation) internal {
+ // solhint-disable-next-line no-inline-assembly
+ assembly {
+ // Copy msg.data. We take full control of memory in this inline assembly
+ // block because it will not return to Solidity code. We overwrite the
+ // Solidity scratch pad at memory position 0.
+ calldatacopy(0, 0, calldatasize())
+
+ // Call the implementation.
+ // out and outsize are 0 because we don't know the size yet.
+ let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
+
+ // Copy the returned data.
+ returndatacopy(0, 0, returndatasize())
+
+ switch result
+ // delegatecall returns 0 on error.
+ case 0 { revert(0, returndatasize()) }
+ default { return(0, returndatasize()) }
+ }
+ }
+```
+
+Smart Account 处理流程图:
+
+
+
+### Implementation 的实现
+
+从如下 Smart Account 的 fallback 接口中可以看到,根据用户的 sig, 可以选择不同的 implementation 实现,这里以其中的一个实现 InstaImplementationM1 为例进行分析
+
+```
+function _fallback(bytes4 _sig) internal {
+ address _implementation = implementations.getImplementation(_sig);
+ require(_implementation != address(0), "InstaAccountV2: Not able to find _implementation");
+ _delegate(_implementation);
+ }
+```
+
+InstaImplementationM1 合约实现可参考:
+
+https://etherscan.io/address/0x8a3462a50e1a9fe8c9e7d9023cacbd9a98d90021
+
+- cast 调用
+
+InstaImplementationM1 中的入口只有一个,那就 cast 接口。
+
+cast 处理过程如下:
+
+- 根据传入的 _targetNames ( 这个参数是个数组 )获取对应的 connectors ( 返回的 connectors 也是个数组 ),connectors 在代码中对应为 _targets
+- 然后对每个 _target 调用 spell ,其实就是 delegate call
+
+```solidity
+ function cast(
+ string[] calldata _targetNames,
+ bytes[] calldata _datas,
+ address _origin
+ )
+ external
+ payable
+ returns (bytes32) // Dummy return to fix instaIndex buildWithCast function
+ {
+ ..............
+
+ string[] memory eventNames = new string[](_length);
+ bytes[] memory eventParams = new bytes[](_length);
+
+ (bool isOk, address[] memory _targets) = ConnectorsInterface(connectorsM1).isConnectors(_targetNames);
+
+ require(isOk, "1: not-connector");
+
+ for (uint i = 0; i < _length; i++) {
+ bytes memory response = spell(_targets[i], _datas[i]);
+ (eventNames[i], eventParams[i]) = decodeEvent(response);
+ }
+
+ ..............
+ }
+```
+
+- 如下查看 spell 代码,可以发现里面使用的就是 delegate call 到 connector
+
+```
+function spell(address _target, bytes memory _data) internal returns (bytes memory response) {
+ require(_target != address(0), "target-invalid");
+ assembly {
+ let succeeded := delegatecall(gas(), _target, add(_data, 0x20), mload(_data), 0, 0)
+ let size := returndatasize()
+
+ response := mload(0x40)
+ mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))
+ mstore(response, size)
+ returndatacopy(add(response, 0x20), 0, size)
+
+ switch iszero(succeeded)
+ case 1 {
+ // throw if delegatecall failed
+ returndatacopy(0x00, 0x00, size)
+ revert(0x00, size)
+ }
+ }
+ }
+```
+
+- connector 中就是和具体的 Defi protocol 交互的逻辑,比如 Aave, Uniswap, Compound
+
+ConnectV2AaveV2Polygon **可参考如下:**
+
+https://polygonscan.com/address/0x14272cf069a5ce1b97c9999b8c368cf3704acd0b#code
+
+### Smart Account 整体调用流程
+
+总结起来,Smart Account 调用的整体流程如下图
+
+
+
+### Smart Account 调用实例
+
+下面以在 InstaDapp Pro 上,对 Aave V2 的仓位进行 Leverage / Max mining 为例进行复盘分析
+
+
+
+- 交易如下
+
+传入的参数 _targetNames 中,存在三个元素
+
+
+
+重放交易,可以看到其中具体的跳转
+
+
+
+交易分析工具: https://dashboard.tenderly.co/
+
+### Authority 角色赋权
+
+Defi Smart Layer 中的一个重要角色就是 Authority ( user )
+
+一个 Smart Account 可以有多个 Authorities
+
+
+
+Authority 的管理涉及到两个合约,InstaList 和 InstaIndex ,这两个合约记录了 Smart Account 和各个 Authority 的对应关系
+
+**InstaList 合约代码:** https://polygonscan.com/address/0x839c2D3aDe63DF5b0b8F3E57D5e145057Ab41556#code
+
+**InstaIndex 合约代码:** https://polygonscan.com/address/0xa9b99766e6c676cf1975c0d3166f96c0848ff5ad#code
+
+- 初次创建 Smart Account 时添加 Authority
+
+在前文中讲到,在创建 Smart Account 的时候,需要调用 InstaIndex 的 build 接口。在这个接口中,会把 user 添加到新创建的 Smart Account 的 Authority 里面,
+
+```solidity
+function build(
+ address _owner,
+ uint accountVersion,
+ address _origin
+ ) public returns (address _account) {
+ require(accountVersion != 0 && accountVersion <= versionCount, "not-valid-account");
+ _account = createClone(accountVersion);
+ ListInterface(list).init(_account);
+ AccountInterface(_account).enable(_owner); // 添加 owner 为 Authority
+ emit LogAccountCreated(msg.sender, _owner, _account, _origin);
+ }
+```
+
+- 添加其他 Authority
+
+在界面手工添加另一个 Authority, 在交易参数中,可以看到 _targetNames 传入的参数值为 AUTHORITY-A
+
+
+
+重放这笔交易,可以看到最终时调用的 InstaList 的 addAuth
+
+
+
+最后吐糟下,官方的 repo 的只需要看 dsa-contract 这个 repo 就可以了
+
+官方的 doc 文档确实最新的,所以最好是直接对着 doc 文档,然后发笔交易进行 debug
\ No newline at end of file
diff --git a/defi/instadapp/pictures/instaDapp1.png b/defi/instadapp/pictures/instaDapp1.png
new file mode 100644
index 000000000..2d2c20599
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp1.png differ
diff --git a/defi/instadapp/pictures/instaDapp10.png b/defi/instadapp/pictures/instaDapp10.png
new file mode 100644
index 000000000..ce0d86dbf
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp10.png differ
diff --git a/defi/instadapp/pictures/instaDapp11.png b/defi/instadapp/pictures/instaDapp11.png
new file mode 100644
index 000000000..81428253a
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp11.png differ
diff --git a/defi/instadapp/pictures/instaDapp12.png b/defi/instadapp/pictures/instaDapp12.png
new file mode 100644
index 000000000..18013221d
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp12.png differ
diff --git a/defi/instadapp/pictures/instaDapp13.png b/defi/instadapp/pictures/instaDapp13.png
new file mode 100644
index 000000000..8f1a3cf61
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp13.png differ
diff --git a/defi/instadapp/pictures/instaDapp2.png b/defi/instadapp/pictures/instaDapp2.png
new file mode 100644
index 000000000..a4b5d0d98
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp2.png differ
diff --git a/defi/instadapp/pictures/instaDapp3.png b/defi/instadapp/pictures/instaDapp3.png
new file mode 100644
index 000000000..0fa36c399
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp3.png differ
diff --git a/defi/instadapp/pictures/instaDapp4.png b/defi/instadapp/pictures/instaDapp4.png
new file mode 100644
index 000000000..5e812823a
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp4.png differ
diff --git a/defi/instadapp/pictures/instaDapp5.png b/defi/instadapp/pictures/instaDapp5.png
new file mode 100644
index 000000000..94d2cf5a4
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp5.png differ
diff --git a/defi/instadapp/pictures/instaDapp6.png b/defi/instadapp/pictures/instaDapp6.png
new file mode 100644
index 000000000..c2b8bd524
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp6.png differ
diff --git a/defi/instadapp/pictures/instaDapp7.png b/defi/instadapp/pictures/instaDapp7.png
new file mode 100644
index 000000000..dba9ab6ee
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp7.png differ
diff --git a/defi/instadapp/pictures/instaDapp8.png b/defi/instadapp/pictures/instaDapp8.png
new file mode 100644
index 000000000..5170e6ea9
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp8.png differ
diff --git a/defi/instadapp/pictures/instaDapp9.png b/defi/instadapp/pictures/instaDapp9.png
new file mode 100644
index 000000000..77332d9f1
Binary files /dev/null and b/defi/instadapp/pictures/instaDapp9.png differ