课程链接:https://space.bilibili.com/220951871/channel/collectiondetail?sid=2824381&ctype=0
讲义仓库:https://github.com/liangpeili/defi-2024/tree/main
DeFi简介
- DeFi:Uniswap/AAVE/Curve/DAl/Compound等;
- GameFi:从CryptoKitties开始;
- SocailFi:nostr/Damus/friend.tech/xpet;
- 国内目前政策:去fi留block,服务实体经济
CeFi的主要组成机构与职能
- 中央银行:发行法定货币
- 商业银行:存款、结算、信贷等;
- 保险公司:风险转移与分散;
- 证券公司:证券买卖、交易,证券承销等;
- 银监会、证监会和保监会;
- 国家金融监督管理总局
CeFi的特点
- 集中的账户管理
- 交易审查与监控
- 基于对机构的信任
- 手续费作为主要利润来源
- 不透明性/信息差
DeFi的起点
Bitcoin:A Peer-to-Peer Electronic Cash System
2021:DeFi之夏
以太坊DeFi生态一览:全球支付、钱包、基础设施、交易所、投资、身份认证、市场、保险、借贷、稳定币、衍生产品
DeFi的特点
- 账号个人管理:Not your keys,not your coins
- 无需许可
- 开源可验证
- 可编程性
- 注意:目前国内并没有做纯Defi的政策空间
课程安排
- 以Uniswap为核心,梳理DeFi领域的上下游产品及其原理
- 从稳定币入手,逐步介绍去中心化交易所Uniswap的核心逻辑,进而扩展到其他领域Defi产品(如借贷等)和算法。
- 理论课24学时+实验课8学时
- 《区块链应用系统开发实践》32学时
稳定币
货币的演化
- 实物货币
- 金属货币
- 基于黄金等贵金属抵押的法定货币
- 基于信用的法定货币
- 电子货币
- 数字货币?
基于法币抵押的稳定币一一USDT
- 稳定币市值排名第一;
- 由Tether发;
- 中心化管理;
- 可以冻结账户,销毁黑U,增发;
基于法币抵押的稳定币---BUSD
- Paxos发行的美元稳定币
- 受纽约金融服务局NYDFS的监管
- 用了Binance的品牌
- 可以1:1购买和赎回
- 100%的美元或者美元现金等价物支撑
- 仅在以太坊发行
- 2023年2月份停止发行
基于加密资产超额抵押的稳定币一DAI
- DAl是Maker Protocol的主要产品;
- Maker Protocol由MakerDAO管理;
- MKR是MakerDAO的治理代币;
- 有利息
MakerDAO 生态组成
DAI的供应量控制
- 贷款利率:Stability Fee
- 存款利率:DAI Saving Rate(DSR)
- 如果1DAI=0.99USD,提高利率
- 如果1DAI=1.01USD,降低利率
思考:为什么DAI会有怎么高的年化盈利能力?
理解MakerDAO团队如何通过DAI项目盈利,可以从以下几个方面考虑:
稳定费用(Stability Fee) :
MakerDAO通过向借款人收取稳定费用来盈利。当用户将加密资产(如ETH)抵押以铸造DAI时,需要支付稳定费用,这些费用是按借款金额的年化利率计算的。稳定费用的支付是通过MKR代币进行的,这些费用最终会被销毁,从而减少MKR的总供应量,提升其价值。
清算罚金(Liquidation Penalty) :
当抵押品价值下降到一定程度(即抵押率低于维持率)时,会触发清算过程。清算过程中,部分抵押品会被出售以偿还债务。清算过程中会收取清算罚金,这也是一种收入来源。
协议费用(Protocol Fees) :
MakerDAO可能会通过不同的协议费用来盈利,比如在特定操作或服务中收取一定比例的手续费。这些费用也会归入项目的盈利。
增值的MKR代币 :
通过收取稳定费用和清算罚金等方式,MakerDAO可以控制和减少MKR代币的供应量。随着项目的成功和生态系统的扩大,MKR代币的需求增加,其市场价值也会随之上升。MKR代币增值是团队和早期支持者的重要盈利途径。
风险管理产品 :
MakerDAO团队还可以开发和提供一些高级的金融工具和风险管理产品,这些产品可以在开放市场上销售或作为服务的一部分,产生收入。
通过上述方式,MakerDAO团队能够通过其稳定币项目实现盈利,同时维持DAI的稳定性和系统的正常运行。
案例分析
-
假设 1 ETH = 2000 USD, 质押了5个ETH 到Maker Vault,按照150%的超额抵押率,最多可以借出
-
10000 / 150% = 6666.67 个 DAI。保险起⻅,⽤户借出 5000 DAI,其余1666.67为缓冲区。
-
情形1: ETH 涨价到3000 USD。此时5 ETH = 15000 USD,基于150%的抵押率,⽤户最多可以借出10000 DAI。
-
情形2: ETH 跌到1500 USD,此时5 ETH = 7500 USD, 7500 USD / 5000 DAI = 150%。⽤户⾯临三个选择:
-
往Maker Vault 质押更多的ETH;
-
还回5000 DAI + Stability Fee, 拿回5个 ETH;
-
还回部分DAI + Stability Fee,增加⾃⼰的缓冲区;
-
DAI 的防护网之一------ Colleteral Auction
- 情形3: ETH 跌到1200 USD,此时5 ETH = 6000 USD,触发清算,Keeper 介⼊清算流程;5 个ETH 按照市价折扣3%进⾏拍卖,每次增加0.5%,直到拍卖成功;
- Keeper 使⽤DAI 来竞拍,价⾼者得;
- 扣除5000 DAI + Penalty Fee 等费⽤,其余 ETH 返回给⽤户;
DAI 的防护网之二------ Maker Buffer
- Stability Fee/Penalty Fee等缓慢积攒;
- 情形4: ETH 跌到900 USD,此时5 ETH = 4500 USD,拍卖后的缺⼝为 500 USD;
- 从Maker Buffer ⽀付500 DAI, 弥补缺⼝;
DAI 的防护网之三------ Debt Auction
- 情形5: ETH 跌到900 USD,此时5 ETH = 4500 USD,拍卖后的缺⼝为500 USD,⽽Maker Buffer ⾥只有100 DAI,资⾦缺⼝为400 USD。
- 增发MKR 进⾏拍卖;
- ⽤户使⽤DAI 参与拍卖,拍卖得到的DAI 来弥补缺⼝;
- ⼀种对社区治理惩罚的⽅式;
Decentralized Autonomous Organization (DAO)
- ⼀种新型的组织形式
- 发⾏治理Token
- 治理Token 代表投票权
- 社区共治、共建、共享
MakerDAO 的运行机制
提案阶段
- 发起提案:任何MKR 持有⼈都可以发起新提案;
- 在MakerDAO 社区讨论;
- 提交优化后的提案;
- Risk Team 对其进⾏⻛险评估;
投票阶段
- ⼀个MKR Token表示⼀个投票权,可以代理;
- 投票期⼀般持续7天;
- 根据投票结果决定是否通过;(4% 同意)
Surplus Auction
- Maker Buffer Limit
- 超出限制后的DAI ⽤来拍卖购买MKR;
- 销毁MKR;
- ⼀种社区治理的奖励⽅式;
基于算法的稳定币---一AMPL
总结
- 稳定币诞生的原因
- 稳定币的类型:USDT/USDC/BUSD/DAI/AMPL
- USDT的中心性
- DAI的运行原理
- Maker Protocol中的清算
- AMPL的运行原理
ERC4626
Vault
- 资产的管理、分红
- 用户充值某项资产,获取某个凭证(避免使用费用高昂的链上数据库)
- 该凭证作为分红、退出的依据
- Yield Farming/借贷/质押等
ERC4626 assets & shares
-
返回⾦库的基础资产代币地址:
solidityfunction asset() external view returns (address assetTokenAddress);
-
返回⾦库管理的基础代币总额:
solidityfunction totalAssets() external view returns (uint256 totalManagedAssets);
-
数量估计
solidityfunction convertToShares(uint256 assets) external view returns (uint256 shares); function convertToAssets(uint256 shares) external view returns (uint256 assets);
充值资产,获取shares
solidity
function maxDeposit(address receiver) external view returns (uint256 maxAssets);
function previewDeposit(uint256 assets) external view returns (uint256 shares);
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
function maxMint(address receiver) external view returns (uint256 maxShares);
function previewMint(uint256 shares) external view returns (uint256 assets);
function mint(uint256 shares, address receiver) external returns (uint256 assets);
返还shares,拿回资产
solidity
function maxWithdraw(address owner) external view returns (uint256 maxAssets);
function previewWithdraw(uint256 assets) external view returns (uint256 shares);
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
function maxRedeem(address owner) external view returns (uint256 maxShares);
function previewRedeem(uint256 shares) external view returns (uint256 assets);
function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
两个事件
solidity
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(address indexed sender,address indexed receiver,address indexed owner,uint256 assets,uint256 shares);
contracts/interfaces/IERC4626.sol
:https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/interfaces/IERC4626.sol
solidity
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4626.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../token/ERC20/IERC20.sol";
import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol";
/**
* @dev Interface of the ERC-4626 "Tokenized Vault Standard", as defined in
* https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].
*/
interface IERC4626 is IERC20, IERC20Metadata {
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(
address indexed sender,
address indexed receiver,
address indexed owner,
uint256 assets,
uint256 shares
);
/**
* @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
*
* - MUST be an ERC-20 token contract.
* - MUST NOT revert.
*/
function asset() external view returns (address assetTokenAddress);
/**
* @dev Returns the total amount of the underlying asset that is "managed" by Vault.
*
* - SHOULD include any compounding that occurs from yield.
* - MUST be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT revert.
*/
function totalAssets() external view returns (uint256 totalManagedAssets);
/**
* @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the "per-user" price-per-share, and instead should reflect the
* "average-user's" price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToShares(uint256 assets) external view returns (uint256 shares);
/**
* @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the "per-user" price-per-share, and instead should reflect the
* "average-user's" price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToAssets(uint256 shares) external view returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
* through a deposit call.
*
* - MUST return a limited value if receiver is subject to some deposit limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
* - MUST NOT revert.
*/
function maxDeposit(address receiver) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
* call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
* in the same transaction.
* - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
* deposit would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewDeposit(uint256 assets) external view returns (uint256 shares);
/**
* @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* deposit execution, and are accounted for during deposit.
* - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault's underlying asset token.
*/
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
* - MUST return a limited value if receiver is subject to some mint limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
* - MUST NOT revert.
*/
function maxMint(address receiver) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
* in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
* same transaction.
* - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
* would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by minting.
*/
function previewMint(uint256 shares) external view returns (uint256 assets);
/**
* @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
* execution, and are accounted for during mint.
* - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault's underlying asset token.
*/
function mint(uint256 shares, address receiver) external returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
* Vault, through a withdraw call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxWithdraw(address owner) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
* call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
* called
* in the same transaction.
* - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
* the withdrawal would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewWithdraw(uint256 assets) external view returns (uint256 shares);
/**
* @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* withdraw execution, and are accounted for during withdraw.
* - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
* through a redeem call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxRedeem(address owner) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
* in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
* same transaction.
* - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
* redemption would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by redeeming.
*/
function previewRedeem(uint256 shares) external view returns (uint256 assets);
/**
* @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* redeem execution, and are accounted for during redeem.
* - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}
ERC4626 Vault Smart Contract tutorial | DeFi Vault tutorial
去中心化交易所
中心化交易所的业务模式------以币安为例
- 交易费:交易所通过提供买卖加密货币的平台来收取交易费用有些交易所还提供高级交易选项,如杠杆交易,这通常会带来更高的费用;
- 上币费:项目方团队后面都会去找交易所上币,然而上币需要缴纳一笔数额不小的上币费;
- 量化交易:用户在交易所中,一般数字资产币都是暂时存放在交易所,基本上交易所掌握所有筹码可以选择做多或者做空,交易所可以去赚取差价,而用户提币出去也能赚取手续费;
- 原生代币;
中心化交易所的交易模式------订单簿模式
- 中央限价订单簿(CLOB)就是一本由出价和报价组成的权限透明账本,从最好价开始依次排序(两边分别是参与者愿意买/卖的价格)。
- 所有的参与者都能看到所有的报价和出价,他们也可以参与其中。
- 订单簿中两边的第一行,即是最好的报价/出价。
订单簿模式的优劣优势
-
优势
-
透明的流动性
-
做市商可自由出入
-
做市商可以自由决定价格与数量
-
-
劣势
- 冷启动问题(很难给出初始流动性)
- 对非流动性资产不利
- 如果是链上交易所,则对链的TPS的要求很高
链上交易方案:自动做市商
- 出现原因:以太坊的TPS对于支撑链上订单簿的实时更新来说太低了。反面案例:Solana链由于其60K的TPS,其上有许多订单簿模式的交易所。
- 交易所里没有订单簿,只有一系列预设的函数,为各类货币的互相交换来定价。
- 这些预设的函数(例如×*y=k)基于两头货币在各自流动性池中的供给变化率,来设定价格。在某个货币的流动性池内,任何人都能够提供该种货币以增加其流动性,从而获得收益。
CPAMM:Constant Product Auto Market Maker
- 基础公式:xy=k
- Liquidity Provider(LP)5 Liquidity Provider Token(LPT)
- LPT数量s=sqrt(x*y)
- 初始流动性确定价格
Dex的去中心性
- 任何人都可以添加流动性,成为LP,并拿到LP Token;
- LP在任意时间可以移除流动性并销毁LP Token,拿回自己添加的Token;
- 用户可以使用非官方的前端页面来进行交易;
- 交易时收取一定手续费,并且分配给LPT Holder;
自动化做市模式的优劣
-
优势:
-
对于新的代币,可以很方便的冷启动
-
去中心化
-
代币交换可组合性很高
-
-
劣势:
-
所有价格点的统一流动性(在Uniswap V3中已解决)
-
滑点频繁
-
波动性大,经常有很大的临时亏损(流动性提供者在平均表现上是盈利的)
-
CPAMM里的数学
- 起始状态:x*y=k
- 添加流动性Add liquidity
- (x+△x)y+△y)=k1,其中△x/△y=×/y,k1>k
- 交易Swap
- (x-△x)y+△y)=k或(X+△x)y-△y)=k
- 移除流动性Remove liquidity
- (x-△X)y-△y)=k2,其中△x/△y=×/y,k2<k
Uniswap
Uniswap 简介
Uniswap更新历史
Uniswap V2
- 2020年5月发布
- 增加ERC20-ERC20直接互换
- 增加Flash Swap闪存交换
- 增加Oracle预言机
- 改进手续费收取方式
- 引爆了DeFi赛道
- 2020年9月,发行治理代币UNI
Uniswap V2的核心合约
- Uniswap V2 Core
- UniswapV2Pair.sol
- UniswapV2Factory.sol
- Uniswap V2 Periphery
- Router contract
- Library contract
Uniswap vs SushiSwap
- 2020年8月28日,SushiSwap发布;
- SushiSwap fork了Uniswap,并且做了一些改进;
- SushiSwap增加了奖励系统,从Uniswap吸引走许多流动性;
- 作为回击,2020年9月Uniswap宣布发行UN‖作为治理代币;
Uniswap V3
- 2021年5月,Uniswap V3发布;
- 主要特性:
- 增加集中流动性:
- 优化手续费设置;
- LPT改成基于NFT的Liquidity Token;
- 改进开源协议;
Uniswap V4
- 2023年6月23日发布代码草案;
- 新增主要特性:
- Hook
- Singleton Pool Manager Design
- Reintroduction of Native ETH
- Flash Accounting
- 目标:更快、更省gas fee,容易集成;成为DeFi领域的基础设施;
Uniswap vs Binance
- 无须实名认证代码开源
- 上币不收费
- 用户自己管理资金,不用托管到交易所
- 社区治理
后续将详细分析Uniswap的数学模型,建议直接观看视频并手写笔记!
去中心化借贷
为什么会有借贷这个业务?
- 需求方(创业、购车、购房等)和资金方的匹配;
- 银行的主要利润来源;
- 借呗、微粒贷等互联网产品;
- 用好了是助力,用不好是灾难;
- 最简单直接的策略:不碰网贷;
区块链里的借贷
中心化借贷产品:Genesis Capita/BlockFi等;
去中心化借贷产品:AAVE、Compound、dy/dx等;
Borrower端需要考虑的问题
- 1.抵押物是什么?
- 2.抵押率怎么定?
- 3.借款利率
- 是多少?
- 怎么确定?
- 如何根据市场情况变化?
- 4.清算
- 什么情况下会被清算?
- 怎样清算?
- 价格来源是什么?
平台方需要考虑的问题
- 如何保护存款人的资金?
- 如何在提高资金利用率的情况下,保障存款人的正常业务?
- 收多少个点的服务费?
- 平台运行异常的情况下如何应对?
贷款利率的确定
- 目标:
- 提高存款使用率
- 保证存款人自由提取,防止挤兑
- 存款使用率的定义:存款使用率=未还借款数量/(未还借款数量+剩余存款数量)
- 根据存款使用率动态调节贷款利率
存款利率的确定
- 存款×存款利率+fee=借款×借款利率
- 存款利率<借款利率
资产托管
- 资产托管在智能合约
- 有没有托管凭证
- 借贷复式记账法
- 使用token做凭证
- 复投的利息计算
- daily compound
- monthly compound
- block compound
复式记账vs Token凭证
- T0时刻,用户A存入100DAI
- T1时刻,从T0到现在产生利息20DAI,此时用户B存入100DAI
- T2时刻,从T1到现在产生利息20DAI
- 问:用户A和用户B的利息各自是多少?
- 复式记账法计算
- 使用Token凭证计算
- 用户A:100DAl->100cDAl
- 用户B:100DA1->100100/120->83.33cDA
- 使用Token凭证的优势:
- 省去复杂的计算过程
- cToken可以在市面流通
抵押物和抵押率
- 一般基于超额抵押来控制风险
- 流动性差、流动性小的代币需要更高的抵押率;
- 流动性好、流动量大的代币需要较低的抵押率;
清算
目的:保护存款人,偿还存款人的资产;
健康因子公式:
\[\begin{aligned}&\mathrm{Health} Factor= \frac{\Sigma Value of Collateral_{i}*Liquidation Threshold_{i}}{Total Value of Debts}\\&0<\mathrm{Liquidation~Threshold}<1\end{aligned} \]
清算阈值是衡量资产安全的一个标准;
当健康因子小于1时,说明该头寸可被清算;
清算的方式
- 荷兰式拍卖:Maker Protocol/DDEX
- 奖励Keeper:按市场价给予一定的折扣,比如5%
- 现货市场出售:CEX/DEX
资产价格来源预言机
- 中心化预言机;
- 去中心化预言机,如Chainlink等;
- 预言机的任何失误都会导致灾难性的结果;
使用借贷产品的理由
- 存款人:存款收利息
- 借款人:
- 做多
- 做空
- 借款投资
- 使用价值