update lending script

This commit is contained in:
2025-12-22 14:12:50 +08:00
parent 682552bfe6
commit 0024e7adb1
25 changed files with 797 additions and 1108 deletions

View File

@@ -0,0 +1,708 @@
{
"manifestVersion": "3.2",
"proxies": [
{
"address": "0x050ACf48e82d3688A93180082f7adeA015d78892",
"txHash": "0x88ce2a21356bed6c3c42db72206cbcd8fa642990fae1eb4dfd2786db8ed420b8",
"kind": "uups"
},
{
"address": "0x916fD79AFE9BdA073A8eF68014026c59292f4bec",
"txHash": "0x80ce485d96f5d3d0672cd212476808ac0198195c6b1e8841c4c4c612f03eab9a",
"kind": "uups"
},
{
"address": "0x6D12F383d58Fb05f00799dEB5742CC0EF28Cf038",
"txHash": "0x274b6b58b6aaf391968fca65e83ce65088a77fff30ed715fc565874d086a3b15",
"kind": "uups"
}
],
"impls": {
"0d29172dc4cf27b6f2516e07cdf4850639d3150c256071c0332dc01901c02251": {
"address": "0x12F6b84017E70C85Bf9EF2CEF320BccFd7E7314B",
"txHash": "0x597ee4bd6908d95d23c501171d737fcdabe9a6ebc7e1cf22837f801754e1de04",
"layout": {
"solcVersion": "0.8.28",
"storage": [
{
"label": "factory",
"offset": 0,
"slot": "0",
"type": "t_mapping(t_address,t_address)",
"contract": "ConfiguratorStorage",
"src": "contracts/ytLending/ConfiguratorStorage.sol:12"
},
{
"label": "configuratorParams",
"offset": 0,
"slot": "1",
"type": "t_mapping(t_address,t_struct(Configuration)5434_storage)",
"contract": "ConfiguratorStorage",
"src": "contracts/ytLending/ConfiguratorStorage.sol:15"
}
],
"types": {
"t_address": {
"label": "address",
"numberOfBytes": "20"
},
"t_bool": {
"label": "bool",
"numberOfBytes": "1"
},
"t_struct(InitializableStorage)73_storage": {
"label": "struct Initializable.InitializableStorage",
"members": [
{
"label": "_initialized",
"type": "t_uint64",
"offset": 0,
"slot": "0"
},
{
"label": "_initializing",
"type": "t_bool",
"offset": 8,
"slot": "0"
}
],
"numberOfBytes": "32"
},
"t_struct(OwnableStorage)13_storage": {
"label": "struct OwnableUpgradeable.OwnableStorage",
"members": [
{
"label": "_owner",
"type": "t_address",
"offset": 0,
"slot": "0"
}
],
"numberOfBytes": "32"
},
"t_uint64": {
"label": "uint64",
"numberOfBytes": "8"
},
"t_array(t_struct(AssetConfig)5401_storage)dyn_storage": {
"label": "struct LendingConfiguration.AssetConfig[]",
"numberOfBytes": "32"
},
"t_mapping(t_address,t_address)": {
"label": "mapping(address => address)",
"numberOfBytes": "32"
},
"t_mapping(t_address,t_struct(Configuration)5434_storage)": {
"label": "mapping(address => struct LendingConfiguration.Configuration)",
"numberOfBytes": "32"
},
"t_struct(AssetConfig)5401_storage": {
"label": "struct LendingConfiguration.AssetConfig",
"members": [
{
"label": "asset",
"type": "t_address",
"offset": 0,
"slot": "0"
},
{
"label": "priceFeed",
"type": "t_address",
"offset": 0,
"slot": "1"
},
{
"label": "decimals",
"type": "t_uint8",
"offset": 20,
"slot": "1"
},
{
"label": "borrowCollateralFactor",
"type": "t_uint64",
"offset": 21,
"slot": "1"
},
{
"label": "liquidateCollateralFactor",
"type": "t_uint64",
"offset": 0,
"slot": "2"
},
{
"label": "liquidationFactor",
"type": "t_uint64",
"offset": 8,
"slot": "2"
},
{
"label": "supplyCap",
"type": "t_uint128",
"offset": 16,
"slot": "2"
}
],
"numberOfBytes": "96"
},
"t_struct(Configuration)5434_storage": {
"label": "struct LendingConfiguration.Configuration",
"members": [
{
"label": "baseToken",
"type": "t_address",
"offset": 0,
"slot": "0"
},
{
"label": "baseTokenPriceFeed",
"type": "t_address",
"offset": 0,
"slot": "1"
},
{
"label": "supplyKink",
"type": "t_uint64",
"offset": 20,
"slot": "1"
},
{
"label": "supplyPerYearInterestRateSlopeLow",
"type": "t_uint64",
"offset": 0,
"slot": "2"
},
{
"label": "supplyPerYearInterestRateSlopeHigh",
"type": "t_uint64",
"offset": 8,
"slot": "2"
},
{
"label": "supplyPerYearInterestRateBase",
"type": "t_uint64",
"offset": 16,
"slot": "2"
},
{
"label": "borrowKink",
"type": "t_uint64",
"offset": 24,
"slot": "2"
},
{
"label": "borrowPerYearInterestRateSlopeLow",
"type": "t_uint64",
"offset": 0,
"slot": "3"
},
{
"label": "borrowPerYearInterestRateSlopeHigh",
"type": "t_uint64",
"offset": 8,
"slot": "3"
},
{
"label": "borrowPerYearInterestRateBase",
"type": "t_uint64",
"offset": 16,
"slot": "3"
},
{
"label": "storeFrontPriceFactor",
"type": "t_uint64",
"offset": 24,
"slot": "3"
},
{
"label": "trackingIndexScale",
"type": "t_uint64",
"offset": 0,
"slot": "4"
},
{
"label": "baseBorrowMin",
"type": "t_uint104",
"offset": 8,
"slot": "4"
},
{
"label": "targetReserves",
"type": "t_uint104",
"offset": 0,
"slot": "5"
},
{
"label": "assetConfigs",
"type": "t_array(t_struct(AssetConfig)5401_storage)dyn_storage",
"offset": 0,
"slot": "6"
}
],
"numberOfBytes": "224"
},
"t_uint104": {
"label": "uint104",
"numberOfBytes": "13"
},
"t_uint128": {
"label": "uint128",
"numberOfBytes": "16"
},
"t_uint8": {
"label": "uint8",
"numberOfBytes": "1"
}
},
"namespaces": {
"erc7201:openzeppelin.storage.Ownable": [
{
"contract": "OwnableUpgradeable",
"label": "_owner",
"type": "t_address",
"src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:24",
"offset": 0,
"slot": "0"
}
],
"erc7201:openzeppelin.storage.Initializable": [
{
"contract": "Initializable",
"label": "_initialized",
"type": "t_uint64",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:69",
"offset": 0,
"slot": "0"
},
{
"contract": "Initializable",
"label": "_initializing",
"type": "t_bool",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:73",
"offset": 8,
"slot": "0"
}
]
}
}
},
"6b202cc33fae20652e97fb9c193b89bcf63d24b3d9c81a0dc6ae547bc6b68239": {
"address": "0xa4FE1e07b99035E4471c13fb30ee9c045b3D6899",
"txHash": "0x4818e0d236efece7b8a5fbacd2391755272a20a660091ffc603da397daa9aa25",
"layout": {
"solcVersion": "0.8.28",
"storage": [
{
"label": "baseToken",
"offset": 0,
"slot": "0",
"type": "t_address",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:14"
},
{
"label": "baseTokenPriceFeed",
"offset": 0,
"slot": "1",
"type": "t_address",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:14"
},
{
"label": "supplyKink",
"offset": 20,
"slot": "1",
"type": "t_uint64",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:18"
},
{
"label": "supplyPerSecondInterestRateSlopeLow",
"offset": 0,
"slot": "2",
"type": "t_uint64",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:19"
},
{
"label": "supplyPerSecondInterestRateSlopeHigh",
"offset": 8,
"slot": "2",
"type": "t_uint64",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:20"
},
{
"label": "supplyPerSecondInterestRateBase",
"offset": 16,
"slot": "2",
"type": "t_uint64",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:22"
},
{
"label": "borrowKink",
"offset": 24,
"slot": "2",
"type": "t_uint64",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:23"
},
{
"label": "borrowPerSecondInterestRateSlopeLow",
"offset": 0,
"slot": "3",
"type": "t_uint64",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:24"
},
{
"label": "borrowPerSecondInterestRateSlopeHigh",
"offset": 8,
"slot": "3",
"type": "t_uint64",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:25"
},
{
"label": "borrowPerSecondInterestRateBase",
"offset": 16,
"slot": "3",
"type": "t_uint64",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:28"
},
{
"label": "storeFrontPriceFactor",
"offset": 24,
"slot": "3",
"type": "t_uint64",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:29"
},
{
"label": "trackingIndexScale",
"offset": 0,
"slot": "4",
"type": "t_uint64",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:31"
},
{
"label": "baseBorrowMin",
"offset": 8,
"slot": "4",
"type": "t_uint104",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:33"
},
{
"label": "targetReserves",
"offset": 0,
"slot": "5",
"type": "t_uint104",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:34"
},
{
"label": "assetConfigs",
"offset": 0,
"slot": "6",
"type": "t_mapping(t_address,t_struct(AssetConfig)5401_storage)",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:35"
},
{
"label": "assetList",
"offset": 0,
"slot": "7",
"type": "t_array(t_address)dyn_storage",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:39"
},
{
"label": "userBasic",
"offset": 0,
"slot": "8",
"type": "t_mapping(t_address,t_struct(UserBasic)5931_storage)",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:44"
},
{
"label": "userCollateral",
"offset": 0,
"slot": "9",
"type": "t_mapping(t_address,t_mapping(t_address,t_uint256))",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:48"
},
{
"label": "totalSupplyBase",
"offset": 0,
"slot": "10",
"type": "t_uint104",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:53"
},
{
"label": "totalBorrowBase",
"offset": 13,
"slot": "10",
"type": "t_uint104",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:55"
},
{
"label": "supplyIndex",
"offset": 0,
"slot": "11",
"type": "t_uint256",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:56"
},
{
"label": "borrowIndex",
"offset": 0,
"slot": "12",
"type": "t_uint256",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:57"
},
{
"label": "lastAccrualTime",
"offset": 0,
"slot": "13",
"type": "t_uint256",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:57"
},
{
"label": "collateralReserves",
"offset": 0,
"slot": "14",
"type": "t_mapping(t_address,t_uint256)",
"contract": "LendingStorage",
"src": "contracts/ytLending/LendingStorage.sol:60"
}
],
"types": {
"t_address": {
"label": "address",
"numberOfBytes": "20"
},
"t_bool": {
"label": "bool",
"numberOfBytes": "1"
},
"t_struct(InitializableStorage)73_storage": {
"label": "struct Initializable.InitializableStorage",
"members": [
{
"label": "_initialized",
"type": "t_uint64",
"offset": 0,
"slot": "0"
},
{
"label": "_initializing",
"type": "t_bool",
"offset": 8,
"slot": "0"
}
],
"numberOfBytes": "32"
},
"t_struct(OwnableStorage)13_storage": {
"label": "struct OwnableUpgradeable.OwnableStorage",
"members": [
{
"label": "_owner",
"type": "t_address",
"offset": 0,
"slot": "0"
}
],
"numberOfBytes": "32"
},
"t_struct(PausableStorage)224_storage": {
"label": "struct PausableUpgradeable.PausableStorage",
"members": [
{
"label": "_paused",
"type": "t_bool",
"offset": 0,
"slot": "0"
}
],
"numberOfBytes": "32"
},
"t_struct(ReentrancyGuardStorage)288_storage": {
"label": "struct ReentrancyGuardUpgradeable.ReentrancyGuardStorage",
"members": [
{
"label": "_status",
"type": "t_uint256",
"offset": 0,
"slot": "0"
}
],
"numberOfBytes": "32"
},
"t_uint256": {
"label": "uint256",
"numberOfBytes": "32"
},
"t_uint64": {
"label": "uint64",
"numberOfBytes": "8"
},
"t_array(t_address)dyn_storage": {
"label": "address[]",
"numberOfBytes": "32"
},
"t_int104": {
"label": "int104",
"numberOfBytes": "13"
},
"t_mapping(t_address,t_mapping(t_address,t_uint256))": {
"label": "mapping(address => mapping(address => uint256))",
"numberOfBytes": "32"
},
"t_mapping(t_address,t_struct(AssetConfig)5401_storage)": {
"label": "mapping(address => struct LendingConfiguration.AssetConfig)",
"numberOfBytes": "32"
},
"t_mapping(t_address,t_struct(UserBasic)5931_storage)": {
"label": "mapping(address => struct LendingStorage.UserBasic)",
"numberOfBytes": "32"
},
"t_mapping(t_address,t_uint256)": {
"label": "mapping(address => uint256)",
"numberOfBytes": "32"
},
"t_struct(AssetConfig)5401_storage": {
"label": "struct LendingConfiguration.AssetConfig",
"members": [
{
"label": "asset",
"type": "t_address",
"offset": 0,
"slot": "0"
},
{
"label": "priceFeed",
"type": "t_address",
"offset": 0,
"slot": "1"
},
{
"label": "decimals",
"type": "t_uint8",
"offset": 20,
"slot": "1"
},
{
"label": "borrowCollateralFactor",
"type": "t_uint64",
"offset": 21,
"slot": "1"
},
{
"label": "liquidateCollateralFactor",
"type": "t_uint64",
"offset": 0,
"slot": "2"
},
{
"label": "liquidationFactor",
"type": "t_uint64",
"offset": 8,
"slot": "2"
},
{
"label": "supplyCap",
"type": "t_uint128",
"offset": 16,
"slot": "2"
}
],
"numberOfBytes": "96"
},
"t_struct(UserBasic)5931_storage": {
"label": "struct LendingStorage.UserBasic",
"members": [
{
"label": "principal",
"type": "t_int104",
"offset": 0,
"slot": "0"
}
],
"numberOfBytes": "32"
},
"t_uint104": {
"label": "uint104",
"numberOfBytes": "13"
},
"t_uint128": {
"label": "uint128",
"numberOfBytes": "16"
},
"t_uint8": {
"label": "uint8",
"numberOfBytes": "1"
}
},
"namespaces": {
"erc7201:openzeppelin.storage.ReentrancyGuard": [
{
"contract": "ReentrancyGuardUpgradeable",
"label": "_status",
"type": "t_uint256",
"src": "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol:43",
"offset": 0,
"slot": "0"
}
],
"erc7201:openzeppelin.storage.Pausable": [
{
"contract": "PausableUpgradeable",
"label": "_paused",
"type": "t_bool",
"src": "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol:21",
"offset": 0,
"slot": "0"
}
],
"erc7201:openzeppelin.storage.Ownable": [
{
"contract": "OwnableUpgradeable",
"label": "_owner",
"type": "t_address",
"src": "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol:24",
"offset": 0,
"slot": "0"
}
],
"erc7201:openzeppelin.storage.Initializable": [
{
"contract": "Initializable",
"label": "_initialized",
"type": "t_uint64",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:69",
"offset": 0,
"slot": "0"
},
{
"contract": "Initializable",
"label": "_initializing",
"type": "t_bool",
"src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:73",
"offset": 8,
"slot": "0"
}
]
}
}
}
}
}

View File

@@ -34,6 +34,11 @@
"name": "InvalidLiquidationFactor",
"type": "error"
},
{
"inputs": [],
"name": "NotForSale",
"type": "error"
},
{
"inputs": [],
"name": "NotLiquidatable",
@@ -310,25 +315,6 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
@@ -559,6 +545,25 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "supplyBalanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{

View File

@@ -86,6 +86,11 @@
"name": "InvalidLiquidationFactor",
"type": "error"
},
{
"inputs": [],
"name": "NotForSale",
"type": "error"
},
{
"inputs": [],
"name": "NotInitializing",
@@ -580,25 +585,6 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "baseBorrowMin",
@@ -1184,6 +1170,25 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "supplyBalanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{

View File

@@ -1,701 +0,0 @@
[
{
"inputs": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "address",
"name": "_priceUpdater",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "allowance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "needed",
"type": "uint256"
}
],
"name": "ERC20InsufficientAllowance",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"internalType": "uint256",
"name": "balance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "needed",
"type": "uint256"
}
],
"name": "ERC20InsufficientBalance",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "approver",
"type": "address"
}
],
"name": "ERC20InvalidApprover",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"name": "ERC20InvalidReceiver",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "ERC20InvalidSender",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "ERC20InvalidSpender",
"type": "error"
},
{
"inputs": [],
"name": "InsufficientAssets",
"type": "error"
},
{
"inputs": [],
"name": "IntervalTooLong",
"type": "error"
},
{
"inputs": [],
"name": "InvalidAmount",
"type": "error"
},
{
"inputs": [],
"name": "InvalidUpdater",
"type": "error"
},
{
"inputs": [],
"name": "InvalidYield",
"type": "error"
},
{
"inputs": [],
"name": "NotUpdater",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"inputs": [],
"name": "UpdateTooFrequent",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "interval",
"type": "uint256"
}
],
"name": "MinUpdateIntervalSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "oldPrice",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newPrice",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"name": "PriceUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "updater",
"type": "address"
}
],
"name": "PriceUpdaterSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "timestamp",
"type": "uint256"
}
],
"name": "YieldAccumulated",
"type": "event"
},
{
"inputs": [],
"name": "PRICE_PRECISION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "accumulatedYield",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "assetPrice",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
}
],
"name": "deposit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getPriceInfo",
"outputs": [
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "lastUpdate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "timeSinceUpdate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalVal",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "lastPriceUpdate",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "minUpdateInterval",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "priceUpdater",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_interval",
"type": "uint256"
}
],
"name": "setMinUpdateInterval",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_updater",
"type": "address"
}
],
"name": "setPriceUpdater",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalAssets",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "updatePrice",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_newYield",
"type": "uint256"
}
],
"name": "updateYield",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_amount",
"type": "uint256"
}
],
"name": "withdraw",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]

File diff suppressed because one or more lines are too long

View File

@@ -86,21 +86,12 @@ contract Lending is
}
}
/**
* @dev 授权升级函数 - 只有 owner 可以升级
*/
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
/**
* @notice 暂停合约
*/
function pause() external onlyOwner {
_pause();
}
/**
* @notice 恢复合约
*/
function unpause() external onlyOwner {
_unpause();
}
@@ -527,7 +518,7 @@ contract Lending is
return LendingMath.principalToBalance(principal, supplyIndex);
}
function balanceOf(address account) external view override returns (uint256) {
function supplyBalanceOf(address account) external view override returns (uint256) {
int104 principal = userBasic[account].principal;
if (principal <= 0) return 0;
// 只返回正余额(存款)

View File

@@ -5,10 +5,6 @@ import "@openzeppelin/contracts/access/Ownable.sol";
import "./Lending.sol";
import "./LendingConfiguration.sol";
/**
* @title LendingFactory
* @notice 工厂合约 - 用于部署新的 Lending 实现
*/
contract LendingFactory is LendingConfiguration, Ownable {
constructor() Ownable(msg.sender) {}

View File

@@ -6,25 +6,15 @@ pragma solidity ^0.8.0;
* @notice 借贷池核心接口
*/
interface ILending {
// ========== Events ==========
event Supply(address indexed from, address indexed dst, uint256 amount);
event Withdraw(address indexed src, address indexed to, uint256 amount);
event SupplyCollateral(address indexed from, address indexed dst, address indexed asset, uint256 amount);
event WithdrawCollateral(address indexed src, address indexed to, address indexed asset, uint256 amount);
/// @notice 清算债务事件
event AbsorbDebt(address indexed absorber, address indexed borrower, uint256 basePaidOut, uint256 usdValue);
/// @notice 清算抵押品事件
event AbsorbCollateral(address indexed absorber, address indexed borrower, address indexed asset, uint256 collateralAbsorbed, uint256 usdValue);
event BuyCollateral(address indexed buyer, address indexed asset, uint256 baseAmount, uint256 collateralAmount);
/// @notice 储备金提取事件
event WithdrawReserves(address indexed to, uint256 amount);
// ========== Errors ==========
error Unauthorized();
error InsufficientBalance();
error InsufficientCollateral();
@@ -37,144 +27,25 @@ interface ILending {
error InsufficientReserves();
error NotForSale();
// ========== Core Functions ==========
/**
* @notice 存入基础资产
* @param amount 存入金额
*/
function supply(uint256 amount) external;
/**
* @notice 取出基础资产
* @param amount 取出金额
*/
function withdraw(uint256 amount) external;
/**
* @notice 存入抵押品
* @param asset 抵押品地址
* @param amount 抵押品数量
*/
function supplyCollateral(address asset, uint256 amount) external;
/**
* @notice 取出抵押品
* @param asset 抵押品地址
* @param amount 抵押品数量
*/
function withdrawCollateral(address asset, uint256 amount) external;
/**
* @notice 借款(通过取出超过存款的基础资产实现)
* @param amount 借款金额
*/
function borrow(uint256 amount) external;
/**
* @notice 清算不良债务(单个)
* @param borrower 待清算的借款人地址
*/
function absorb(address borrower) external;
/**
* @notice 批量清算不良债务
* @param absorber 清算发起人地址
* @param accounts 待清算的借款人地址数组
*/
function absorbMultiple(address absorber, address[] calldata accounts) external;
/**
* @notice 购买清算后的抵押品
* @param asset 抵押品地址
* @param minAmount 最小购买量
* @param baseAmount 支付的基础资产数量
* @param recipient 接收抵押品的地址
*/
function buyCollateral(address asset, uint256 minAmount, uint256 baseAmount, address recipient) external;
// ========== View Functions ==========
/**
* @notice 获取用户基础资产余额
* @param account 用户地址
* @return 余额(正数=存款,负数=借款)
*/
function getBalance(address account) external view returns (int256);
/**
* @notice 获取用户抵押品余额
* @param account 用户地址
* @param asset 抵押品地址
* @return 抵押品数量
*/
function getCollateral(address account, address asset) external view returns (uint256);
/**
* @notice 检查账户是否可被清算
* @param account 用户地址
* @return 是否可清算
*/
function isLiquidatable(address account) external view returns (bool);
/**
* @notice 获取当前供应利率
* @return 供应利率 (年化scaled by 1e18)
*/
function getSupplyRate() external view returns (uint64);
/**
* @notice 获取当前借款利率
* @return 借款利率 (年化scaled by 1e18)
*/
function getBorrowRate() external view returns (uint64);
/**
* @notice 获取用户存款余额只返回正数部分ERC20兼容
* @param account 用户地址
* @return 存款余额
*/
function balanceOf(address account) external view returns (uint256);
/**
* @notice 获取用户借款余额(只返回债务部分)
* @param account 用户地址
* @return 借款余额
*/
function supplyBalanceOf(address account) external view returns (uint256);
function borrowBalanceOf(address account) external view returns (uint256);
/**
* @notice 计算支付指定baseAmount可购买的抵押品数量
* @param asset 抵押品地址
* @param baseAmount 支付的基础资产数量
* @return 可购买的抵押品数量
*/
function quoteCollateral(address asset, uint256 baseAmount) external view returns (uint256);
/**
* @notice 获取协议储备金
* @return 储备金余额(可能为负)
*/
function getReserves() external view returns (int256);
/**
* @notice 获取抵押品库存
* @param asset 抵押品地址
* @return 库存数量
*/
function getCollateralReserves(address asset) external view returns (uint256);
/**
* @notice 获取市场利用率
* @return 利用率scaled by 1e18
*/
function getUtilization() external view returns (uint256);
/**
* @notice 提取协议储备金(仅 owner
* @param to 接收地址
* @param amount 提取数量
*/
function withdrawReserves(address to, uint256 amount) external;
}

View File

@@ -6,16 +6,7 @@ pragma solidity ^0.8.0;
* @notice 价格预言机接口
*/
interface IPriceFeed {
/**
* @notice 获取资产价格
* @return price 价格 (scaled by 1e8)
*/
function getPrice() external view returns (uint256 price);
/**
* @notice 获取价格精度
* @return 价格小数位数
*/
function decimals() external view returns (uint8);
}

View File

@@ -1,161 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title YTToken
* @notice YT代币示例实现Yield Token
* @dev 展示如何实现价格接口供YTPriceFeed读取
*/
contract YTToken is ERC20, Ownable {
error NotUpdater();
error InvalidUpdater();
error IntervalTooLong();
error UpdateTooFrequent();
error InvalidYield();
error InvalidAmount();
error InsufficientAssets();
uint256 public constant PRICE_PRECISION = 10 ** 30;
uint256 public totalAssets;
uint256 public accumulatedYield;
// 价格变量
uint256 public assetPrice;
uint256 public lastPriceUpdate;
// 价格更新控制
address public priceUpdater;
uint256 public minUpdateInterval = 5 minutes; // 最小更新间隔
event PriceUpdated(uint256 oldPrice, uint256 newPrice, uint256 timestamp);
event YieldAccumulated(uint256 amount, uint256 timestamp);
event PriceUpdaterSet(address indexed updater);
event MinUpdateIntervalSet(uint256 interval);
modifier onlyPriceUpdater() {
if (msg.sender != priceUpdater && msg.sender != owner()) revert NotUpdater();
_;
}
constructor(
string memory name,
string memory symbol,
address _priceUpdater
) ERC20(name, symbol) Ownable(msg.sender) {
assetPrice = PRICE_PRECISION; // 初始价格为1
lastPriceUpdate = block.timestamp;
priceUpdater = _priceUpdater;
}
/**
* @notice 设置价格更新者
*/
function setPriceUpdater(address _updater) external onlyOwner {
if (_updater == address(0)) revert InvalidUpdater();
priceUpdater = _updater;
emit PriceUpdaterSet(_updater);
}
/**
* @notice 设置最小更新间隔
*/
function setMinUpdateInterval(uint256 _interval) external onlyOwner {
if (_interval > 1 hours) revert IntervalTooLong();
minUpdateInterval = _interval;
emit MinUpdateIntervalSet(_interval);
}
/**
* @notice 更新代币价格
* @dev 只能由授权的updater调用有最小时间间隔限制
*/
function updatePrice() public onlyPriceUpdater {
if (block.timestamp < lastPriceUpdate + minUpdateInterval) revert UpdateTooFrequent();
uint256 oldPrice = assetPrice;
uint256 supply = totalSupply();
if (supply == 0) {
assetPrice = PRICE_PRECISION;
} else {
uint256 totalValue = totalAssets + accumulatedYield;
// 计算每个token对应的USDC价值18位精度
uint256 usdcPerToken = totalValue * 1e18 / supply;
// 转换为30位精度的价格
assetPrice = usdcPerToken * PRICE_PRECISION / 1e18;
}
lastPriceUpdate = block.timestamp;
emit PriceUpdated(oldPrice, assetPrice, block.timestamp);
}
/**
* @notice 累积收益并更新价格
* @dev 当从收益策略中收到新收益时调用
*/
function updateYield(uint256 _newYield) external onlyPriceUpdater {
if (_newYield == 0) revert InvalidYield();
accumulatedYield += _newYield;
emit YieldAccumulated(_newYield, block.timestamp);
// 收益更新后立即更新价格
if (block.timestamp >= lastPriceUpdate + minUpdateInterval) {
uint256 oldPrice = assetPrice;
uint256 supply = totalSupply();
if (supply > 0) {
uint256 totalValue = totalAssets + accumulatedYield;
uint256 usdcPerToken = totalValue * 1e18 / supply;
assetPrice = usdcPerToken * PRICE_PRECISION / 1e18;
}
lastPriceUpdate = block.timestamp;
emit PriceUpdated(oldPrice, assetPrice, block.timestamp);
}
}
/**
* @notice 存入资产(模拟)
* @dev 实际实现中应该处理真实的USDC存款
*/
function deposit(uint256 _amount) external onlyOwner {
if (_amount == 0) revert InvalidAmount();
totalAssets += _amount;
_mint(msg.sender, _amount);
}
/**
* @notice 提取资产(模拟)
* @dev 实际实现中应该处理真实的USDC提款
*/
function withdraw(uint256 _amount) external onlyOwner {
if (_amount == 0) revert InvalidAmount();
if (totalAssets < _amount) revert InsufficientAssets();
totalAssets -= _amount;
_burn(msg.sender, _amount);
}
/**
* @notice 获取当前价格信息
*/
function getPriceInfo() external view returns (
uint256 price,
uint256 lastUpdate,
uint256 timeSinceUpdate,
uint256 totalVal
) {
price = assetPrice;
lastUpdate = lastPriceUpdate;
timeSinceUpdate = block.timestamp - lastPriceUpdate;
totalVal = totalAssets + accumulatedYield;
}
}

12
deployments-lending.json Normal file
View File

@@ -0,0 +1,12 @@
{
"421614": {
"lendingFactory": "0x7f103156778058aEEDa9d65c5Dd5d6eB7E73fC74",
"configuratorProxy": "0x050ACf48e82d3688A93180082f7adeA015d78892",
"configuratorImpl": "0x12F6b84017E70C85Bf9EF2CEF320BccFd7E7314B",
"lendingImpl": "0x9a84efc5BFd82cC3A6B24BE00DF2FD4716C51A87",
"timestamp": "2025-12-22T06:07:41.196Z",
"deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
"lendingProxy": "0x6D12F383d58Fb05f00799dEB5742CC0EF28Cf038",
"configTimestamp": "2025-12-22T06:11:34.649Z"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"abi":[{"type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"type":"function","name":"getPrice","inputs":[],"outputs":[{"name":"price","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"decimals()":"313ce567","getPrice()":"98d5fdca"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"decimals()\":{\"returns\":{\"_0\":\"\\u4ef7\\u683c\\u5c0f\\u6570\\u4f4d\\u6570\"}},\"getPrice()\":{\"returns\":{\"price\":\"\\u4ef7\\u683c (scaled by 1e8)\"}}},\"title\":\"IPriceFeed\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"decimals()\":{\"notice\":\"\\u83b7\\u53d6\\u4ef7\\u683c\\u7cbe\\u5ea6\"},\"getPrice()\":{\"notice\":\"\\u83b7\\u53d6\\u8d44\\u4ea7\\u4ef7\\u683c\"}},\"notice\":\"\\u4ef7\\u683c\\u9884\\u8a00\\u673a\\u63a5\\u53e3\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ytLending/interfaces/IPriceFeed.sol\":\"IPriceFeed\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@ensdomains/=node_modules/@ensdomains/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\"],\"viaIR\":true},\"sources\":{\"contracts/ytLending/interfaces/IPriceFeed.sol\":{\"keccak256\":\"0x7bbeeba520a889f4700e09e5287bff93670da68391f1fd8990d9f166c9d9ef8a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://70c00d129acc01ee6a7f4c265b58447a3cc57ebecc47013abdbca506ab1e4444\",\"dweb:/ipfs/QmNq6vLXpSrZSE3JKb22nExAJSDyq98q4hLqxzSFT6QgUu\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"view","type":"function","name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getPrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}]}],"devdoc":{"kind":"dev","methods":{"decimals()":{"returns":{"_0":"价格小数位数"}},"getPrice()":{"returns":{"price":"价格 (scaled by 1e8)"}}},"version":1},"userdoc":{"kind":"user","methods":{"decimals()":{"notice":"获取价格精度"},"getPrice()":{"notice":"获取资产价格"}},"version":1}},"settings":{"remappings":["@ensdomains/=node_modules/@ensdomains/","@openzeppelin/=node_modules/@openzeppelin/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"contracts/ytLending/interfaces/IPriceFeed.sol":"IPriceFeed"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"contracts/ytLending/interfaces/IPriceFeed.sol":{"keccak256":"0x7bbeeba520a889f4700e09e5287bff93670da68391f1fd8990d9f166c9d9ef8a","urls":["bzz-raw://70c00d129acc01ee6a7f4c265b58447a3cc57ebecc47013abdbca506ab1e4444","dweb:/ipfs/QmNq6vLXpSrZSE3JKb22nExAJSDyq98q4hLqxzSFT6QgUu"],"license":"MIT"}},"version":1},"id":16}
{"abi":[{"type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint8","internalType":"uint8"}],"stateMutability":"view"},{"type":"function","name":"getPrice","inputs":[],"outputs":[{"name":"price","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"decimals()":"313ce567","getPrice()":"98d5fdca"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"price\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"title\":\"IPriceFeed\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"\\u4ef7\\u683c\\u9884\\u8a00\\u673a\\u63a5\\u53e3\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/ytLending/interfaces/IPriceFeed.sol\":\"IPriceFeed\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@ensdomains/=node_modules/@ensdomains/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\"],\"viaIR\":true},\"sources\":{\"contracts/ytLending/interfaces/IPriceFeed.sol\":{\"keccak256\":\"0x70d3c43bb10de1881f27e2ae4cfdc7d9fe88b49bff734a570c01c8f40a75ede8\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ce0ae7615d33b4d3af325a392b862dcc8a5136b89b674c9bb9c1f644390d67b4\",\"dweb:/ipfs/QmWAbyrMQkF4e8YMRA8JUnBbHcgwPLXjBJjTdfXQ2ekJPm\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"view","type":"function","name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"getPrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}]}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@ensdomains/=node_modules/@ensdomains/","@openzeppelin/=node_modules/@openzeppelin/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"contracts/ytLending/interfaces/IPriceFeed.sol":"IPriceFeed"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"contracts/ytLending/interfaces/IPriceFeed.sol":{"keccak256":"0x70d3c43bb10de1881f27e2ae4cfdc7d9fe88b49bff734a570c01c8f40a75ede8","urls":["bzz-raw://ce0ae7615d33b4d3af325a392b862dcc8a5136b89b674c9bb9c1f644390d67b4","dweb:/ipfs/QmWAbyrMQkF4e8YMRA8JUnBbHcgwPLXjBJjTdfXQ2ekJPm"],"license":"MIT"}},"version":1},"id":8}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"id":"5c8609e4d5730c4a","source_id_to_path":{"0":"contracts/ytLending/Configurator.sol","1":"contracts/ytLending/ConfiguratorStorage.sol","2":"contracts/ytLending/Lending.sol","3":"contracts/ytLending/LendingConfiguration.sol","4":"contracts/ytLending/LendingFactory.sol","5":"contracts/ytLending/LendingMath.sol","6":"contracts/ytLending/LendingStorage.sol","7":"contracts/ytLending/interfaces/ILending.sol","8":"contracts/ytLending/interfaces/IPriceFeed.sol","9":"lib/forge-std/src/Base.sol","10":"lib/forge-std/src/StdAssertions.sol","11":"lib/forge-std/src/StdChains.sol","12":"lib/forge-std/src/StdCheats.sol","13":"lib/forge-std/src/StdConstants.sol","14":"lib/forge-std/src/StdError.sol","15":"lib/forge-std/src/StdInvariant.sol","16":"lib/forge-std/src/StdJson.sol","17":"lib/forge-std/src/StdMath.sol","18":"lib/forge-std/src/StdStorage.sol","19":"lib/forge-std/src/StdStyle.sol","20":"lib/forge-std/src/StdToml.sol","21":"lib/forge-std/src/StdUtils.sol","22":"lib/forge-std/src/Test.sol","23":"lib/forge-std/src/Vm.sol","24":"lib/forge-std/src/console.sol","25":"lib/forge-std/src/console2.sol","26":"lib/forge-std/src/interfaces/IMulticall3.sol","27":"lib/forge-std/src/safeconsole.sol","28":"node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol","29":"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol","30":"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol","31":"node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol","32":"node_modules/@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol","33":"node_modules/@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol","34":"node_modules/@openzeppelin/contracts/access/Ownable.sol","35":"node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol","36":"node_modules/@openzeppelin/contracts/interfaces/IERC165.sol","37":"node_modules/@openzeppelin/contracts/interfaces/IERC1967.sol","38":"node_modules/@openzeppelin/contracts/interfaces/IERC20.sol","39":"node_modules/@openzeppelin/contracts/interfaces/draft-IERC1822.sol","40":"node_modules/@openzeppelin/contracts/interfaces/draft-IERC6093.sol","41":"node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol","42":"node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol","43":"node_modules/@openzeppelin/contracts/proxy/Proxy.sol","44":"node_modules/@openzeppelin/contracts/proxy/beacon/IBeacon.sol","45":"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol","46":"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol","47":"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol","48":"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol","49":"node_modules/@openzeppelin/contracts/utils/Address.sol","50":"node_modules/@openzeppelin/contracts/utils/Context.sol","51":"node_modules/@openzeppelin/contracts/utils/Errors.sol","52":"node_modules/@openzeppelin/contracts/utils/StorageSlot.sol","53":"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol","54":"test/YtLending.t.sol"},"language":"Solidity"}
{"id":"6fdd3cdda74c78f6","source_id_to_path":{"0":"contracts/ytLending/Configurator.sol","1":"contracts/ytLending/ConfiguratorStorage.sol","2":"contracts/ytLending/Lending.sol","3":"contracts/ytLending/LendingConfiguration.sol","4":"contracts/ytLending/LendingFactory.sol","5":"contracts/ytLending/LendingMath.sol","6":"contracts/ytLending/LendingStorage.sol","7":"contracts/ytLending/interfaces/ILending.sol","8":"contracts/ytLending/interfaces/IPriceFeed.sol","9":"lib/forge-std/src/Base.sol","10":"lib/forge-std/src/StdAssertions.sol","11":"lib/forge-std/src/StdChains.sol","12":"lib/forge-std/src/StdCheats.sol","13":"lib/forge-std/src/StdConstants.sol","14":"lib/forge-std/src/StdError.sol","15":"lib/forge-std/src/StdInvariant.sol","16":"lib/forge-std/src/StdJson.sol","17":"lib/forge-std/src/StdMath.sol","18":"lib/forge-std/src/StdStorage.sol","19":"lib/forge-std/src/StdStyle.sol","20":"lib/forge-std/src/StdToml.sol","21":"lib/forge-std/src/StdUtils.sol","22":"lib/forge-std/src/Test.sol","23":"lib/forge-std/src/Vm.sol","24":"lib/forge-std/src/console.sol","25":"lib/forge-std/src/console2.sol","26":"lib/forge-std/src/interfaces/IMulticall3.sol","27":"lib/forge-std/src/safeconsole.sol","28":"node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol","29":"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol","30":"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol","31":"node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol","32":"node_modules/@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol","33":"node_modules/@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol","34":"node_modules/@openzeppelin/contracts/access/Ownable.sol","35":"node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol","36":"node_modules/@openzeppelin/contracts/interfaces/IERC165.sol","37":"node_modules/@openzeppelin/contracts/interfaces/IERC1967.sol","38":"node_modules/@openzeppelin/contracts/interfaces/IERC20.sol","39":"node_modules/@openzeppelin/contracts/interfaces/draft-IERC1822.sol","40":"node_modules/@openzeppelin/contracts/interfaces/draft-IERC6093.sol","41":"node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol","42":"node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol","43":"node_modules/@openzeppelin/contracts/proxy/Proxy.sol","44":"node_modules/@openzeppelin/contracts/proxy/beacon/IBeacon.sol","45":"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol","46":"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol","47":"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol","48":"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol","49":"node_modules/@openzeppelin/contracts/utils/Address.sol","50":"node_modules/@openzeppelin/contracts/utils/Context.sol","51":"node_modules/@openzeppelin/contracts/utils/Errors.sol","52":"node_modules/@openzeppelin/contracts/utils/StorageSlot.sol","53":"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol","54":"test/YtLending.t.sol"},"language":"Solidity"}

View File

@@ -0,0 +1 @@
{"id":"e5b0a4d0cf09ca18","source_id_to_path":{"0":"contracts/ytLending/Configurator.sol","1":"contracts/ytLending/ConfiguratorStorage.sol","2":"contracts/ytLending/Lending.sol","3":"contracts/ytLending/LendingConfiguration.sol","4":"contracts/ytLending/LendingFactory.sol","5":"contracts/ytLending/LendingMath.sol","6":"contracts/ytLending/LendingStorage.sol","7":"contracts/ytLending/interfaces/ILending.sol","8":"contracts/ytLending/interfaces/IPriceFeed.sol","9":"lib/forge-std/src/Base.sol","10":"lib/forge-std/src/StdAssertions.sol","11":"lib/forge-std/src/StdChains.sol","12":"lib/forge-std/src/StdCheats.sol","13":"lib/forge-std/src/StdConstants.sol","14":"lib/forge-std/src/StdError.sol","15":"lib/forge-std/src/StdInvariant.sol","16":"lib/forge-std/src/StdJson.sol","17":"lib/forge-std/src/StdMath.sol","18":"lib/forge-std/src/StdStorage.sol","19":"lib/forge-std/src/StdStyle.sol","20":"lib/forge-std/src/StdToml.sol","21":"lib/forge-std/src/StdUtils.sol","22":"lib/forge-std/src/Test.sol","23":"lib/forge-std/src/Vm.sol","24":"lib/forge-std/src/console.sol","25":"lib/forge-std/src/console2.sol","26":"lib/forge-std/src/interfaces/IMulticall3.sol","27":"lib/forge-std/src/safeconsole.sol","28":"node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol","29":"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol","30":"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol","31":"node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol","32":"node_modules/@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol","33":"node_modules/@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol","34":"node_modules/@openzeppelin/contracts/access/Ownable.sol","35":"node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol","36":"node_modules/@openzeppelin/contracts/interfaces/IERC165.sol","37":"node_modules/@openzeppelin/contracts/interfaces/IERC1967.sol","38":"node_modules/@openzeppelin/contracts/interfaces/IERC20.sol","39":"node_modules/@openzeppelin/contracts/interfaces/draft-IERC1822.sol","40":"node_modules/@openzeppelin/contracts/interfaces/draft-IERC6093.sol","41":"node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol","42":"node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol","43":"node_modules/@openzeppelin/contracts/proxy/Proxy.sol","44":"node_modules/@openzeppelin/contracts/proxy/beacon/IBeacon.sol","45":"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol","46":"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol","47":"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol","48":"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol","49":"node_modules/@openzeppelin/contracts/utils/Address.sol","50":"node_modules/@openzeppelin/contracts/utils/Context.sol","51":"node_modules/@openzeppelin/contracts/utils/Errors.sol","52":"node_modules/@openzeppelin/contracts/utils/StorageSlot.sol","53":"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol","54":"test/YtLending.t.sol"},"language":"Solidity"}

View File

@@ -0,0 +1 @@
{"id":"f44be44b92a828cb","source_id_to_path":{"0":"contracts/ytLending/Configurator.sol","1":"contracts/ytLending/ConfiguratorStorage.sol","2":"contracts/ytLending/Lending.sol","3":"contracts/ytLending/LendingConfiguration.sol","4":"contracts/ytLending/LendingFactory.sol","5":"contracts/ytLending/LendingMath.sol","6":"contracts/ytLending/LendingStorage.sol","7":"contracts/ytLending/interfaces/ILending.sol","8":"contracts/ytLending/interfaces/IPriceFeed.sol","9":"lib/forge-std/src/Base.sol","10":"lib/forge-std/src/StdAssertions.sol","11":"lib/forge-std/src/StdChains.sol","12":"lib/forge-std/src/StdCheats.sol","13":"lib/forge-std/src/StdConstants.sol","14":"lib/forge-std/src/StdError.sol","15":"lib/forge-std/src/StdInvariant.sol","16":"lib/forge-std/src/StdJson.sol","17":"lib/forge-std/src/StdMath.sol","18":"lib/forge-std/src/StdStorage.sol","19":"lib/forge-std/src/StdStyle.sol","20":"lib/forge-std/src/StdToml.sol","21":"lib/forge-std/src/StdUtils.sol","22":"lib/forge-std/src/Test.sol","23":"lib/forge-std/src/Vm.sol","24":"lib/forge-std/src/console.sol","25":"lib/forge-std/src/console2.sol","26":"lib/forge-std/src/interfaces/IMulticall3.sol","27":"lib/forge-std/src/safeconsole.sol","28":"node_modules/@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol","29":"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol","30":"node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol","31":"node_modules/@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol","32":"node_modules/@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol","33":"node_modules/@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol","34":"node_modules/@openzeppelin/contracts/access/Ownable.sol","35":"node_modules/@openzeppelin/contracts/interfaces/IERC1363.sol","36":"node_modules/@openzeppelin/contracts/interfaces/IERC165.sol","37":"node_modules/@openzeppelin/contracts/interfaces/IERC1967.sol","38":"node_modules/@openzeppelin/contracts/interfaces/IERC20.sol","39":"node_modules/@openzeppelin/contracts/interfaces/draft-IERC1822.sol","40":"node_modules/@openzeppelin/contracts/interfaces/draft-IERC6093.sol","41":"node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol","42":"node_modules/@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol","43":"node_modules/@openzeppelin/contracts/proxy/Proxy.sol","44":"node_modules/@openzeppelin/contracts/proxy/beacon/IBeacon.sol","45":"node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol","46":"node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol","47":"node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol","48":"node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol","49":"node_modules/@openzeppelin/contracts/utils/Address.sol","50":"node_modules/@openzeppelin/contracts/utils/Context.sol","51":"node_modules/@openzeppelin/contracts/utils/Errors.sol","52":"node_modules/@openzeppelin/contracts/utils/StorageSlot.sol","53":"node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol","54":"test/YtLending.t.sol"},"language":"Solidity"}

View File

@@ -92,7 +92,7 @@ async function main() {
existingDeployments[chainId] = {
...existingDeployments[chainId],
...deployments,
timestamp: new Date().toISOString(),
deployTimestamp: new Date().toISOString(),
deployer: deployer.address
};

View File

@@ -33,26 +33,21 @@ async function main() {
console.log(" Lending Impl:", deployments.lendingImpl, "\n");
const configurator = await ethers.getContractAt("Configurator", deployments.configuratorProxy);
const lendingFactory = await ethers.getContractAt("LendingFactory", deployments.lendingFactory);
// ========== 第一阶段:配置外部代币和价格源 ==========
console.log("⚙️ Phase 1: 配置外部代币和价格源");
// 这里使用示例地址,实际部署时需要替换为真实地址
// 如果你已有 WUSD 等合约,请从部署文件中读取
const USDC = {
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // Mainnet USDC (示例)
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
decimals: 6
};
const WETH = {
address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // Mainnet WETH (示例)
address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
decimals: 18
};
// 价格预言机地址(需要部署或使用 Chainlink
const usdcPriceFeed = "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6"; // Chainlink USDC/USD (示例)
const ethPriceFeed = "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419"; // Chainlink ETH/USD (示例)
const usdcPriceFeed = "0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6";
const ethPriceFeed = "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419";
console.log(" 基础资产 (USDC):", USDC.address);
console.log(" 抵押资产 (WETH):", WETH.address);
@@ -141,23 +136,6 @@ async function main() {
const lendingImplAddress = await upgrades.erc1967.getImplementationAddress(lendingProxyAddress);
console.log(" ✅ Lending Implementation (验证):", lendingImplAddress, "\n");
// ========== 第五阶段:验证部署 ==========
console.log("✨ Phase 5: 验证部署");
console.log(" Lending Owner:", await lending.owner());
console.log(" Lending Paused:", await lending.paused());
console.log(" Base Token:", await lending.baseToken());
console.log(" Total Supply:", ethers.formatUnits(await lending.totalSupply(), USDC.decimals));
console.log(" Total Borrow:", ethers.formatUnits(await lending.totalBorrow(), USDC.decimals));
const supplyRate = await lending.getSupplyRate();
const borrowRate = await lending.getBorrowRate();
// 注意:返回的是每秒利率,需要乘以一年的秒数得到 APY
const SECONDS_PER_YEAR = 365 * 24 * 60 * 60;
console.log(" Supply Rate (per second):", ethers.formatUnits(supplyRate, 18));
console.log(" Supply APY:", ethers.formatUnits(BigInt(supplyRate) * BigInt(SECONDS_PER_YEAR), 18));
console.log(" Borrow Rate (per second):", ethers.formatUnits(borrowRate, 18));
console.log(" Borrow APY:", ethers.formatUnits(BigInt(borrowRate) * BigInt(SECONDS_PER_YEAR), 18), "\n");
// ========== 保存部署信息 ==========
deployments.lendingProxy = lendingProxyAddress;
deployments.configTimestamp = new Date().toISOString();
@@ -178,14 +156,6 @@ async function main() {
console.log("Borrow Kink: ", "80%");
console.log("Min Borrow: ", "100 USDC");
console.log("=====================================\n");
console.log("✅ Lending 借贷池已完全配置完成!");
console.log("📝 后续步骤:");
console.log(" 1. 用户可以调用 supply() 存入 USDC");
console.log(" 2. 用户可以调用 supplyCollateral() 存入 WETH");
console.log(" 3. 用户可以调用 borrow() 借出 USDC");
console.log(" 4. 清算人可以调用 absorb() 清算不良贷款");
console.log(" 5. 清算人可以调用 buyCollateral() 购买清算抵押品\n");
}
main()

View File

@@ -177,7 +177,7 @@ contract YtLendingTest is Test {
vm.stopPrank();
// 验证余额
assertEq(lending.balanceOf(alice), 10000e18, "Alice balance should be 10,000 USDC");
assertEq(lending.supplyBalanceOf(alice), 10000e18, "Alice balance should be 10,000 USDC");
assertEq(lending.getTotalSupply(), 10000e18, "Total supply should be 10,000 USDC");
// 验证 principal初始时 index=1所以 principal=balance
@@ -195,8 +195,8 @@ contract YtLendingTest is Test {
lending.supply(5000e18);
// 验证
assertEq(lending.balanceOf(alice), 10000e18, "Alice balance");
assertEq(lending.balanceOf(bob), 5000e18, "Bob balance");
assertEq(lending.supplyBalanceOf(alice), 10000e18, "Alice balance");
assertEq(lending.supplyBalanceOf(bob), 5000e18, "Bob balance");
assertEq(lending.getTotalSupply(), 15000e18, "Total supply should be 15,000 USDC");
}
@@ -213,7 +213,7 @@ contract YtLendingTest is Test {
vm.prank(alice);
lending.withdraw(10000e18);
assertEq(lending.balanceOf(alice), 0, "Alice balance should be 0");
assertEq(lending.supplyBalanceOf(alice), 0, "Alice balance should be 0");
assertEq(lending.getTotalSupply(), 0, "Total supply should be 0");
}
@@ -226,7 +226,7 @@ contract YtLendingTest is Test {
vm.prank(alice);
lending.withdraw(3000e18);
assertEq(lending.balanceOf(alice), 7000e18, "Alice balance should be 7,000 USDC");
assertEq(lending.supplyBalanceOf(alice), 7000e18, "Alice balance should be 7,000 USDC");
assertEq(lending.getTotalSupply(), 7000e18, "Total supply should be 7,000 USDC");
}
@@ -325,7 +325,7 @@ contract YtLendingTest is Test {
// rate = base + (utilization × slope)
// = 0% + (80% × 3%) = 2.4%
// 预期余额 = 10,000 × 1.024 = 10,240 USDC
uint256 aliceBalance = lending.balanceOf(alice);
uint256 aliceBalance = lending.supplyBalanceOf(alice);
assertApproxEqRel(aliceBalance, 10240e18, 0.001e18, "Alice should earn 2.4% interest (0.1% tolerance)");
// Borrow APY 计算:
@@ -360,7 +360,7 @@ contract YtLendingTest is Test {
// 验证复利效果(按秒计算的利息应该增长余额)
// Alice 占总存款的 1/3 (10k / 30k),所以获得约 1/3 的供应利息
// 利用率 = 8k / 30k ≈ 27%,供应利率较低
uint256 aliceBalance = lending.balanceOf(alice);
uint256 aliceBalance = lending.supplyBalanceOf(alice);
assertTrue(aliceBalance > 10000e18, "Compound interest should grow balance");
}
@@ -482,7 +482,7 @@ contract YtLendingTest is Test {
// 抵押品价值(打折后)= 17,500 * 0.95 = 16,625
// 可以覆盖 16,000 债务,还剩 625
assertTrue(lending.balanceOf(bob) > 0, "Bob should have positive balance from excess collateral");
assertTrue(lending.supplyBalanceOf(bob) > 0, "Bob should have positive balance from excess collateral");
}
function test_16_AbsorbMultiple_Batch() public {
@@ -886,7 +886,7 @@ contract YtLendingTest is Test {
lending.accrueInterest();
// 5. 验证利息累积
uint256 aliceBalance = lending.balanceOf(alice);
uint256 aliceBalance = lending.supplyBalanceOf(alice);
assertTrue(aliceBalance > 50000e18, "Alice should earn interest");
uint256 bobDebt = lending.borrowBalanceOf(bob);