From 41717445a9979cf4d7aa34b9dff081c433389a6a Mon Sep 17 00:00:00 2001 From: Debugger022 Date: Tue, 20 Jan 2026 18:14:25 +0530 Subject: [PATCH 1/2] feat: add vip and simulations for bsctestnet --- simulations/vip-800/abi/Comptroller.json | 4145 ++++++++++++++++++++++ simulations/vip-800/bsctestnet-2.ts | 117 + simulations/vip-800/bsctestnet.ts | 97 + vips/vip-800/bsctestnet-2.ts | 171 + vips/vip-800/bsctestnet.ts | 260 ++ 5 files changed, 4790 insertions(+) create mode 100644 simulations/vip-800/abi/Comptroller.json create mode 100644 simulations/vip-800/bsctestnet-2.ts create mode 100644 simulations/vip-800/bsctestnet.ts create mode 100644 vips/vip-800/bsctestnet-2.ts create mode 100644 vips/vip-800/bsctestnet.ts diff --git a/simulations/vip-800/abi/Comptroller.json b/simulations/vip-800/abi/Comptroller.json new file mode 100644 index 000000000..5ca3a7000 --- /dev/null +++ b/simulations/vip-800/abi/Comptroller.json @@ -0,0 +1,4145 @@ +[ + { + "inputs": [], + "name": "AlreadyInSelectedPool", + "type": "error" + }, + { + "inputs": [], + "name": "ArrayLengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "BorrowNotAllowedInPool", + "type": "error" + }, + { + "inputs": [], + "name": "EmptyPoolLabel", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + } + ], + "name": "InactivePool", + "type": "error" + }, + { + "inputs": [], + "name": "IncompatibleBorrowedAssets", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidOperationForCorePool", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "enum WeightFunction", + "name": "strategy", + "type": "uint8" + } + ], + "name": "InvalidWeightingStrategy", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "shortfall", + "type": "uint256" + } + ], + "name": "LiquidityCheckFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketAlreadyListed", + "type": "error" + }, + { + "inputs": [], + "name": "MarketConfigNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "MarketNotListedInCorePool", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + } + ], + "name": "PoolDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "PoolMarketNotFound", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "enum Action", + "name": "action", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "bool", + "name": "pauseState", + "type": "bool" + } + ], + "name": "ActionPausedMarket", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "ActionProtocolPaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "oldStatus", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "newStatus", + "type": "bool" + } + ], + "name": "BorrowAllowedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "approver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "DelegateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "indexed": false, + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "_diamondCut", + "type": "tuple[]" + } + ], + "name": "DiamondCut", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "venusDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "venusBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerVenus", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "supplier", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "venusDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "venusSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierVenus", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "DistributedVAIVaultVenus", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "detail", + "type": "uint256" + } + ], + "name": "Failure", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "enable", + "type": "bool" + } + ], + "name": "IsForcedLiquidationEnabledForUserUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "enable", + "type": "bool" + } + ], + "name": "IsForcedLiquidationEnabledUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketEntered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "MarketExited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketListed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketUnlisted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlAddress", + "type": "address" + } + ], + "name": "NewAccessControl", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBorrowCap", + "type": "uint256" + } + ], + "name": "NewBorrowCap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldCloseFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCloseFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCollateralFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + } + ], + "name": "NewCollateralFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldComptrollerLens", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newComptrollerLens", + "type": "address" + } + ], + "name": "NewComptrollerLens", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationIncentiveMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationIncentive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldLiquidationThresholdMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLiquidationThresholdMantissa", + "type": "uint256" + } + ], + "name": "NewLiquidationThreshold", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldLiquidatorContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newLiquidatorContract", + "type": "address" + } + ], + "name": "NewLiquidatorContract", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldPauseGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "NewPauseGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ResilientOracleInterface", + "name": "oldPriceOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract ResilientOracleInterface", + "name": "newPriceOracle", + "type": "address" + } + ], + "name": "NewPriceOracle", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract IPrime", + "name": "oldPrimeToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract IPrime", + "name": "newPrimeToken", + "type": "address" + } + ], + "name": "NewPrimeToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSupplyCap", + "type": "uint256" + } + ], + "name": "NewSupplyCap", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldTreasuryAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newTreasuryAddress", + "type": "address" + } + ], + "name": "NewTreasuryAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldTreasuryGuardian", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newTreasuryGuardian", + "type": "address" + } + ], + "name": "NewTreasuryGuardian", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldTreasuryPercent", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTreasuryPercent", + "type": "uint256" + } + ], + "name": "NewTreasuryPercent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract VAIControllerInterface", + "name": "oldVAIController", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract VAIControllerInterface", + "name": "newVAIController", + "type": "address" + } + ], + "name": "NewVAIController", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldVAIMintRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newVAIMintRate", + "type": "uint256" + } + ], + "name": "NewVAIMintRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vault_", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "releaseStartBlock_", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "releaseInterval_", + "type": "uint256" + } + ], + "name": "NewVAIVaultInfo", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldVenusVAIVaultRate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newVenusVAIVaultRate", + "type": "uint256" + } + ], + "name": "NewVenusVAIVaultRate", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldXVS", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newXVS", + "type": "address" + } + ], + "name": "NewXVSToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldXVSVToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newXVSVToken", + "type": "address" + } + ], + "name": "NewXVSVToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "bool", + "name": "oldStatus", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "newStatus", + "type": "bool" + } + ], + "name": "PoolActiveStatusUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "string", + "name": "label", + "type": "string" + } + ], + "name": "PoolCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "bool", + "name": "oldStatus", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "newStatus", + "type": "bool" + } + ], + "name": "PoolFallbackStatusUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "string", + "name": "oldLabel", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "newLabel", + "type": "string" + } + ], + "name": "PoolLabelUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "indexed": true, + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "PoolMarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "PoolMarketRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "previousPoolId", + "type": "uint96" + }, + { + "indexed": true, + "internalType": "uint96", + "name": "newPoolId", + "type": "uint96" + } + ], + "name": "PoolSelected", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "VenusBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "VenusGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "VenusSeized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "VenusSupplySpeedUpdated", + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "fallback" + }, + { + "inputs": [ + { + "internalType": "contract Unitroller", + "name": "unitroller", + "type": "address" + } + ], + "name": "_become", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "_grantXVS", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAccessControlAddress", + "type": "address" + } + ], + "name": "_setAccessControl", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "markets_", + "type": "address[]" + }, + { + "internalType": "enum Action[]", + "name": "actions_", + "type": "uint8[]" + }, + { + "internalType": "bool", + "name": "paused_", + "type": "bool" + } + ], + "name": "_setActionsPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "_setCloseFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ComptrollerLensInterface", + "name": "comptrollerLens_", + "type": "address" + } + ], + "name": "_setComptrollerLens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vTokenBorrowed", + "type": "address" + }, + { + "internalType": "bool", + "name": "enable", + "type": "bool" + } + ], + "name": "_setForcedLiquidation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "address", + "name": "vTokenBorrowed", + "type": "address" + }, + { + "internalType": "bool", + "name": "enable", + "type": "bool" + } + ], + "name": "_setForcedLiquidationForUser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newLiquidatorContract_", + "type": "address" + } + ], + "name": "_setLiquidatorContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newBorrowCaps", + "type": "uint256[]" + } + ], + "name": "_setMarketBorrowCaps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newSupplyCaps", + "type": "uint256[]" + } + ], + "name": "_setMarketSupplyCaps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPauseGuardian", + "type": "address" + } + ], + "name": "_setPauseGuardian", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "newOracle", + "type": "address" + } + ], + "name": "_setPriceOracle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IPrime", + "name": "_prime", + "type": "address" + } + ], + "name": "_setPrimeToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "state", + "type": "bool" + } + ], + "name": "_setProtocolPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newTreasuryGuardian", + "type": "address" + }, + { + "internalType": "address", + "name": "newTreasuryAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newTreasuryPercent", + "type": "uint256" + } + ], + "name": "_setTreasuryData", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VAIControllerInterface", + "name": "vaiController_", + "type": "address" + } + ], + "name": "_setVAIController", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newVAIMintRate", + "type": "uint256" + } + ], + "name": "_setVAIMintRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vault_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "releaseStartBlock_", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minReleaseAmount_", + "type": "uint256" + } + ], + "name": "_setVAIVaultInfo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "supplySpeeds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "borrowSpeeds", + "type": "uint256[]" + } + ], + "name": "_setVenusSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "venusVAIVaultRate_", + "type": "uint256" + } + ], + "name": "_setVenusVAIVaultRate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "xvs_", + "type": "address" + } + ], + "name": "_setXVSToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "xvsVToken_", + "type": "address" + } + ], + "name": "_setXVSVToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + } + ], + "name": "_supportMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "accountAssets", + "outputs": [ + { + "internalType": "contract VToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + }, + { + "internalType": "enum Action", + "name": "action", + "type": "uint8" + } + ], + "name": "actionPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96[]", + "name": "poolIds", + "type": "uint96[]" + }, + { + "internalType": "address[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "addPoolMarkets", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "allMarkets", + "outputs": [ + { + "internalType": "contract VToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "approvedDelegates", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "borrowCapGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "borrowCaps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + } + ], + "name": "checkMembership", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "holders", + "type": "address[]" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "borrowers", + "type": "bool" + }, + { + "internalType": "bool", + "name": "suppliers", + "type": "bool" + }, + { + "internalType": "bool", + "name": "collateral", + "type": "bool" + } + ], + "name": "claimVenus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimVenus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimVenus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "holders", + "type": "address[]" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "bool", + "name": "borrowers", + "type": "bool" + }, + { + "internalType": "bool", + "name": "suppliers", + "type": "bool" + } + ], + "name": "claimVenus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimVenusAsCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "closeFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comptrollerLens", + "outputs": [ + { + "internalType": "contract ComptrollerLensInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "corePoolId", + "outputs": [ + { + "internalType": "uint96", + "name": "", + "type": "uint96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "label", + "type": "string" + } + ], + "name": "createPool", + "outputs": [ + { + "internalType": "uint96", + "name": "", + "type": "uint96" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "enum IDiamondCut.FacetCutAction", + "name": "action", + "type": "uint8" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct IDiamondCut.FacetCut[]", + "name": "diamondCut_", + "type": "tuple[]" + } + ], + "name": "diamondCut", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "enterMarkets", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + } + ], + "name": "enterPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vTokenAddress", + "type": "address" + } + ], + "name": "exitMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "functionSelector", + "type": "bytes4" + } + ], + "name": "facetAddress", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "uint96", + "name": "functionSelectorPosition", + "type": "uint96" + } + ], + "internalType": "struct ComptrollerV13Storage.FacetAddressAndPosition", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facetAddresses", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "facet", + "type": "address" + } + ], + "name": "facetFunctionSelectors", + "outputs": [ + { + "internalType": "bytes4[]", + "name": "", + "type": "bytes4[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "facet", + "type": "address" + } + ], + "name": "facetPosition", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "facets", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "facetAddress", + "type": "address" + }, + { + "internalType": "bytes4[]", + "name": "functionSelectors", + "type": "bytes4[]" + } + ], + "internalType": "struct Diamond.Facet[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getAllMarkets", + "outputs": [ + { + "internalType": "contract VToken[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAssetsIn", + "outputs": [ + { + "internalType": "contract VToken[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getBorrowingPower", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getCollateralFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getEffectiveLiquidationIncentive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "enum WeightFunction", + "name": "weightingStrategy", + "type": "uint8" + } + ], + "name": "getEffectiveLtvFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "vTokenModify", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "getHypotheticalAccountLiquidity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getLiquidationIncentive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getLiquidationThreshold", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getPoolMarketIndex", + "outputs": [ + { + "internalType": "PoolMarketId", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + } + ], + "name": "getPoolVTokens", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getXVSAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getXVSVTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint96", + "name": "targetPoolId", + "type": "uint96" + } + ], + "name": "hasValidPoolBorrows", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isComptroller", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "isForcedLiquidationEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "isForcedLiquidationEnabledForUser", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + } + ], + "name": "isMarketListed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastPoolId", + "outputs": [ + { + "internalType": "uint96", + "name": "", + "type": "uint96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "vTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "liquidateBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "vTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "liquidateBorrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "address", + "name": "vTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "vTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "vTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateCalculateSeizeTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vTokenCollateral", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + } + ], + "name": "liquidateVAICalculateSeizeTokens", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidatorContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "markets", + "outputs": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isVenus", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "liquidationThresholdMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationIncentiveMantissa", + "type": "uint256" + }, + { + "internalType": "uint96", + "name": "marketPoolId", + "type": "uint96" + }, + { + "internalType": "bool", + "name": "isBorrowAllowed", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxAssets", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minReleaseAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mintAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "mintVAIGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualMintAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + } + ], + "name": "mintVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "mintedVAIs", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracle", + "outputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pauseGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingComptrollerImplementation", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "poolMarkets", + "outputs": [ + { + "internalType": "bool", + "name": "isListed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "collateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isVenus", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "liquidationThresholdMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "liquidationIncentiveMantissa", + "type": "uint256" + }, + { + "internalType": "uint96", + "name": "marketPoolId", + "type": "uint96" + }, + { + "internalType": "bool", + "name": "isBorrowAllowed", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "", + "type": "uint96" + } + ], + "name": "pools", + "outputs": [ + { + "internalType": "string", + "name": "label", + "type": "string" + }, + { + "internalType": "bool", + "name": "isActive", + "type": "bool" + }, + { + "internalType": "bool", + "name": "allowCorePoolFallback", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "prime", + "outputs": [ + { + "internalType": "contract IPrime", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "redeemer", + "type": "address" + }, + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeemVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "releaseStartBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "removePoolMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "actualRepayAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowerIndex", + "type": "uint256" + } + ], + "name": "repayBorrowVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "repayVAIGuardianPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "vTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "holders", + "type": "address[]" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "seizeVenus", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vTokenCollateral", + "type": "address" + }, + { + "internalType": "address", + "name": "vTokenBorrowed", + "type": "address" + }, + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seizeVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "markets_", + "type": "address[]" + }, + { + "internalType": "enum Action[]", + "name": "actions_", + "type": "uint8[]" + }, + { + "internalType": "bool", + "name": "paused_", + "type": "bool" + } + ], + "name": "setActionsPaused", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "internalType": "bool", + "name": "allowFallback", + "type": "bool" + } + ], + "name": "setAllowCorePoolFallback", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newCloseFactorMantissa", + "type": "uint256" + } + ], + "name": "setCloseFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newLiquidationThresholdMantissa", + "type": "uint256" + } + ], + "name": "setCollateralFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newCollateralFactorMantissa", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "newLiquidationThresholdMantissa", + "type": "uint256" + } + ], + "name": "setCollateralFactor", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vTokenBorrowed", + "type": "address" + }, + { + "internalType": "bool", + "name": "enable", + "type": "bool" + } + ], + "name": "setForcedLiquidation", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "bool", + "name": "borrowAllowed", + "type": "bool" + } + ], + "name": "setIsBorrowAllowed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "setLiquidationIncentive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newLiquidationIncentiveMantissa", + "type": "uint256" + } + ], + "name": "setLiquidationIncentive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newBorrowCaps", + "type": "uint256[]" + } + ], + "name": "setMarketBorrowCaps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "newSupplyCaps", + "type": "uint256[]" + } + ], + "name": "setMarketSupplyCaps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "setMintedVAIOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "internalType": "bool", + "name": "active", + "type": "bool" + } + ], + "name": "setPoolActive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + }, + { + "internalType": "string", + "name": "newLabel", + "type": "string" + } + ], + "name": "setPoolLabel", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ResilientOracleInterface", + "name": "newOracle", + "type": "address" + } + ], + "name": "setPriceOracle", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IPrime", + "name": "_prime", + "type": "address" + } + ], + "name": "setPrimeToken", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "supplyCaps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + } + ], + "name": "supportMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferAllowed", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "transferTokens", + "type": "uint256" + } + ], + "name": "transferVerify", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "treasuryAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasuryGuardian", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "treasuryPercent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "market", + "type": "address" + } + ], + "name": "unlistMarket", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "updateDelegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "userPoolId", + "outputs": [ + { + "internalType": "uint96", + "name": "", + "type": "uint96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaiController", + "outputs": [ + { + "internalType": "contract VAIControllerInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaiMintRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vaiVaultAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "venusAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "venusBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "venusBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "venusBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "venusInitialIndex", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "venusSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "venusSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "venusSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "venusVAIVaultRate", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/simulations/vip-800/bsctestnet-2.ts b/simulations/vip-800/bsctestnet-2.ts new file mode 100644 index 000000000..531233162 --- /dev/null +++ b/simulations/vip-800/bsctestnet-2.ts @@ -0,0 +1,117 @@ +import { expect } from "chai"; +import { Contract } from "ethers"; +import { ethers } from "hardhat"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { expectEvents, setMaxStalePeriodInBinanceOracle, setMaxStalePeriodInChainlinkOracle } from "src/utils"; +import { forking, testVip } from "src/vip-framework"; + +import { CORE_MARKETS } from "../../vips/vip-547/bsctestnet"; +import { vip800 } from "../../vips/vip-800/bsctestnet"; +import { EMODE_POOLS, vip800 as vip800Bsctestnet2 } from "../../vips/vip-800/bsctestnet-2"; +import COMPTROLLER_ABI from "./abi/Comptroller.json"; + +const { bsctestnet } = NETWORK_ADDRESSES; + +forking(85524987, async () => { + let comptroller: Contract; + + before(async () => { + const provider = ethers.provider; + comptroller = new ethers.Contract(bsctestnet.UNITROLLER, COMPTROLLER_ABI, provider); + + for (const market of CORE_MARKETS) { + // Call function with default feed = AddressZero (so it fetches from oracle.tokenConfigs) + await setMaxStalePeriodInChainlinkOracle( + NETWORK_ADDRESSES.bsctestnet.CHAINLINK_ORACLE, + market.asset, + ethers.constants.AddressZero, + NETWORK_ADDRESSES.bsctestnet.NORMAL_TIMELOCK, + 315360000, + ); + + await setMaxStalePeriodInChainlinkOracle( + NETWORK_ADDRESSES.bsctestnet.REDSTONE_ORACLE, + market.asset, + ethers.constants.AddressZero, + NETWORK_ADDRESSES.bsctestnet.NORMAL_TIMELOCK, + 315360000, + ); + } + await setMaxStalePeriodInBinanceOracle(NETWORK_ADDRESSES.bsctestnet.BINANCE_ORACLE, "WBETH", 315360000); + await setMaxStalePeriodInBinanceOracle(NETWORK_ADDRESSES.bsctestnet.BINANCE_ORACLE, "TWT", 315360000); + await setMaxStalePeriodInBinanceOracle(NETWORK_ADDRESSES.bsctestnet.BINANCE_ORACLE, "lisUSD", 315360000); + }); + + describe("Pre-VIP behavior", async () => { + it("check new Emode PoolId does not exist", async () => { + expect(await comptroller.lastPoolId()).to.be.lessThan(EMODE_POOLS[EMODE_POOLS.length - 1].id); + }); + }); + + testVip("VIP-800 Part-1", await vip800(), { + callbackAfterExecution: async txResponse => { + await expectEvents( + txResponse, + [COMPTROLLER_ABI], + [ + "NewCollateralFactor", + "NewLiquidationThreshold", + "NewLiquidationIncentive", + "BorrowAllowedUpdated", + "PoolCreated", + "PoolMarketInitialized", + "PoolFallbackStatusUpdated", + ], + [18, 18, 18, 18, 6, 18, 6], + ); + }, + }); + + testVip("VIP-800 Part-2", await vip800Bsctestnet2(), { + callbackAfterExecution: async txResponse => { + await expectEvents( + txResponse, + [COMPTROLLER_ABI], + [ + "NewCollateralFactor", + "NewLiquidationThreshold", + "NewLiquidationIncentive", + "BorrowAllowedUpdated", + "PoolCreated", + "PoolMarketInitialized", + "PoolFallbackStatusUpdated", + ], + [6, 6, 6, 6, 2, 6, 2], + ); + }, + }); + + describe("Post-VIP behavior", async () => { + it("should update lastPoolId to the new pool", async () => { + expect(await comptroller.lastPoolId()).to.equals(EMODE_POOLS[EMODE_POOLS.length - 1].id); + }); + + for (const EMODE_POOL of EMODE_POOLS) { + describe(`Emode Pool ${EMODE_POOL.label}`, async () => { + it("should set the newly created pool as active with correct label", async () => { + const newPool = await comptroller.pools(EMODE_POOL.id); + expect(newPool.label).to.equals(EMODE_POOL.label); + expect(newPool.isActive).to.equals(true); + expect(newPool.allowCorePoolFallback).to.equal(EMODE_POOL.allowCorePoolFallback); + }); + + it("should set the correct risk parameters to all pool markets", async () => { + for (const config of Object.values(EMODE_POOL.marketsConfig)) { + const marketData = await comptroller.poolMarkets(EMODE_POOL.id, config.address); + expect(marketData.marketPoolId).to.be.equal(EMODE_POOL.id); + expect(marketData.isListed).to.be.equal(true); + expect(marketData.collateralFactorMantissa).to.be.equal(config.collateralFactor); + expect(marketData.liquidationThresholdMantissa).to.be.equal(config.liquidationThreshold); + expect(marketData.liquidationIncentiveMantissa).to.be.equal(config.liquidationIncentive); + expect(marketData.isBorrowAllowed).to.be.equal(config.borrowAllowed); + } + }); + }); + } + }); +}); diff --git a/simulations/vip-800/bsctestnet.ts b/simulations/vip-800/bsctestnet.ts new file mode 100644 index 000000000..f9005f952 --- /dev/null +++ b/simulations/vip-800/bsctestnet.ts @@ -0,0 +1,97 @@ +import { expect } from "chai"; +import { Contract } from "ethers"; +import { ethers } from "hardhat"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { expectEvents, setMaxStalePeriodInBinanceOracle, setMaxStalePeriodInChainlinkOracle } from "src/utils"; +import { forking, testVip } from "src/vip-framework"; + +import { CORE_MARKETS } from "../../vips/vip-547/bsctestnet"; +import { EMODE_POOLS, vip800 } from "../../vips/vip-800/bsctestnet"; +import COMPTROLLER_ABI from "./abi/Comptroller.json"; + +const { bsctestnet } = NETWORK_ADDRESSES; + +forking(85516647, async () => { + let comptroller: Contract; + + before(async () => { + const provider = ethers.provider; + comptroller = new ethers.Contract(bsctestnet.UNITROLLER, COMPTROLLER_ABI, provider); + + for (const market of CORE_MARKETS) { + // Call function with default feed = AddressZero (so it fetches from oracle.tokenConfigs) + await setMaxStalePeriodInChainlinkOracle( + NETWORK_ADDRESSES.bsctestnet.CHAINLINK_ORACLE, + market.asset, + ethers.constants.AddressZero, + NETWORK_ADDRESSES.bsctestnet.NORMAL_TIMELOCK, + 3153600000, + ); + + await setMaxStalePeriodInChainlinkOracle( + NETWORK_ADDRESSES.bsctestnet.REDSTONE_ORACLE, + market.asset, + ethers.constants.AddressZero, + NETWORK_ADDRESSES.bsctestnet.NORMAL_TIMELOCK, + 3153600000, + ); + } + await setMaxStalePeriodInBinanceOracle(NETWORK_ADDRESSES.bsctestnet.BINANCE_ORACLE, "WBETH", 3153600000); + await setMaxStalePeriodInBinanceOracle(NETWORK_ADDRESSES.bsctestnet.BINANCE_ORACLE, "TWT", 3153600000); + await setMaxStalePeriodInBinanceOracle(NETWORK_ADDRESSES.bsctestnet.BINANCE_ORACLE, "lisUSD", 3153600000); + }); + + describe("Pre-VIP behavior", async () => { + it("check new Emode PoolId does not exist", async () => { + expect(await comptroller.lastPoolId()).to.be.lessThan(EMODE_POOLS[EMODE_POOLS.length - 1].id); + }); + }); + + testVip("VIP-800", await vip800(), { + callbackAfterExecution: async txResponse => { + await expectEvents( + txResponse, + [COMPTROLLER_ABI], + [ + "NewCollateralFactor", + "NewLiquidationThreshold", + "NewLiquidationIncentive", + "BorrowAllowedUpdated", + "PoolCreated", + "PoolMarketInitialized", + "PoolFallbackStatusUpdated", + ], + [18, 18, 18, 18, 6, 18, 6], + ); + }, + }); + + describe("Post-VIP behavior", async () => { + it("should update lastPoolId to the new pool", async () => { + expect(await comptroller.lastPoolId()).to.equals(EMODE_POOLS[EMODE_POOLS.length - 1].id); + }); + + for (const EMODE_POOL of EMODE_POOLS) { + describe(`Emode Pool ${EMODE_POOL.label}`, async () => { + it("should set the newly created pool as active with correct label", async () => { + const newPool = await comptroller.pools(EMODE_POOL.id); + expect(newPool.label).to.equals(EMODE_POOL.label); + expect(newPool.isActive).to.equals(true); + expect(newPool.allowCorePoolFallback).to.equal(EMODE_POOL.allowCorePoolFallback); + }); + + it("should set the correct risk parameters to all pool markets", async () => { + for (const config of Object.values(EMODE_POOL.marketsConfig)) { + const marketData = await comptroller.poolMarkets(EMODE_POOL.id, config.address); + expect(marketData.marketPoolId).to.be.equal(EMODE_POOL.id); + expect(marketData.isListed).to.be.equal(true); + expect(marketData.collateralFactorMantissa).to.be.equal(config.collateralFactor); + expect(marketData.liquidationThresholdMantissa).to.be.equal(config.liquidationThreshold); + expect(marketData.liquidationIncentiveMantissa).to.be.equal(config.liquidationIncentive); + expect(marketData.isBorrowAllowed).to.be.equal(config.borrowAllowed); + } + }); + }); + } + }); +}); diff --git a/vips/vip-800/bsctestnet-2.ts b/vips/vip-800/bsctestnet-2.ts new file mode 100644 index 000000000..9219212d0 --- /dev/null +++ b/vips/vip-800/bsctestnet-2.ts @@ -0,0 +1,171 @@ +import { parseUnits } from "ethers/lib/utils"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { ProposalType } from "src/types"; +import { makeProposal } from "src/utils"; + +const { bsctestnet } = NETWORK_ADDRESSES; + +// Link, bch, Fil and Dot are not supported on BSC Testnet +export const vUSDT = "0xb7526572FFE56AB9D7489838Bf2E18e3323b441A"; +export const vUSDC = "0xD5C4C2e2facBEB59D0216D0595d63FcDc6F9A1a7"; +export const vMATIC = "0x3619bdDc61189F33365CC572DF3a68FB3b316516"; +export const vTRX = "0x6AF3Fdb3282c5bb6926269Db10837fa8Aec67C04"; +export const vTHE = "0x39A239F5117BFaC7a1b0b3A517c454113323451d"; + +export const EMODE_POOLS = [ + // The vMATIC oracle is returning "invalid resilient oracle price" error currently, so this pool is commented out for now + // { + // label: "MATIC", + // id: 11, + // markets: [vMATIC, vUSDT, vUSDC], + // allowCorePoolFallback: true, + // marketsConfig: { + // vMATIC: { + // address: vMATIC, + // collateralFactor: parseUnits("0.6", 18), + // liquidationThreshold: parseUnits("0.6", 18), + // liquidationIncentive: parseUnits("1.1", 18), + // borrowAllowed: true, + // }, + // vUSDT: { + // address: vUSDT, + // collateralFactor: parseUnits("0.8", 18), + // liquidationThreshold: parseUnits("0.8", 18), + // liquidationIncentive: parseUnits("1.1", 18), + // borrowAllowed: true, + // }, + // vUSDC: { + // address: vUSDC, + // collateralFactor: parseUnits("0.81", 18), + // liquidationThreshold: parseUnits("0.81", 18), + // liquidationIncentive: parseUnits("1.1", 18), + // borrowAllowed: true, + // }, + // }, + // }, + { + label: "TRX", + id: 11, + markets: [vTRX, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vTRX: { + address: vTRX, + collateralFactor: parseUnits("0.6", 18), + liquidationThreshold: parseUnits("0.6", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.81", 18), + liquidationThreshold: parseUnits("0.81", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "THE", + id: 12, + markets: [vTHE, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vTHE: { + address: vTHE, + collateralFactor: parseUnits("0.53", 18), + liquidationThreshold: parseUnits("0.53", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.81", 18), + liquidationThreshold: parseUnits("0.81", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, +]; + +function generateEmodePoolCommands(pool: any) { + const commands = [ + { + target: bsctestnet.UNITROLLER, + signature: "createPool(string)", + params: [pool.label], + }, + { + target: bsctestnet.UNITROLLER, + signature: "setPoolActive(uint96,bool)", + params: [pool.id, true], + }, + { + target: bsctestnet.UNITROLLER, + signature: "addPoolMarkets(uint96[],address[])", + params: [Array(pool.markets.length).fill(pool.id), pool.markets], + }, + { + target: bsctestnet.UNITROLLER, + signature: "setAllowCorePoolFallback(uint96,bool)", + params: [pool.id, pool.allowCorePoolFallback], + }, + ]; + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bsctestnet.UNITROLLER, + signature: "setCollateralFactor(uint96,address,uint256,uint256)", + params: [pool.id, market.address, market.collateralFactor, market.liquidationThreshold], + }); + } + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bsctestnet.UNITROLLER, + signature: "setLiquidationIncentive(uint96,address,uint256)", + params: [pool.id, market.address, market.liquidationIncentive], + }); + } + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bsctestnet.UNITROLLER, + signature: "setIsBorrowAllowed(uint96,address,bool)", + params: [pool.id, market.address, market.borrowAllowed], + }); + } + + return commands; +} + +export const vip800 = () => { + const meta = { + version: "v2", + title: "VIP-800 [BNB Chain] Asset Migration from BNB core pool to isolated Emode pools (TRX, THE)", + description: "VIP-800 [BNB Chain] Asset Migration from BNB core pool to isolated Emode pools (TRX, THE)", + forDescription: "I agree that Venus Protocol should proceed with this proposal", + againstDescription: "I do not think that Venus Protocol should proceed with this proposal", + abstainDescription: "I am indifferent to whether Venus Protocol proceeds or not", + }; + + return makeProposal(EMODE_POOLS.flatMap(generateEmodePoolCommands), meta, ProposalType.REGULAR); +}; diff --git a/vips/vip-800/bsctestnet.ts b/vips/vip-800/bsctestnet.ts new file mode 100644 index 000000000..50b290583 --- /dev/null +++ b/vips/vip-800/bsctestnet.ts @@ -0,0 +1,260 @@ +import { parseUnits } from "ethers/lib/utils"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { ProposalType } from "src/types"; +import { makeProposal } from "src/utils"; + +const { bsctestnet } = NETWORK_ADDRESSES; + +// Link, bch, Fil and Dot are not supported on BSC Testnet +export const vUSDT = "0xb7526572FFE56AB9D7489838Bf2E18e3323b441A"; +export const vUSDC = "0xD5C4C2e2facBEB59D0216D0595d63FcDc6F9A1a7"; +export const vUNI = "0x171B468b52d7027F12cEF90cd065d6776a25E24e"; +export const vAAVE = "0x714db6c38A17883964B68a07d56cE331501d9eb6"; +export const vDOGE = "0xF912d3001CAf6DC4ADD366A62Cc9115B4303c9A9"; +export const vTWT = "0x95DaED37fdD3F557b3A5cCEb7D50Be65b36721DF"; +export const vADA = "0x37C28DE42bA3d22217995D146FC684B2326Ede64"; +export const vLTC = "0xAfc13BC065ABeE838540823431055D2ea52eBA52"; + +export const EMODE_POOLS = [ + { + label: "UNI", + id: 5, + markets: [vUNI, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vUNI: { + address: vUNI, + collateralFactor: parseUnits("0.55", 18), + liquidationThreshold: parseUnits("0.55", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.81", 18), + liquidationThreshold: parseUnits("0.81", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "AAVE", + id: 6, + markets: [vAAVE, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vAAVE: { + address: vAAVE, + collateralFactor: parseUnits("0.55", 18), + liquidationThreshold: parseUnits("0.55", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.81", 18), + liquidationThreshold: parseUnits("0.81", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "DOGE", + id: 7, + markets: [vDOGE, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vDOGE: { + address: vDOGE, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.81", 18), + liquidationThreshold: parseUnits("0.81", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "TWT", + id: 8, + markets: [vTWT, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vTWT: { + address: vTWT, + collateralFactor: parseUnits("0.5", 18), + liquidationThreshold: parseUnits("0.5", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.81", 18), + liquidationThreshold: parseUnits("0.81", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "ADA", + id: 9, + markets: [vADA, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vADA: { + address: vADA, + collateralFactor: parseUnits("0.6", 18), + liquidationThreshold: parseUnits("0.6", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.81", 18), + liquidationThreshold: parseUnits("0.81", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "LTC", + id: 10, + markets: [vLTC, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vLTC: { + address: vLTC, + collateralFactor: parseUnits("0.6", 18), + liquidationThreshold: parseUnits("0.6", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.81", 18), + liquidationThreshold: parseUnits("0.81", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, +]; + +function generateEmodePoolCommands(pool: any) { + const commands = [ + { + target: bsctestnet.UNITROLLER, + signature: "createPool(string)", + params: [pool.label], + }, + { + target: bsctestnet.UNITROLLER, + signature: "setPoolActive(uint96,bool)", + params: [pool.id, true], + }, + { + target: bsctestnet.UNITROLLER, + signature: "addPoolMarkets(uint96[],address[])", + params: [Array(pool.markets.length).fill(pool.id), pool.markets], + }, + { + target: bsctestnet.UNITROLLER, + signature: "setAllowCorePoolFallback(uint96,bool)", + params: [pool.id, pool.allowCorePoolFallback], + }, + ]; + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bsctestnet.UNITROLLER, + signature: "setCollateralFactor(uint96,address,uint256,uint256)", + params: [pool.id, market.address, market.collateralFactor, market.liquidationThreshold], + }); + } + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bsctestnet.UNITROLLER, + signature: "setLiquidationIncentive(uint96,address,uint256)", + params: [pool.id, market.address, market.liquidationIncentive], + }); + } + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bsctestnet.UNITROLLER, + signature: "setIsBorrowAllowed(uint96,address,bool)", + params: [pool.id, market.address, market.borrowAllowed], + }); + } + + return commands; +} + +export const vip800 = () => { + const meta = { + version: "v2", + title: "VIP-800 [BNB Chain] Asset Migration from BNB core pool to isolated Emode pools", + description: "VIP-800 [BNB Chain] Asset Migration from BNB core pool to isolated Emode pools", + forDescription: "I agree that Venus Protocol should proceed with this proposal", + againstDescription: "I do not think that Venus Protocol should proceed with this proposal", + abstainDescription: "I am indifferent to whether Venus Protocol proceeds or not", + }; + + return makeProposal(EMODE_POOLS.flatMap(generateEmodePoolCommands), meta, ProposalType.REGULAR); +}; From 7e2c5a9247aed65c1f672f0cbdef4b9f08964e9f Mon Sep 17 00:00:00 2001 From: Debugger022 Date: Fri, 23 Jan 2026 15:12:36 +0530 Subject: [PATCH 2/2] feat: add vip and simulation for bscmainnet --- simulations/vip-800/bscmainnet-2.ts | 131 +++++++++++++ simulations/vip-800/bscmainnet.ts | 96 +++++++++ src/vip-framework/index.ts | 2 +- vips/vip-800/bscmainnet-2.ts | 259 +++++++++++++++++++++++++ vips/vip-800/bscmainnet.ts | 289 ++++++++++++++++++++++++++++ 5 files changed, 776 insertions(+), 1 deletion(-) create mode 100644 simulations/vip-800/bscmainnet-2.ts create mode 100644 simulations/vip-800/bscmainnet.ts create mode 100644 vips/vip-800/bscmainnet-2.ts create mode 100644 vips/vip-800/bscmainnet.ts diff --git a/simulations/vip-800/bscmainnet-2.ts b/simulations/vip-800/bscmainnet-2.ts new file mode 100644 index 000000000..d73bc517b --- /dev/null +++ b/simulations/vip-800/bscmainnet-2.ts @@ -0,0 +1,131 @@ +import { expect } from "chai"; +import { Contract } from "ethers"; +import { ethers } from "hardhat"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { + expectEvents, + setMaxStalePeriodInBinanceOracle, + setMaxStalePeriodInChainlinkOracle, + setRedstonePrice, +} from "src/utils"; +import { forking, testVip } from "src/vip-framework"; + +import { CORE_MARKETS } from "../../vips/vip-547/bscmainnet"; +import { vip800 } from "../../vips/vip-800/bscmainnet"; +import { EMODE_POOLS, vip800 as vip800_2 } from "../../vips/vip-800/bscmainnet-2"; +import COMPTROLLER_ABI from "./abi/Comptroller.json"; + +const { bscmainnet } = NETWORK_ADDRESSES; + +forking(76766086, async () => { + let comptroller: Contract; + + before(async () => { + const provider = ethers.provider; + comptroller = new ethers.Contract(bscmainnet.UNITROLLER, COMPTROLLER_ABI, provider); + + for (const market of CORE_MARKETS) { + // Call function with default feed = AddressZero (so it fetches from oracle.tokenConfigs) + await setMaxStalePeriodInChainlinkOracle( + bscmainnet.CHAINLINK_ORACLE, + market.underlying, + ethers.constants.AddressZero, + bscmainnet.NORMAL_TIMELOCK, + 3153600000, + ); + + await setMaxStalePeriodInChainlinkOracle( + bscmainnet.REDSTONE_ORACLE, + market.underlying, + ethers.constants.AddressZero, + bscmainnet.NORMAL_TIMELOCK, + 3153600000, + ); + + await setMaxStalePeriodInBinanceOracle(bscmainnet.BINANCE_ORACLE, market.symbol.slice(1), 315360000); + } + + const THE = "0xF4C8E32EaDEC4BFe97E0F595AdD0f4450a863a11"; + const THE_REDSTONE_FEED = "0xFB1267A29C0aa19daae4a483ea895862A69e4AA5"; + await setRedstonePrice(bscmainnet.REDSTONE_ORACLE, THE, THE_REDSTONE_FEED, bscmainnet.NORMAL_TIMELOCK); + + const TRX = "0xCE7de646e7208a4Ef112cb6ed5038FA6cC6b12e3"; + const TRX_REDSTONE_FEED = "0xa17362dd9AD6d0aF646D7C8f8578fddbfc90B916"; + await setRedstonePrice(bscmainnet.REDSTONE_ORACLE, TRX, TRX_REDSTONE_FEED, bscmainnet.NORMAL_TIMELOCK, 3153600000, { + tokenDecimals: 6, + }); + }); + + describe("Pre-VIP behavior", async () => { + it("check new Emode PoolId does not exist", async () => { + expect(await comptroller.lastPoolId()).to.be.lessThan(EMODE_POOLS[EMODE_POOLS.length - 1].id); + }); + }); + + testVip("VIP-800 Part-1", await vip800(), { + callbackAfterExecution: async txResponse => { + await expectEvents( + txResponse, + [COMPTROLLER_ABI], + [ + "NewCollateralFactor", + "NewLiquidationThreshold", + "NewLiquidationIncentive", + "BorrowAllowedUpdated", + "PoolCreated", + "PoolMarketInitialized", + "PoolFallbackStatusUpdated", + ], + [21, 21, 21, 21, 7, 21, 7], + ); + }, + }); + + testVip("VIP-800 Part-2", await vip800_2(), { + callbackAfterExecution: async txResponse => { + await expectEvents( + txResponse, + [COMPTROLLER_ABI], + [ + "NewCollateralFactor", // vMatic has 0 collateral factor, so no event for it + "NewLiquidationThreshold", + "NewLiquidationIncentive", + "BorrowAllowedUpdated", + "PoolCreated", + "PoolMarketInitialized", + "PoolFallbackStatusUpdated", + ], + [17, 18, 18, 18, 6, 18, 6], + ); + }, + }); + + describe("Post-VIP behavior", async () => { + it("should update lastPoolId to the new pool", async () => { + expect(await comptroller.lastPoolId()).to.equals(EMODE_POOLS[EMODE_POOLS.length - 1].id); + }); + + for (const EMODE_POOL of EMODE_POOLS) { + describe(`Emode Pool ${EMODE_POOL.label}`, async () => { + it("should set the newly created pool as active with correct label", async () => { + const newPool = await comptroller.pools(EMODE_POOL.id); + expect(newPool.label).to.equals(EMODE_POOL.label); + expect(newPool.isActive).to.equals(true); + expect(newPool.allowCorePoolFallback).to.equal(EMODE_POOL.allowCorePoolFallback); + }); + + it("should set the correct risk parameters to all pool markets", async () => { + for (const config of Object.values(EMODE_POOL.marketsConfig)) { + const marketData = await comptroller.poolMarkets(EMODE_POOL.id, config.address); + expect(marketData.marketPoolId).to.be.equal(EMODE_POOL.id); + expect(marketData.isListed).to.be.equal(true); + expect(marketData.collateralFactorMantissa).to.be.equal(config.collateralFactor); + expect(marketData.liquidationThresholdMantissa).to.be.equal(config.liquidationThreshold); + expect(marketData.liquidationIncentiveMantissa).to.be.equal(config.liquidationIncentive); + expect(marketData.isBorrowAllowed).to.be.equal(config.borrowAllowed); + } + }); + }); + } + }); +}); diff --git a/simulations/vip-800/bscmainnet.ts b/simulations/vip-800/bscmainnet.ts new file mode 100644 index 000000000..c64be2900 --- /dev/null +++ b/simulations/vip-800/bscmainnet.ts @@ -0,0 +1,96 @@ +import { expect } from "chai"; +import { Contract } from "ethers"; +import { ethers } from "hardhat"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { expectEvents, setMaxStalePeriodInBinanceOracle, setMaxStalePeriodInChainlinkOracle } from "src/utils"; +import { forking, testVip } from "src/vip-framework"; + +import { CORE_MARKETS } from "../../vips/vip-547/bscmainnet"; +import { EMODE_POOLS, vip800 } from "../../vips/vip-800/bscmainnet"; +import COMPTROLLER_ABI from "./abi/Comptroller.json"; + +const { bscmainnet } = NETWORK_ADDRESSES; + +forking(76766086, async () => { + let comptroller: Contract; + + before(async () => { + const provider = ethers.provider; + comptroller = new ethers.Contract(bscmainnet.UNITROLLER, COMPTROLLER_ABI, provider); + + for (const market of CORE_MARKETS) { + // Call function with default feed = AddressZero (so it fetches from oracle.tokenConfigs) + await setMaxStalePeriodInChainlinkOracle( + bscmainnet.CHAINLINK_ORACLE, + market.underlying, + ethers.constants.AddressZero, + bscmainnet.NORMAL_TIMELOCK, + 3153600000, + ); + + await setMaxStalePeriodInChainlinkOracle( + bscmainnet.REDSTONE_ORACLE, + market.underlying, + ethers.constants.AddressZero, + bscmainnet.NORMAL_TIMELOCK, + 3153600000, + ); + + await setMaxStalePeriodInBinanceOracle(bscmainnet.BINANCE_ORACLE, market.symbol.slice(1), 315360000); + } + }); + + describe("Pre-VIP behavior", async () => { + it("check new Emode PoolId does not exist", async () => { + expect(await comptroller.lastPoolId()).to.be.lessThan(EMODE_POOLS[EMODE_POOLS.length - 1].id); + }); + }); + + testVip("VIP-800", await vip800(), { + callbackAfterExecution: async txResponse => { + await expectEvents( + txResponse, + [COMPTROLLER_ABI], + [ + "NewCollateralFactor", + "NewLiquidationThreshold", + "NewLiquidationIncentive", + "BorrowAllowedUpdated", + "PoolCreated", + "PoolMarketInitialized", + "PoolFallbackStatusUpdated", + ], + [21, 21, 21, 21, 7, 21, 7], + ); + }, + }); + + describe("Post-VIP behavior", async () => { + it("should update lastPoolId to the new pool", async () => { + expect(await comptroller.lastPoolId()).to.equals(EMODE_POOLS[EMODE_POOLS.length - 1].id); + }); + + for (const EMODE_POOL of EMODE_POOLS) { + describe(`Emode Pool ${EMODE_POOL.label}`, async () => { + it("should set the newly created pool as active with correct label", async () => { + const newPool = await comptroller.pools(EMODE_POOL.id); + expect(newPool.label).to.equals(EMODE_POOL.label); + expect(newPool.isActive).to.equals(true); + expect(newPool.allowCorePoolFallback).to.equal(EMODE_POOL.allowCorePoolFallback); + }); + + it("should set the correct risk parameters to all pool markets", async () => { + for (const config of Object.values(EMODE_POOL.marketsConfig)) { + const marketData = await comptroller.poolMarkets(EMODE_POOL.id, config.address); + expect(marketData.marketPoolId).to.be.equal(EMODE_POOL.id); + expect(marketData.isListed).to.be.equal(true); + expect(marketData.collateralFactorMantissa).to.be.equal(config.collateralFactor); + expect(marketData.liquidationThresholdMantissa).to.be.equal(config.liquidationThreshold); + expect(marketData.liquidationIncentiveMantissa).to.be.equal(config.liquidationIncentive); + expect(marketData.isBorrowAllowed).to.be.equal(config.borrowAllowed); + } + }); + }); + } + }); +}); diff --git a/src/vip-framework/index.ts b/src/vip-framework/index.ts index de2aa7f1f..5176b2df4 100644 --- a/src/vip-framework/index.ts +++ b/src/vip-framework/index.ts @@ -30,7 +30,7 @@ const OMNICHAIN_PROPOSAL_SENDER = getOmnichainProposalSenderAddress(); const OMNICHAIN_GOVERNANCE_EXECUTOR = NETWORK_ADDRESSES[FORKED_NETWORK as REMOTE_NETWORKS].OMNICHAIN_GOVERNANCE_EXECUTOR; -const VOTING_PERIOD = 115200; +const VOTING_PERIOD = 192384; export const { DEFAULT_PROPOSER_ADDRESS, diff --git a/vips/vip-800/bscmainnet-2.ts b/vips/vip-800/bscmainnet-2.ts new file mode 100644 index 000000000..3be8e7677 --- /dev/null +++ b/vips/vip-800/bscmainnet-2.ts @@ -0,0 +1,259 @@ +import { parseUnits } from "ethers/lib/utils"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { ProposalType } from "src/types"; +import { makeProposal } from "src/utils"; + +const { bscmainnet } = NETWORK_ADDRESSES; + +export const vUSDT = "0xfD5840Cd36d94D7229439859C0112a4185BC0255"; +export const vUSDC = "0xecA88125a5ADbe82614ffC12D0DB554E2e2867C8"; +export const vLTC = "0x57A5297F2cB2c0AaC9D554660acd6D385Ab50c6B"; +export const vFIL = "0xf91d58b5aE142DAcC749f58A49FCBac340Cb0343"; +export const vMATIC = "0x5c9476FcD6a4F9a3654139721c949c2233bBbBc8"; +export const vTRX = "0xC5D3466aA484B040eE977073fcF337f2c00071c1"; +export const vDOT = "0x1610bc33319e9398de5f57B33a5b184c806aD217"; +export const vTHE = "0x86e06EAfa6A1eA631Eab51DE500E3D474933739f"; + +export const EMODE_POOLS = [ + { + label: "LTC", + id: 11, + markets: [vLTC, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vLTC: { + address: vLTC, + collateralFactor: parseUnits("0.63", 18), + liquidationThreshold: parseUnits("0.63", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "FIL", + id: 12, + markets: [vFIL, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vFIL: { + address: vFIL, + collateralFactor: parseUnits("0.63", 18), + liquidationThreshold: parseUnits("0.63", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "MATIC", + id: 13, + markets: [vMATIC, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vMATIC: { + address: vMATIC, + collateralFactor: parseUnits("0", 18), + liquidationThreshold: parseUnits("0.65", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "TRX", + id: 14, + markets: [vTRX, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vTRX: { + address: vTRX, + collateralFactor: parseUnits("0.525", 18), + liquidationThreshold: parseUnits("0.525", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "DOT", + id: 15, + markets: [vDOT, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vDOT: { + address: vDOT, + collateralFactor: parseUnits("0.65", 18), + liquidationThreshold: parseUnits("0.65", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "THE", + id: 16, + markets: [vTHE, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vTHE: { + address: vTHE, + collateralFactor: parseUnits("0.53", 18), + liquidationThreshold: parseUnits("0.53", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, +]; + +function generateEmodePoolCommands(pool: any) { + const commands = [ + { + target: bscmainnet.UNITROLLER, + signature: "createPool(string)", + params: [pool.label], + }, + { + target: bscmainnet.UNITROLLER, + signature: "setPoolActive(uint96,bool)", + params: [pool.id, true], + }, + { + target: bscmainnet.UNITROLLER, + signature: "addPoolMarkets(uint96[],address[])", + params: [Array(pool.markets.length).fill(pool.id), pool.markets], + }, + { + target: bscmainnet.UNITROLLER, + signature: "setAllowCorePoolFallback(uint96,bool)", + params: [pool.id, pool.allowCorePoolFallback], + }, + ]; + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bscmainnet.UNITROLLER, + signature: "setCollateralFactor(uint96,address,uint256,uint256)", + params: [pool.id, market.address, market.collateralFactor, market.liquidationThreshold], + }); + } + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bscmainnet.UNITROLLER, + signature: "setLiquidationIncentive(uint96,address,uint256)", + params: [pool.id, market.address, market.liquidationIncentive], + }); + } + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bscmainnet.UNITROLLER, + signature: "setIsBorrowAllowed(uint96,address,bool)", + params: [pool.id, market.address, market.borrowAllowed], + }); + } + + return commands; +} + +export const vip800 = () => { + const meta = { + version: "v2", + title: "VIP-800 [BNB Chain] Asset Migration from BNB core pool to isolated Emode pools (TRX, THE)", + description: "VIP-800 [BNB Chain] Asset Migration from BNB core pool to isolated Emode pools (TRX, THE)", + forDescription: "I agree that Venus Protocol should proceed with this proposal", + againstDescription: "I do not think that Venus Protocol should proceed with this proposal", + abstainDescription: "I am indifferent to whether Venus Protocol proceeds or not", + }; + + return makeProposal(EMODE_POOLS.flatMap(generateEmodePoolCommands), meta, ProposalType.REGULAR); +}; diff --git a/vips/vip-800/bscmainnet.ts b/vips/vip-800/bscmainnet.ts new file mode 100644 index 000000000..7932db350 --- /dev/null +++ b/vips/vip-800/bscmainnet.ts @@ -0,0 +1,289 @@ +import { parseUnits } from "ethers/lib/utils"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { ProposalType } from "src/types"; +import { makeProposal } from "src/utils"; + +const { bscmainnet } = NETWORK_ADDRESSES; + +export const vUSDT = "0xfD5840Cd36d94D7229439859C0112a4185BC0255"; +export const vUSDC = "0xecA88125a5ADbe82614ffC12D0DB554E2e2867C8"; +export const vLINK = "0x650b940a1033B8A1b1873f78730FcFC73ec11f1f"; +export const vUNI = "0x27FF564707786720C71A2e5c1490A63266683612"; +export const vAAVE = "0x26DA28954763B92139ED49283625ceCAf52C6f94"; +export const vDOGE = "0xec3422Ef92B2fb59e84c8B02Ba73F1fE84Ed8D71"; +export const vBCH = "0x5F0388EBc2B94FA8E123F404b79cCF5f40b29176"; +export const vTWT = "0x4d41a36D04D97785bcEA57b057C412b278e6Edcc"; +export const vADA = "0x9A0AF7FDb2065Ce470D72664DE73cAE409dA28Ec"; + +export const EMODE_POOLS = [ + { + label: "LINK", + id: 4, + markets: [vLINK, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vLINK: { + address: vLINK, + collateralFactor: parseUnits("0.63", 18), + liquidationThreshold: parseUnits("0.63", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "UNI", + id: 5, + markets: [vUNI, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vUNI: { + address: vUNI, + collateralFactor: parseUnits("0.55", 18), + liquidationThreshold: parseUnits("0.55", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "AAVE", + id: 6, + markets: [vAAVE, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vAAVE: { + address: vAAVE, + collateralFactor: parseUnits("0.55", 18), + liquidationThreshold: parseUnits("0.55", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "DOGE", + id: 7, + markets: [vDOGE, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vDOGE: { + address: vDOGE, + collateralFactor: parseUnits("0.43", 18), + liquidationThreshold: parseUnits("0.43", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "BCH", + id: 8, + markets: [vBCH, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vBCH: { + address: vBCH, + collateralFactor: parseUnits("0.6", 18), + liquidationThreshold: parseUnits("0.6", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "TWT", + id: 9, + markets: [vTWT, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vTWT: { + address: vTWT, + collateralFactor: parseUnits("0.5", 18), + liquidationThreshold: parseUnits("0.5", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, + { + label: "ADA", + id: 10, + markets: [vADA, vUSDT, vUSDC], + allowCorePoolFallback: true, + marketsConfig: { + vADA: { + address: vADA, + collateralFactor: parseUnits("0.63", 18), + liquidationThreshold: parseUnits("0.63", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDT: { + address: vUSDT, + collateralFactor: parseUnits("0.8", 18), + liquidationThreshold: parseUnits("0.8", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + vUSDC: { + address: vUSDC, + collateralFactor: parseUnits("0.825", 18), + liquidationThreshold: parseUnits("0.825", 18), + liquidationIncentive: parseUnits("1.1", 18), + borrowAllowed: true, + }, + }, + }, +]; + +function generateEmodePoolCommands(pool: any) { + const commands = [ + { + target: bscmainnet.UNITROLLER, + signature: "createPool(string)", + params: [pool.label], + }, + { + target: bscmainnet.UNITROLLER, + signature: "setPoolActive(uint96,bool)", + params: [pool.id, true], + }, + { + target: bscmainnet.UNITROLLER, + signature: "addPoolMarkets(uint96[],address[])", + params: [Array(pool.markets.length).fill(pool.id), pool.markets], + }, + { + target: bscmainnet.UNITROLLER, + signature: "setAllowCorePoolFallback(uint96,bool)", + params: [pool.id, pool.allowCorePoolFallback], + }, + ]; + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bscmainnet.UNITROLLER, + signature: "setCollateralFactor(uint96,address,uint256,uint256)", + params: [pool.id, market.address, market.collateralFactor, market.liquidationThreshold], + }); + } + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bscmainnet.UNITROLLER, + signature: "setLiquidationIncentive(uint96,address,uint256)", + params: [pool.id, market.address, market.liquidationIncentive], + }); + } + + for (const marketKey of Object.keys(pool.marketsConfig)) { + const market = pool.marketsConfig[marketKey]; + commands.push({ + target: bscmainnet.UNITROLLER, + signature: "setIsBorrowAllowed(uint96,address,bool)", + params: [pool.id, market.address, market.borrowAllowed], + }); + } + + return commands; +} + +export const vip800 = () => { + const meta = { + version: "v2", + title: "VIP-800 [BNB Chain] Asset Migration from BNB core pool to isolated Emode pools", + description: "VIP-800 [BNB Chain] Asset Migration from BNB core pool to isolated Emode pools", + forDescription: "I agree that Venus Protocol should proceed with this proposal", + againstDescription: "I do not think that Venus Protocol should proceed with this proposal", + abstainDescription: "I am indifferent to whether Venus Protocol proceeds or not", + }; + + return makeProposal(EMODE_POOLS.flatMap(generateEmodePoolCommands), meta, ProposalType.REGULAR); +};