update lending buyCollateral function
This commit is contained in:
@@ -373,6 +373,7 @@ contract Lending is
|
||||
|
||||
/**
|
||||
* @notice 购买清算后的抵押品
|
||||
* @dev 自动限制购买量到可用储备,只收取实际需要的费用
|
||||
*/
|
||||
function buyCollateral(
|
||||
address asset,
|
||||
@@ -388,15 +389,24 @@ contract Lending is
|
||||
revert NotForSale(); // 储备金充足,无需出售
|
||||
}
|
||||
|
||||
// 计算可购买的抵押品数量
|
||||
// 计算可购买的抵押品数量(基于用户愿意支付的 baseAmount)
|
||||
uint256 collateralAmount = quoteCollateral(asset, baseAmount);
|
||||
|
||||
// 验证数量
|
||||
if (collateralAmount < minAmount) revert InsufficientBalance();
|
||||
if (collateralAmount > collateralReserves[asset]) revert InsufficientBalance();
|
||||
// 自动限制到可用储备量
|
||||
// 这样可以防止价格波动导致交易失败
|
||||
if (collateralAmount > collateralReserves[asset]) {
|
||||
collateralAmount = collateralReserves[asset];
|
||||
}
|
||||
|
||||
// 收取清算人支付的资金
|
||||
IERC20(baseToken).transferFrom(msg.sender, address(this), baseAmount);
|
||||
// 滑点保护:确保购买量不低于用户的最小期望
|
||||
if (collateralAmount < minAmount) revert InsufficientBalance();
|
||||
|
||||
// 根据实际购买量计算需要支付的金额(而非固定的 baseAmount)
|
||||
// 这样如果购买量被限制,用户只需支付相应的费用
|
||||
uint256 actualBaseAmount = quoteBaseAmount(asset, collateralAmount);
|
||||
|
||||
// 收取实际需要的资金
|
||||
IERC20(baseToken).transferFrom(msg.sender, address(this), actualBaseAmount);
|
||||
|
||||
// 抵押品出库
|
||||
collateralReserves[asset] -= collateralAmount;
|
||||
@@ -405,7 +415,38 @@ contract Lending is
|
||||
IERC20(asset).safeTransfer(recipient, collateralAmount);
|
||||
|
||||
// 注意:收入会自动体现在 getReserves() 中,因为 balance 增加了
|
||||
emit BuyCollateral(msg.sender, asset, baseAmount, collateralAmount);
|
||||
emit BuyCollateral(msg.sender, asset, actualBaseAmount, collateralAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计算购买指定数量抵押品需要支付的 baseToken 数量(反向计算)
|
||||
* @param asset 抵押品地址
|
||||
* @param collateralAmount 要购买的抵押品数量
|
||||
* @return 需要支付的 baseToken 数量
|
||||
*/
|
||||
function quoteBaseAmount(address asset, uint256 collateralAmount) internal view returns (uint256) {
|
||||
AssetConfig memory assetConfig = assetConfigs[asset];
|
||||
|
||||
uint256 assetPrice = IYTLendingPriceFeed(lendingPriceSource).getPrice(asset);
|
||||
uint256 basePrice = IYTLendingPriceFeed(lendingPriceSource).getPrice(baseToken);
|
||||
|
||||
uint256 FACTOR_SCALE = 1e18;
|
||||
uint256 baseScale = 10 ** uint256(IERC20Metadata(baseToken).decimals());
|
||||
uint256 assetScale = 10 ** uint256(assetConfig.decimals);
|
||||
|
||||
// 计算折扣因子
|
||||
uint256 discountFactor = (storeFrontPriceFactor * (FACTOR_SCALE - assetConfig.liquidationFactor)) / FACTOR_SCALE;
|
||||
|
||||
// 计算折扣后的资产价格
|
||||
uint256 effectiveAssetPrice = (assetPrice * (FACTOR_SCALE - discountFactor)) / FACTOR_SCALE;
|
||||
|
||||
// 反向计算:baseAmount = (collateralAmount * effectiveAssetPrice * baseScale) / (basePrice * assetScale)
|
||||
if (baseScale == assetScale) {
|
||||
return (collateralAmount * effectiveAssetPrice) / basePrice;
|
||||
} else {
|
||||
uint256 adjustedAmount = (collateralAmount * baseScale) / assetScale;
|
||||
return (adjustedAmount * effectiveAssetPrice) / basePrice;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user