{"author":{"address":null,"user":"https://learnblockchain.cn/people/22539"},"content":{"body":"上一课中我们具体讲到了杠杆交易的风险，满足两个条件之后，就有可能会爆仓\r\n条件一：抵押品总USD价值 + 仓位盈亏USD价值 \u003c 资金USD费用 + 清算USD费用。\r\n条件二：(抵押品总USD价值 + 仓位盈亏USD价值) * 最大杠杆倍数 \u003c 仓位总USD价值。\r\n那如果爆仓了，合约会触发什么样的逻辑来执行清算相关的逻辑呢？下面我们就慢慢结合着源码来分析一下\r\n当然，清算的触发逻辑依然是由 “清算机器人” 来执行\r\n**清算的执行的核心智能合约是**\r\nPositionManager   仓位管理合约\r\nVault   核心资金管理合约\r\n\r\n**大致的执行流程**\r\n\r\n![image.png](https://img.learnblockchain.cn/attachments/2024/09/wQgt0Ew466d9217524848.png)\r\n\r\n**现在我们结合着源码一起来进行分析**\r\n\r\n```js\r\nfunction liquidatePosition(\r\n        address _account,   仓位对应的账户\r\n        address _collateralToken,   抵押token\r\n        address _indexToken,   目标资产的地址，用来跟踪仓位的价格 \r\n        bool _isLong,   （true 为多头，false 为空头）\r\n        address _feeReceiver  清算费用收取者，一般是清算机器人\r\n    ) external nonReentrant onlyLiquidator {\r\n        address _vault = vault;\r\n        // 这一步用来获取治理权限\r\n        address timelock = IVault(_vault).gov();  \r\n        // 获取用户的头寸信息,重点是size\r\n        (uint256 size, , , , , , , ) = IVault(vault).getPosition(_account, _collateralToken, _indexToken, _isLong);\r\n      \t// 如果是做多，这目标代币用最低价。反之则用最高级\r\n        uint256 markPrice = _isLong ? IVault(_vault).getMinPrice(_indexToken) : IVault(_vault).getMaxPrice(_indexToken);\r\n        // should be called strictly before position is updated in Vault\r\n        // 如果是做空仓位，则要进行全局的空头数据更新\r\n        IShortsTracker(shortsTracker).updateGlobalShortData(_account, _collateralToken, _indexToken, _isLong, size, markPrice, false);\r\n\r\n        // 启用杠杆\r\n        ITimelock(timelock).enableLeverage(_vault);\r\n        // 清算仓位\r\n        IVault(_vault).liquidatePosition(_account, _collateralToken, _indexToken, _isLong, _feeReceiver);\r\n        // 禁用杠杆\r\n  \t\t\tITimelock(timelock).disableLeverage(_vault);\r\n    }\r\n```\r\n第一步  获取当前的vault合约地址\r\n第二步  获取用户的头寸信息，重点是size\r\n第三步  获取目标代币的价格，如果是做多，用最低价，反正用最高价\r\n第四步  进行全局的空头数据更新（做多不用）\r\n第五步  启用杠杆\r\n第六步  调用valut 执行清算逻辑  （valut合约里面的逻辑最为核心，后面专门开辟一个章节来讲）\r\n第七步  禁用杠杆\r\n\r\n大家可能会有疑问的是， 第三步，为什么获取目标代币的价格的时候，做多用最低价，做空用最高价？\r\n因为在多头仓位中，清算的风险是价格下跌。如果价格跌破某个临界点，仓位需要被清算以防止更大损失。因此，使用最低价格是为了更接近市场的最坏情况，确保系统能及时清算，并且保证清算时用户的仓位是以较低的价格计算损失的。\r\n同理，当对空头仓位进行清算时，系统会使用该资产的最高价格（getMaxPrice），因为在空头仓位中，清算的风险是价格上涨。如果价格上涨到某个临界点，仓位需要被清算以防止更大损失。因此，使用最高价格可以防止用户在空头仓位中由于价格上涨造成更大的亏损，确保清算及时发生。\r\n\r\n第二点  大家看了源码可能会注意到，执行清算逻辑之前的处理逻辑，其实和市价单合约执行加仓前的逻辑非常类似，也有一个启用和禁用杠杆的逻辑\r\n这两步的核心还是防止杠杆被滥用，确保清算过程中，系统处于允许执行高风险操作的状态，而在清算结束后，及时关闭杠杆，防止潜在的恶意操作或系统错误引发不必要的风险。这种设计提高了系统的安全性和稳定性。\r\n\r\n第三点  大家可能注意到，PositionManager中，自身也有增加仓位，减少仓位的功能，和PositionRouter的功能类似，这是因为PositionManager中，它的方法更多的是面向管理员进行微调。而PositionRouter是面向用户进行杠杆交易的，两者面向的群体不一样。","title":"GMX 源码解析三，清算逻辑"},"history":null,"timestamp":1725506051,"version":1}