diff --git a/simulations/vip-662/abi/ChainlinkOracle.json b/simulations/vip-662/abi/ChainlinkOracle.json new file mode 100644 index 000000000..a30575f77 --- /dev/null +++ b/simulations/vip-662/abi/ChainlinkOracle.json @@ -0,0 +1,187 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "address", "name": "calledContract", "type": "address" }, + { "internalType": "string", "name": "methodSignature", "type": "string" } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint8", "name": "version", "type": "uint8" }], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "address", "name": "oldAccessControlManager", "type": "address" }, + { "indexed": false, "internalType": "address", "name": "newAccessControlManager", "type": "address" } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "asset", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "previousPriceMantissa", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newPriceMantissa", "type": "uint256" } + ], + "name": "PricePosted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "asset", "type": "address" }, + { "indexed": false, "internalType": "address", "name": "feed", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "maxStalePeriod", "type": "uint256" } + ], + "name": "TokenConfigAdded", + "type": "event" + }, + { + "inputs": [], + "name": "BNB_ADDR", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "acceptOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [{ "internalType": "contract IAccessControlManagerV8", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "asset", "type": "address" }], + "name": "getPrice", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "accessControlManager_", "type": "address" }], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "prices", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [{ "internalType": "address", "name": "accessControlManager_", "type": "address" }], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "uint256", "name": "price", "type": "uint256" } + ], + "name": "setDirectPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "feed", "type": "address" }, + { "internalType": "uint256", "name": "maxStalePeriod", "type": "uint256" } + ], + "internalType": "struct ChainlinkOracle.TokenConfig", + "name": "tokenConfig", + "type": "tuple" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "feed", "type": "address" }, + { "internalType": "uint256", "name": "maxStalePeriod", "type": "uint256" } + ], + "internalType": "struct ChainlinkOracle.TokenConfig[]", + "name": "tokenConfigs_", + "type": "tuple[]" + } + ], + "name": "setTokenConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "tokenConfigs", + "outputs": [ + { "internalType": "address", "name": "asset", "type": "address" }, + { "internalType": "address", "name": "feed", "type": "address" }, + { "internalType": "uint256", "name": "maxStalePeriod", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/simulations/vip-662/abi/Comptroller.json b/simulations/vip-662/abi/Comptroller.json new file mode 100644 index 000000000..7fc9365bb --- /dev/null +++ b/simulations/vip-662/abi/Comptroller.json @@ -0,0 +1,4477 @@ +[ + { + "inputs": [], + "name": "AlreadyInSelectedPool", + "type": "error" + }, + { + "inputs": [], + "name": "ArrayLengthMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "BorrowNotAllowedInPool", + "type": "error" + }, + { + "inputs": [], + "name": "EmptyPoolLabel", + "type": "error" + }, + { + "inputs": [], + "name": "ExecuteFlashLoanFailed", + "type": "error" + }, + { + "inputs": [], + "name": "FailedToCreateDebtPosition", + "type": "error" + }, + { + "inputs": [], + "name": "FlashLoanNotEnabled", + "type": "error" + }, + { + "inputs": [], + "name": "FlashLoanPausedSystemWide", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint96", + "name": "poolId", + "type": "uint96" + } + ], + "name": "InactivePool", + "type": "error" + }, + { + "inputs": [], + "name": "IncompatibleBorrowedAssets", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAmount", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidFlashLoanParams", + "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": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketNotListed", + "type": "error" + }, + { + "inputs": [], + "name": "MarketNotListedInCorePool", + "type": "error" + }, + { + "inputs": [], + "name": "NoAssetsRequested", + "type": "error" + }, + { + "inputs": [], + "name": "NotAnApprovedDelegate", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "repaid", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "required", + "type": "uint256" + } + ], + "name": "NotEnoughRepayment", + "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" + }, + { + "inputs": [], + "name": "ReentrancyGuardReentrantCall", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "SenderNotAuthorizedForFlashLoan", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "requested", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "maximum", + "type": "uint256" + } + ], + "name": "TooManyAssetsRequested", + "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": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract VToken[]", + "name": "assets", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "FlashLoanExecuted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bool", + "name": "oldPaused", + "type": "bool" + }, + { + "indexed": false, + "internalType": "bool", + "name": "newPaused", + "type": "bool" + } + ], + "name": "FlashLoanPauseChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "onBehalf", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repaidAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remainingDebt", + "type": "uint256" + } + ], + "name": "FlashLoanRepaid", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "bool", + "name": "isWhitelisted", + "type": "bool" + } + ], + "name": "IsAccountFlashLoanWhitelisted", + "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": [], + "name": "MAX_FLASHLOAN_ASSETS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "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": "", + "type": "address" + } + ], + "name": "authorizedFlashLoan", + "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": "onBehalf", + "type": "address" + }, + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "enterMarketBehalf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "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 payable", + "name": "onBehalf", + "type": "address" + }, + { + "internalType": "address payable", + "name": "receiver", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "underlyingAmounts", + "type": "uint256[]" + }, + { + "internalType": "bytes", + "name": "param", + "type": "bytes" + } + ], + "name": "executeFlashLoan", + "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": [], + "name": "flashLoanPaused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "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": "bool", + "name": "paused", + "type": "bool" + } + ], + "name": "setFlashLoanPaused", + "outputs": [], + "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": "account", + "type": "address" + }, + { + "internalType": "bool", + "name": "isWhiteListed", + "type": "bool" + } + ], + "name": "setWhiteListFlashLoanAccount", + "outputs": [], + "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-662/abi/ERC20.json b/simulations/vip-662/abi/ERC20.json new file mode 100644 index 000000000..3a509c9c4 --- /dev/null +++ b/simulations/vip-662/abi/ERC20.json @@ -0,0 +1,134 @@ +[ + { + "inputs": [ + { "internalType": "string", "name": "name_", "type": "string" }, + { "internalType": "string", "name": "symbol_", "type": "string" }, + { "internalType": "uint8", "name": "decimals_", "type": "uint8" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "amount", "type": "uint256" }], + "name": "faucet", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/simulations/vip-662/abi/ResilientOracle.json b/simulations/vip-662/abi/ResilientOracle.json new file mode 100644 index 000000000..927d27526 --- /dev/null +++ b/simulations/vip-662/abi/ResilientOracle.json @@ -0,0 +1,655 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "nativeMarketAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "vaiAddress", + "type": "address" + }, + { + "internalType": "contract BoundValidatorInterface", + "name": "_boundValidator", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "role", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bool", + "name": "enable", + "type": "bool" + } + ], + "name": "OracleEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "role", + "type": "uint256" + } + ], + "name": "OracleSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "mainOracle", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "pivotOracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "fallbackOracle", + "type": "address" + } + ], + "name": "TokenConfigAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "INVALID_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NATIVE_TOKEN_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "boundValidator", + "outputs": [ + { + "internalType": "contract BoundValidatorInterface", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "enum ResilientOracle.OracleRole", + "name": "role", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "enable", + "type": "bool" + } + ], + "name": "enableOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "enum ResilientOracle.OracleRole", + "name": "role", + "type": "uint8" + } + ], + "name": "getOracle", + "outputs": [ + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "getTokenConfig", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address[3]", + "name": "oracles", + "type": "address[3]" + }, + { + "internalType": "bool[3]", + "name": "enableFlagsForOracles", + "type": "bool[3]" + }, + { + "internalType": "bool", + "name": "cachingEnabled", + "type": "bool" + } + ], + "internalType": "struct ResilientOracle.TokenConfig", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "getUnderlyingPrice", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "nativeMarket", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "internalType": "enum ResilientOracle.OracleRole", + "name": "role", + "type": "uint8" + } + ], + "name": "setOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address[3]", + "name": "oracles", + "type": "address[3]" + }, + { + "internalType": "bool[3]", + "name": "enableFlagsForOracles", + "type": "bool[3]" + }, + { + "internalType": "bool", + "name": "cachingEnabled", + "type": "bool" + } + ], + "internalType": "struct ResilientOracle.TokenConfig", + "name": "tokenConfig", + "type": "tuple" + } + ], + "name": "setTokenConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "address[3]", + "name": "oracles", + "type": "address[3]" + }, + { + "internalType": "bool[3]", + "name": "enableFlagsForOracles", + "type": "bool[3]" + }, + { + "internalType": "bool", + "name": "cachingEnabled", + "type": "bool" + } + ], + "internalType": "struct ResilientOracle.TokenConfig[]", + "name": "tokenConfigs_", + "type": "tuple[]" + } + ], + "name": "setTokenConfigs", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "asset", + "type": "address" + } + ], + "name": "updateAssetPrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updatePrice", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/simulations/vip-662/abi/RiskFundV2.json b/simulations/vip-662/abi/RiskFundV2.json new file mode 100644 index 000000000..074ad1471 --- /dev/null +++ b/simulations/vip-662/abi/RiskFundV2.json @@ -0,0 +1,621 @@ +[ + { + "inputs": [], + "name": "InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "poolReserve", + "type": "uint256" + } + ], + "name": "InsufficientPoolReserve", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRiskFundConverter", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidShortfallAddress", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "calledContract", + "type": "address" + }, + { + "internalType": "string", + "name": "methodSignature", + "type": "string" + } + ], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValueNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldConvertibleBaseAsset", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newConvertibleBaseAsset", + "type": "address" + } + ], + "name": "ConvertibleBaseAssetUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "PoolAssetsDecreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "PoolAssetsIncreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldRiskFundConverter", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newRiskFundConverter", + "type": "address" + } + ], + "name": "RiskFundConverterUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldShortfallContract", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newShortfallContract", + "type": "address" + } + ], + "name": "ShortfallContractUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "SweepTokenFromPool", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TransferredReserveForAuction", + "type": "event" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract IAccessControlManagerV8", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "convertibleBaseAsset", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + } + ], + "name": "getPoolsBaseAssetReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "poolAssetsFunds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "riskFundConverter", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "convertibleBaseAsset_", + "type": "address" + } + ], + "name": "setConvertibleBaseAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "riskFundConverter_", + "type": "address" + } + ], + "name": "setRiskFundConverter", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "shortfallContractAddress_", + "type": "address" + } + ], + "name": "setShortfallContractAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortfall", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "sweepTokenFromPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferReserveForAuction", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "comptroller", + "type": "address" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "updatePoolState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/simulations/vip-662/abi/TreasuryTokenBuybackDistributor.json b/simulations/vip-662/abi/TreasuryTokenBuybackDistributor.json new file mode 100644 index 000000000..8c673c0d9 --- /dev/null +++ b/simulations/vip-662/abi/TreasuryTokenBuybackDistributor.json @@ -0,0 +1,365 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "btcbBuyback_", + "type": "address" + }, + { + "internalType": "address", + "name": "ethBuyback_", + "type": "address" + }, + { + "internalType": "address", + "name": "xvsBuyback_", + "type": "address" + }, + { + "internalType": "address", + "name": "usdtBuyback_", + "type": "address" + }, + { + "internalType": "address", + "name": "usdcBuyback_", + "type": "address" + }, + { + "internalType": "address", + "name": "uBuyback_", + "type": "address" + }, + { + "internalType": "address", + "name": "vai_", + "type": "address" + }, + { + "internalType": "address", + "name": "vaiPsm_", + "type": "address" + }, + { + "internalType": "address", + "name": "stableToken_", + "type": "address" + }, + { + "internalType": "address", + "name": "treasury_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "OnlySelf", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "sum", + "type": "uint256" + } + ], + "name": "WeightsMisconfigured", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" + } + ], + "name": "TokenDistributed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "vaiIn", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "stableOut", + "type": "uint256" + } + ], + "name": "VaiConvertedViaPsm", + "type": "event" + }, + { + "inputs": [], + "name": "BTCB_BUYBACK", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "BTCB_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ETH_BUYBACK", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ETH_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_BPS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "STABLE_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TREASURY", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDC_BUYBACK", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDC_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDT_BUYBACK", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "USDT_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "U_BUYBACK", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "U_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VAI", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VAI_PSM", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "XVS_BUYBACK", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "XVS_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "_convertVaiViaPsm", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "convertVaiViaPsm", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "distribute", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/simulations/vip-662/abi/VTreasury.json b/simulations/vip-662/abi/VTreasury.json new file mode 100644 index 000000000..4df72989d --- /dev/null +++ b/simulations/vip-662/abi/VTreasury.json @@ -0,0 +1,154 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "withdrawAddress", + "type": "address" + } + ], + "name": "WithdrawTreasuryBEP20", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "withdrawAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "withdrawAddress", + "type": "address" + } + ], + "name": "WithdrawTreasuryBNB", + "type": "event" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "constant": true, + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "withdrawAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "withdrawAddress", + "type": "address" + } + ], + "name": "withdrawTreasuryBEP20", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "withdrawAmount", + "type": "uint256" + }, + { + "internalType": "address payable", + "name": "withdrawAddress", + "type": "address" + } + ], + "name": "withdrawTreasuryBNB", + "outputs": [], + "payable": true, + "stateMutability": "payable", + "type": "function" + } +] diff --git a/simulations/vip-662/bscmainnet.ts b/simulations/vip-662/bscmainnet.ts new file mode 100644 index 000000000..dd00f6bcd --- /dev/null +++ b/simulations/vip-662/bscmainnet.ts @@ -0,0 +1,313 @@ +import { mine, takeSnapshot } from "@nomicfoundation/hardhat-network-helpers"; +import { expect } from "chai"; +import { BigNumber, Contract } from "ethers"; +import { ethers } from "hardhat"; +import { expectEvents, setMaxStalePeriod } from "src/utils"; +import { forking, testVip } from "src/vip-framework"; + +import vip662, { + ATLAS_ORACLE, + ATLAS_PIVOT_ENABLE_FLAGS, + ATLAS_PIVOT_MARKETS, + ATLAS_PIVOT_ORACLES, + BINANCE_ORACLE, + CHAINLINK_ORACLE, + COMPTROLLER, + DEV_RECIPIENT, + DEV_RECIPIENT_TOKENS, + LONG_TAIL_TOKENS, + NEW_VAI_VAULT_RATE, + REDSTONE_ORACLE, + RESILIENT_ORACLE, + RISK_FUND, + RISK_FUND_BUYBACK, + TREASURY_TOKEN_BUYBACK_DISTRIBUTOR, + USDT, + VAI, + VAI_ATLAS_FEED, + VAI_ATLAS_MAX_STALE_PERIOD, + VAI_ENABLE_FLAGS, + VAI_ORACLES, + VAI_PSM, + VTREASURY, +} from "../../vips/vip-662/bscmainnet"; +import coreMarketOracles from "../../vips/vip-662/data/coreMarketOracles.json"; +import CHAINLINK_ORACLE_ABI from "./abi/ChainlinkOracle.json"; +import COMPTROLLER_ABI from "./abi/Comptroller.json"; +import ERC20_ABI from "./abi/ERC20.json"; +import RESILIENT_ORACLE_ABI from "./abi/ResilientOracle.json"; +import RISK_FUND_ABI from "./abi/RiskFundV2.json"; +import DISTRIBUTOR_ABI from "./abi/TreasuryTokenBuybackDistributor.json"; +import VTREASURY_ABI from "./abi/VTreasury.json"; + +const FORK_BLOCK = coreMarketOracles.block; + +const NATIVE_BNB = "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"; +const VBNB = "0xA07c5b74C9B40447a954e1466938b865b6BBea36"; +const VUSDT = "0xfD5840Cd36d94D7229439859C0112a4185BC0255"; +const XVS = "0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63"; +const OLD_VAI_VAULT_RATE = BigNumber.from("341157958083832"); +const OLD_ATLAS_FALLBACK_ORACLES = [CHAINLINK_ORACLE, REDSTONE_ORACLE, ATLAS_ORACLE]; +const OLD_VAI_ORACLES = [CHAINLINK_ORACLE, BINANCE_ORACLE, ethers.constants.AddressZero]; +const OLD_VAI_ENABLE_FLAGS = [true, true, false]; + +// Enough blocks for the pre-VIP rate to accrue more than the Comptroller's 4 XVS minReleaseAmount +const BLOCKS_TO_MINE = 20_000; +const DUMMY_USER = "0x0000000000000000000000000000000000000001"; + +type OracleConfig = { oracles: string[]; flags: boolean[]; caching: boolean }; + +forking(FORK_BLOCK, async () => { + const resilientOracle = new ethers.Contract(RESILIENT_ORACLE, RESILIENT_ORACLE_ABI, ethers.provider); + const atlasOracle = new ethers.Contract(ATLAS_ORACLE, CHAINLINK_ORACLE_ABI, ethers.provider); + const chainlinkOracle = new ethers.Contract(CHAINLINK_ORACLE, CHAINLINK_ORACLE_ABI, ethers.provider); + const comptroller = new ethers.Contract(COMPTROLLER, COMPTROLLER_ABI, ethers.provider); + const xvs = new ethers.Contract(XVS, ERC20_ABI, ethers.provider); + const token = (address: string) => new ethers.Contract(address, ERC20_ABI, ethers.provider); + const vai = token(VAI); + const usdt = token(USDT); + const psm = new ethers.Contract(VAI_PSM, ["function feeOut() view returns (uint256)"], ethers.provider); + + let coreAssets: string[]; + let vaiVault: string; + const configsBefore: Record = {}; + + let treasuryVaiBefore: BigNumber; + let treasuryUsdtBefore: BigNumber; + const buybackBalancesBefore: Record = {}; + const devRecipientBalancesBefore: Record = {}; + + const readConfig = async (asset: string): Promise => { + const config = await resilientOracle.getTokenConfig(asset); + return { + oracles: config.oracles.map((oracle: string) => ethers.utils.getAddress(oracle)), + flags: [...config.enableFlagsForOracles], + caching: config.cachingEnabled, + }; + }; + + const expectConfig = (config: OracleConfig, oracles: string[], flags: boolean[]) => { + expect(config.oracles).to.deep.equal(oracles.map(oracle => ethers.utils.getAddress(oracle))); + expect(config.flags).to.deep.equal(flags); + expect(config.caching).to.equal(false); + }; + + // Releases the XVS accrued for the VAI Vault by settling rewards for an arbitrary account in one + // listed market (the all-markets overload reverts on delisted markets still in getAllMarkets) + const vaultXvsReceivedAfterMining = async (): Promise => { + const balanceBefore = await xvs.balanceOf(vaiVault); + await mine(BLOCKS_TO_MINE); + const signer = (await ethers.getSigners())[0]; + await comptroller.connect(signer)["claimVenus(address,address[])"](DUMMY_USER, [VUSDT]); + return (await xvs.balanceOf(vaiVault)).sub(balanceBefore); + }; + + before(async () => { + vaiVault = await comptroller.vaiVaultAddress(); + const markets: string[] = await comptroller.getAllMarkets(); + coreAssets = await Promise.all( + markets.map(async market => { + if (ethers.utils.getAddress(market) === VBNB) return NATIVE_BNB; + const vToken = new ethers.Contract(market, ["function underlying() view returns (address)"], ethers.provider); + return ethers.utils.getAddress(await vToken.underlying()); + }), + ); + for (const asset of coreAssets) { + configsBefore[asset] = await readConfig(asset); + } + + // testVip moves the fork past the USDT feeds' stale period. The PSM prices USDT through the + // ResilientOracle, so without this convertVaiViaPsm fails inside its try/catch and the VAI stays in + // the distributor. + await setMaxStalePeriod(resilientOracle, usdt as Contract); + + treasuryVaiBefore = await vai.balanceOf(VTREASURY); + treasuryUsdtBefore = await usdt.balanceOf(VTREASURY); + for (const { address } of LONG_TAIL_TOKENS) { + buybackBalancesBefore[address] = await token(address).balanceOf(RISK_FUND_BUYBACK); + } + for (const { address } of DEV_RECIPIENT_TOKENS) { + devRecipientBalancesBefore[address] = await token(address).balanceOf(DEV_RECIPIENT); + } + }); + + describe("Pre-VIP behavior", () => { + it("coreMarketOracles matches every Core Pool market's current oracle config", async () => { + const oracleAddresses: Record = coreMarketOracles.oracleAddresses; + const toAddress = (oracle: string | null) => + ethers.utils.getAddress(oracle === null ? ethers.constants.AddressZero : oracleAddresses[oracle] ?? oracle); + + expect(coreMarketOracles.coreMarketOracles.map(({ asset }) => asset)).to.deep.equal(coreAssets); + for (const { + symbol, + asset, + main, + pivot, + fallback, + enableFlags, + cachingEnabled, + } of coreMarketOracles.coreMarketOracles) { + expect(configsBefore[asset], symbol).to.deep.equal({ + oracles: [main, pivot, fallback].map(toAddress), + flags: enableFlags, + caching: cachingEnabled, + }); + } + }); + + it("Atlas is the fallback oracle for exactly the markets the VIP updates", async () => { + const atlasFallbackAssets = coreAssets.filter( + asset => configsBefore[asset].oracles[2] === ethers.utils.getAddress(ATLAS_ORACLE), + ); + expect(atlasFallbackAssets).to.have.members(ATLAS_PIVOT_MARKETS.map(({ asset }) => asset)); + expect(atlasFallbackAssets).to.have.lengthOf(ATLAS_PIVOT_MARKETS.length); + }); + + for (const { symbol, asset } of ATLAS_PIVOT_MARKETS) { + it(`${symbol} uses [Chainlink, RedStone, Atlas], all enabled, caching disabled`, async () => { + expectConfig(await readConfig(asset), OLD_ATLAS_FALLBACK_ORACLES, [true, true, true]); + }); + } + + it("VAI uses [Chainlink, Binance, none]", async () => { + expectConfig(await readConfig(VAI), OLD_VAI_ORACLES, OLD_VAI_ENABLE_FLAGS); + }); + + it("Atlas oracle has no VAI config", async () => { + const config = await atlasOracle.tokenConfigs(VAI); + expect(config.feed).to.equal(ethers.constants.AddressZero); + }); + + it("VAI Vault XVS rate is 341157958083832 wei per block", async () => { + expect(await comptroller.venusVAIVaultRate()).to.equal(OLD_VAI_VAULT_RATE); + }); + + it("VAI Vault receives XVS as blocks pass", async () => { + const snapshot = await takeSnapshot(); + expect(await vaultXvsReceivedAfterMining()).to.be.gt(0); + await snapshot.restore(); + }); + + it("VTreasury holds VAI and the distributor holds none", async () => { + expect(treasuryVaiBefore).to.be.gt(0); + expect(await vai.balanceOf(TREASURY_TOKEN_BUYBACK_DISTRIBUTOR)).to.equal(0); + }); + + for (const { symbol, address, amount } of [...LONG_TAIL_TOKENS, ...DEV_RECIPIENT_TOKENS]) { + it(`RiskFund holds exactly ${amount} ${symbol}`, async () => { + expect(await token(address).balanceOf(RISK_FUND)).to.equal(amount); + }); + } + }); + + testVip("VIP-662 Oracle adjustments and VAI Vault rewards stop", await vip662(), { + callbackAfterExecution: async txResponse => { + await expectEvents(txResponse, [RESILIENT_ORACLE_ABI], ["TokenConfigAdded"], [ATLAS_PIVOT_MARKETS.length + 1]); + await expectEvents(txResponse, [CHAINLINK_ORACLE_ABI], ["TokenConfigAdded"], [1]); + await expectEvents(txResponse, [COMPTROLLER_ABI], ["NewVenusVAIVaultRate"], [1]); + await expectEvents(txResponse, [VTREASURY_ABI], ["WithdrawTreasuryBEP20"], [1]); + await expectEvents(txResponse, [DISTRIBUTOR_ABI], ["VaiConvertedViaPsm"], [1]); + await expectEvents( + txResponse, + [RISK_FUND_ABI], + ["SweepToken"], + [LONG_TAIL_TOKENS.length + DEV_RECIPIENT_TOKENS.length], + ); + }, + }); + + describe("Post-VIP behavior", () => { + for (const { symbol, asset } of ATLAS_PIVOT_MARKETS) { + it(`${symbol} uses [Chainlink, Atlas, RedStone], all enabled, caching disabled`, async () => { + expectConfig(await readConfig(asset), ATLAS_PIVOT_ORACLES, ATLAS_PIVOT_ENABLE_FLAGS); + }); + } + + it("every other Core Pool market keeps its oracle config", async () => { + const updated = new Set(ATLAS_PIVOT_MARKETS.map(({ asset }) => asset)); + for (const asset of coreAssets.filter(asset => !updated.has(asset))) { + expect(await readConfig(asset), asset).to.deep.equal(configsBefore[asset]); + } + }); + + it("no Core Pool market has Atlas as fallback oracle", async () => { + for (const asset of coreAssets) { + const config = await readConfig(asset); + expect(config.oracles[2], asset).to.not.equal(ethers.utils.getAddress(ATLAS_ORACLE)); + } + }); + + it("Atlas oracle has the VAI feed and stale period", async () => { + const config = await atlasOracle.tokenConfigs(VAI); + expect(config.asset).to.equal(ethers.utils.getAddress(VAI)); + expect(config.feed).to.equal(ethers.utils.getAddress(VAI_ATLAS_FEED)); + expect(config.maxStalePeriod).to.equal(VAI_ATLAS_MAX_STALE_PERIOD); + }); + + it("VAI uses [Atlas, none, none] with only the main oracle enabled", async () => { + expectConfig(await readConfig(VAI), VAI_ORACLES, VAI_ENABLE_FLAGS); + }); + + it("VAI Vault XVS rate is 0", async () => { + expect(await comptroller.venusVAIVaultRate()).to.equal(NEW_VAI_VAULT_RATE); + }); + + it("VAI Vault receives no more XVS as blocks pass", async () => { + expect(await vaultXvsReceivedAfterMining()).to.equal(0); + }); + + it("VTreasury VAI is swapped for USDT at the PSM", async () => { + // USDT is below $1 at the fork block, so the PSM prices it at $1: USDT out = VAI * 10000 / (10000 + feeOut) + const feeOut = await psm.feeOut(); + const usdtOut = treasuryVaiBefore.mul(10000).div(feeOut.add(10000)); + expect((await usdt.balanceOf(VTREASURY)).sub(treasuryUsdtBefore)).to.equal(usdtOut); + + // The PSM burns VAI equal to the USDT out and sends its fee back to VTreasury, so only the fee and + // at most 1 wei of rounding remain outside the burn + const distributorVai = await vai.balanceOf(TREASURY_TOKEN_BUYBACK_DISTRIBUTOR); + expect(distributorVai).to.be.lte(1); + expect((await vai.balanceOf(VTREASURY)).add(distributorVai)).to.equal(treasuryVaiBefore.sub(usdtOut)); + }); + + for (const { symbol, address, amount } of LONG_TAIL_TOKENS) { + it(`${symbol} is moved from the RiskFund to the RiskFund buyback`, async () => { + expect(await token(address).balanceOf(RISK_FUND)).to.equal(0); + expect((await token(address).balanceOf(RISK_FUND_BUYBACK)).sub(buybackBalancesBefore[address])).to.equal( + amount, + ); + }); + } + + for (const { symbol, address, amount } of DEV_RECIPIENT_TOKENS) { + it(`${symbol} is moved whole from the RiskFund to the dev recipient`, async () => { + expect(await token(address).balanceOf(RISK_FUND)).to.equal(0); + expect((await token(address).balanceOf(DEV_RECIPIENT)).sub(devRecipientBalancesBefore[address])).to.equal( + amount, + ); + }); + } + + describe("Prices", () => { + // testVip moves the fork past every feed's stale period, so extend them. This rewrites the + // stale periods asserted above, which is why the config checks run first. + before(async () => { + const assets = [...ATLAS_PIVOT_MARKETS.map(({ asset }) => asset), VAI]; + for (const asset of assets) { + await setMaxStalePeriod(resilientOracle, new ethers.Contract(asset, ERC20_ABI, ethers.provider) as Contract); + } + }); + + for (const { symbol, asset } of ATLAS_PIVOT_MARKETS) { + it(`${symbol} returns the Chainlink price validated against the Atlas pivot`, async () => { + expect(await resilientOracle.getPrice(asset)).to.equal(await chainlinkOracle.getPrice(asset)); + }); + } + + it("VAI returns the Atlas price", async () => { + const atlasPrice = await atlasOracle.getPrice(VAI); + expect(await resilientOracle.getPrice(VAI)).to.equal(atlasPrice); + expect(await resilientOracle.getUnderlyingPrice(VAI)).to.equal(atlasPrice); + }); + }); + }); +}); diff --git a/vips/vip-662/bscmainnet.ts b/vips/vip-662/bscmainnet.ts new file mode 100644 index 000000000..8a9de76fb --- /dev/null +++ b/vips/vip-662/bscmainnet.ts @@ -0,0 +1,243 @@ +import { ethers } from "ethers"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; +import { ProposalType } from "src/types"; +import { makeProposal } from "src/utils"; + +import coreMarketOracles from "./data/coreMarketOracles.json"; + +const { bscmainnet } = NETWORK_ADDRESSES; + +export const RESILIENT_ORACLE = bscmainnet.RESILIENT_ORACLE; +export const CHAINLINK_ORACLE = bscmainnet.CHAINLINK_ORACLE; +export const REDSTONE_ORACLE = bscmainnet.REDSTONE_ORACLE; +export const BINANCE_ORACLE = bscmainnet.BINANCE_ORACLE; +export const ATLAS_ORACLE = bscmainnet.ATLAS_ORACLE; +export const COMPTROLLER = bscmainnet.UNITROLLER; +export const VAI = bscmainnet.VAI; + +// Atlas VAI/USD feed (Atlas feed id 1049). Atlas pushes on a 24h heartbeat or a 1% deviation, +// so the stale period is the heartbeat plus a 5 minute buffer. +export const VAI_ATLAS_FEED = "0x560fe27da57934EAF2f4107989704EeBd3Da749D"; +export const VAI_ATLAS_MAX_STALE_PERIOD = 86700; + +export const NEW_VAI_VAULT_RATE = 0; + +// Core Pool markets where Atlas is currently the fallback oracle, generated by +// vips/vip-662/scripts/fetchCoreMarketOracles.ts. Each one is today configured as +// [Chainlink, RedStone, Atlas] with every oracle enabled and caching disabled (the script fails +// otherwise). The VIP swaps the pivot and fallback slots and keeps the main oracle, the enable flags +// and the caching flag as is. +export const ATLAS_PIVOT_MARKETS = coreMarketOracles.atlasPivotMarkets; + +export const ATLAS_PIVOT_ORACLES = [CHAINLINK_ORACLE, ATLAS_ORACLE, REDSTONE_ORACLE]; +export const ATLAS_PIVOT_ENABLE_FLAGS = [true, true, true]; + +export const VAI_ORACLES = [ATLAS_ORACLE, ethers.constants.AddressZero, ethers.constants.AddressZero]; +export const VAI_ENABLE_FLAGS = [true, false, false]; + +export const VTREASURY = bscmainnet.VTREASURY; +export const USDT = "0x55d398326f99059fF775485246999027B3197955"; + +// TreasuryTokenBuybackDistributor from VIP-646. convertVaiViaPsm() swaps the distributor's whole VAI +// balance for USDT at the VAI PSM and sends the USDT to VTreasury. The PSM fee is paid in VAI and also +// goes to VTreasury. +export const TREASURY_TOKEN_BUYBACK_DISTRIBUTOR = "0xc594053D4b2FaA311b55dDbFAb2338f7c90D6632"; +export const VAI_PSM = "0xC138aa4E424D1A8539e8F38Af5a754a2B7c3Cc36"; + +export const RISK_FUND = "0xdF31a28D68A2AB381D42b380649Ead7ae2A76E42"; +// Sells the tokens it holds for USDT and sends the USDT to the RiskFund +export const RISK_FUND_BUYBACK = "0x0c71EFabD00329E839745ef23aB946d3ed24A805"; + +// RiskFund.sweepToken reverts when the amount is above the balance, so every amount in the three lists +// below is the exact RiskFund balance at block 122009038. BSW and TWT (under $1 each) stay in the RiskFund. +export const LONG_TAIL_TOKENS = [ + { symbol: "FLOKI", address: "0xfb5B838b6cfEEdC2873aB27866079AC55363D37E", amount: "177082682555785184" }, + { symbol: "TRX", address: "0xCE7de646e7208a4Ef112cb6ed5038FA6cC6b12e3", amount: "1833688639" }, + { symbol: "BTT", address: "0x352Cb5E19b12FC216548a2677bD0fce83BaE434B", amount: "1392507212379014539551354602" }, + { symbol: "USDD (old)", address: "0xd17479997F34dd9156Deef8F95A52D81D265be9c", amount: "392463934353680646351" }, + { symbol: "lisUSD", address: "0x0782b6d8c4551B9760e74c0545a9bCD90bdc41E5", amount: "113920863202075023885" }, + { symbol: "TRXOLD", address: "0x85EAC5Ac2F758618dFa09bDbe0cf174e7d574D5B", amount: "15619663448654146823" }, + { symbol: "RACA", address: "0x12BB890508c125661E03b09EC06E404bc9289040", amount: "316724376165504616820380" }, +]; + +// Venus dev recipient used in VIP-628, VIP-641 and VIP-649: receives tokens the proposal cannot convert +// on-chain and works them out off-chain, returning the proceeds to the RiskFund as USDT in a later step. +export const DEV_RECIPIENT = "0x080f8a0fb70f8f0f1b83c6178225a96cbe2be0de"; + +// The RiskFund buyback prices every token it sells through the ResilientOracle, and getPrice reverts for +// these four: WIN's only oracle is a Chainlink feed that no longer answers, the other three have no oracle +// configuration at all. They go to the dev recipient instead. +export const UNPRICED_TOKENS = [ + { symbol: "WIN", address: "0xaeF0d72a118ce24feE3cD1d43d383897D05B4e99", amount: "1412410526598519969216500" }, + { symbol: "CAT", address: "0x6894CDe390a3f51155ea41Ed24a33A4827d3063D", amount: "12652875825153018355850633" }, + { symbol: "小大力神杯", address: "0x285D6aCC01F38f1Ea4666FA49Ac5f8268d127777", amount: "2020000000000000000000" }, + { symbol: "BRAD", address: "0x3dB1B406a4d50A841948765685ed42ed1f174444", amount: "50000000000000000000000" }, +]; + +// Liquid staking receipt tokens held by the RiskFund, moved whole to the dev recipient for off-chain +// unstaking rather than exited on-chain: the instant exits charge a fee, pay a non-fixed amount of BNB the +// RiskFund cannot receive directly, and the pStake one leaves dust behind. +export const STAKING_RECEIPTS = [ + { symbol: "ankrBNB", address: "0x52F24a5e03aee338Da5fd9Df68D2b6FAe1178827", amount: "2905734451637837137" }, + { symbol: "BNBx", address: "0x1bdd3Cf7F79cfB8EdbB955f20ad99211551BA275", amount: "601110316592232264" }, + { symbol: "stkBNB", address: "0xc2E9d07F66A89c44062459A47a0D2Dc038E4fb16", amount: "208460201756396971" }, + { symbol: "slisBNB", address: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B", amount: "634257472081931688" }, +]; + +export const DEV_RECIPIENT_TOKENS = [...UNPRICED_TOKENS, ...STAKING_RECEIPTS]; + +export const vip662 = () => { + const meta = { + version: "v2", + title: "VIP-662 [BNB Chain] Oracle Adjustments, VAI Vault Rewards Stop, and Treasury and Risk Fund Cleanup", + description: `#### Summary + +This proposal makes three operational changes on the BNB Chain Core Pool: + +1. Promotes the Atlas oracle to the pivot role for every Core Pool market where it is currently the fallback oracle. +2. Makes Atlas the only price source for VAI. +3. Stops the XVS rewards distributed to the VAI Vault. + +It also cleans up funds held by the Venus Treasury and the Risk Fund: + +4. Converts the VAI held by the Venus Treasury to USDT through the VAI Peg Stability Module (PSM). +5. Sends the long-tail tokens held by the Risk Fund to the RiskFund buyback, which sells them for USDT. +6. Sends the Risk Fund's remaining tokens that the buyback cannot price, and its liquid staking receipt tokens, to the Venus dev recipient for off-chain conversion, with the proceeds returned to the Risk Fund as USDT in a later step. + +#### Atlas as pivot oracle + +Atlas is currently the fallback oracle for ${ATLAS_PIVOT_MARKETS.length} Core Pool markets: ${ATLAS_PIVOT_MARKETS.map( + ({ symbol }) => symbol, + ).join( + ", ", + )}. For each of them this VIP moves Atlas to the pivot slot and moves the current pivot oracle (RedStone) to the fallback slot. The main oracle (Chainlink), the enabled flags and the caching flag stay unchanged. Markets where Atlas is already the main or the pivot oracle are not modified. No feed, stale period or bound is changed. + +#### VAI price source + +The Atlas oracle has no VAI configuration today, so it is first configured with the Atlas VAI/USD feed (${VAI_ATLAS_FEED}) and a maximum stale period of ${VAI_ATLAS_MAX_STALE_PERIOD} seconds (24 hour heartbeat plus a 5 minute buffer). The ResilientOracle configuration for VAI is then set to Atlas as the main oracle, with no pivot and no fallback oracle. Chainlink and Binance are removed from the VAI price path. + +After this change VAI has a single price source. There is no pivot oracle to cross validate the Atlas price and no fallback oracle to take over. If Atlas stops pushing the VAI price for more than ${VAI_ATLAS_MAX_STALE_PERIOD} seconds, getPrice reverts for VAI, and every operation that prices VAI, including minting, repaying and liquidating VAI, reverts with it until a new price is pushed. + +#### VAI Vault rewards + +The XVS distribution rate to the VAI Vault is set to 0. The current rate is 341,157,958,083,832 wei of XVS per block (about 65.47 XVS per day). Before the rate is updated, the Comptroller releases the XVS accrued since the last release to the VAI Vault, provided that amount reaches the Comptroller's minimum release amount of 4 XVS; a smaller amount stays in the Comptroller. VAI Vault stakers keep access to rewards already accrued. + +#### Treasury VAI + +The Venus Treasury holds about 2,343.39 VAI. The whole balance is withdrawn to the TreasuryTokenBuybackDistributor (${TREASURY_TOKEN_BUYBACK_DISTRIBUTOR}, used in VIP-646), and convertVaiViaPsm() swaps it for USDT at the VAI PSM (${VAI_PSM}). The USDT goes back to the Venus Treasury. The PSM charges a 0.1% fee, paid in VAI, which also goes to the Venus Treasury. At the time of writing the swap returns about 2,341.05 USDT. + +convertVaiViaPsm() is best effort. It wraps the PSM swap in a try/catch, so if the PSM cannot serve the swap at execution time, for example while it is paused or while its USDT price is stale, the call does not revert and the rest of the proposal still executes. In that case the VAI stays in the TreasuryTokenBuybackDistributor instead of returning to the Venus Treasury as USDT. A successful conversion emits one VaiConvertedViaPsm event, which should be checked in the execution receipt. + +#### Risk Fund long-tail tokens + +The Risk Fund (${RISK_FUND}) holds these tokens outside its base assets. Each one is sent to the RiskFund buyback (${RISK_FUND_BUYBACK}), which sells it for USDT and sends the USDT to the Risk Fund: + +- FLOKI: 177,082,682.56 (about $4,298) +- TRX: 1,833.69 (about $619) +- BTT: 1,392,507,212.38 (about $460) +- USDD (old): 392.46 (about $391) +- lisUSD: 113.92 (about $114) +- TRXOLD: 15.62 (about $5) +- RACA: 316,724.38 (about $4) + +BSW and TWT are worth less than $1 each and are not moved. + +#### Risk Fund tokens the buyback cannot price + +The RiskFund buyback prices every token it sells through the Resilient Oracle. getPrice reverts for the four tokens below, so the buyback cannot value them: the only oracle configured for WIN is Chainlink, whose WIN feed no longer responds, and the other three have no oracle configuration. Each one is sent whole to the Venus dev recipient (${DEV_RECIPIENT}, also used in VIP-628, VIP-641 and VIP-649), which converts it off-chain and returns the proceeds to the Risk Fund as USDT in a later step: + +- WIN: 1,412,410.53 (about $53) +- CAT: 12,652,875.83 (about $25) +- 小大力神杯: 2,020 (about $6) +- BRAD: 50,000 (about $3) + +#### Risk Fund staking positions + +The Risk Fund holds receipt tokens from four liquid staking protocols. Each one is sent whole to the same Venus dev recipient, which unstakes it off-chain and returns the proceeds to the Risk Fund as USDT in a later step: + +- ankrBNB: 2.9057 (about $2,311) +- BNBx: 0.6011 (about $479) +- stkBNB: 0.2085 (about $157) +- slisBNB: 0.6343 (about $473) + +The positions are not exited on-chain in this proposal. The instant exits charge a fee (0.25% on Ankr), pay an amount of BNB that is only known at execution and that the Risk Fund cannot receive directly, the pStake pool only accepts multiples of 1e12 wei and would leave dust behind, and Lista's instant withdrawal is limited to whitelisted accounts. Moving the receipt tokens whole avoids all of that and keeps the proposal independent of the state of those protocols at execution. + +#### Actions + +1. Calls setTokenConfig((address,address,uint256)) on AtlasOracle (${ATLAS_ORACLE}) for VAI (${VAI}) with the feed and stale period above. +2. Calls setTokenConfig((address,address[3],bool[3],bool)) on ResilientOracle (${RESILIENT_ORACLE}) once per market listed above, setting the oracles to [Chainlink (${CHAINLINK_ORACLE}), Atlas (${ATLAS_ORACLE}), RedStone (${REDSTONE_ORACLE})] with all oracles enabled and caching disabled. +3. Calls setTokenConfig((address,address[3],bool[3],bool)) on ResilientOracle for VAI, setting the oracles to [Atlas, none, none] with only the main oracle enabled and caching disabled. +4. Calls _setVenusVAIVaultRate(uint256) on the Core Pool Comptroller (${COMPTROLLER}) with a rate of 0. +5. Calls withdrawTreasuryBEP20(address,uint256,address) on VTreasury (${VTREASURY}) for the whole VAI balance, to the TreasuryTokenBuybackDistributor. +6. Calls convertVaiViaPsm() on the TreasuryTokenBuybackDistributor. +7. Calls sweepToken(address,address,uint256) on the Risk Fund once per long-tail token listed above, to the RiskFund buyback. +8. Calls sweepToken(address,address,uint256) on the Risk Fund once per token the buyback cannot price (WIN, CAT, 小大力神杯, BRAD), to the Venus dev recipient. +9. Calls sweepToken(address,address,uint256) on the Risk Fund once per staking receipt token (ankrBNB, BNBx, stkBNB, slisBNB), to the Venus dev recipient.`, + 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( + [ + // Atlas feed for VAI, needed before Atlas can be the VAI main oracle + { + target: ATLAS_ORACLE, + signature: "setTokenConfig((address,address,uint256))", + params: [[VAI, VAI_ATLAS_FEED, VAI_ATLAS_MAX_STALE_PERIOD]], + }, + + // Atlas moves from fallback to pivot, RedStone moves from pivot to fallback + ...ATLAS_PIVOT_MARKETS.map(({ asset }) => ({ + target: RESILIENT_ORACLE, + signature: "setTokenConfig((address,address[3],bool[3],bool))", + params: [[asset, ATLAS_PIVOT_ORACLES, ATLAS_PIVOT_ENABLE_FLAGS, false]], + })), + + // VAI priced by Atlas only + { + target: RESILIENT_ORACLE, + signature: "setTokenConfig((address,address[3],bool[3],bool))", + params: [[VAI, VAI_ORACLES, VAI_ENABLE_FLAGS, false]], + }, + + // Stop XVS rewards to the VAI Vault + { + target: COMPTROLLER, + signature: "_setVenusVAIVaultRate(uint256)", + params: [NEW_VAI_VAULT_RATE], + }, + + // Treasury VAI to USDT through the PSM, USDT goes back to VTreasury + { + target: VTREASURY, + signature: "withdrawTreasuryBEP20(address,uint256,address)", + params: [VAI, ethers.constants.MaxUint256, TREASURY_TOKEN_BUYBACK_DISTRIBUTOR], + }, + { + target: TREASURY_TOKEN_BUYBACK_DISTRIBUTOR, + signature: "convertVaiViaPsm()", + params: [], + }, + + // Long-tail tokens to the RiskFund buyback, sold for USDT + ...LONG_TAIL_TOKENS.map(({ address, amount }) => ({ + target: RISK_FUND, + signature: "sweepToken(address,address,uint256)", + params: [address, RISK_FUND_BUYBACK, amount], + })), + + // Tokens the buyback cannot price and the staking receipt tokens, whole to the dev recipient for + // off-chain conversion + ...DEV_RECIPIENT_TOKENS.map(({ address, amount }) => ({ + target: RISK_FUND, + signature: "sweepToken(address,address,uint256)", + params: [address, DEV_RECIPIENT, amount], + })), + ], + meta, + ProposalType.REGULAR, + ); +}; + +export default vip662; diff --git a/vips/vip-662/data/coreMarketOracles.json b/vips/vip-662/data/coreMarketOracles.json new file mode 100644 index 000000000..e8fddbeea --- /dev/null +++ b/vips/vip-662/data/coreMarketOracles.json @@ -0,0 +1,630 @@ +{ + "block": 122009038, + "comptroller": "0xfD36E2c2a6789Db23113685031d7F16329158384", + "resilientOracle": "0x6592b5DE802159F3E74B2486b091D11a8256ab8A", + "oracleAddresses": { + "ChainlinkOracle": "0x1B2103441A0A108daD8848D8F5d790e4D402921F", + "RedStoneOracle": "0x8455EFA4D7Ff63b8BFD96AdD889483Ea7d39B70a", + "BinanceOracle": "0x594810b741d136f1960141C0d8Fb4a91bE78A820", + "AtlasOracle": "0x9E6928Ec418948ceb9f1cd9872fD312b13D841D0" + }, + "coreMarketOracles": [ + { + "symbol": "vUSDC", + "vToken": "0xecA88125a5ADbe82614ffC12D0DB554E2e2867C8", + "asset": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vUSDT", + "vToken": "0xfD5840Cd36d94D7229439859C0112a4185BC0255", + "asset": "0x55d398326f99059fF775485246999027B3197955", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vBUSD", + "vToken": "0x95c78222B3D6e262426483D42CfA53685A67Ab9D", + "asset": "0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56", + "main": "ChainlinkOracle", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vSXP", + "vToken": "0x2fF3d0F6990a40261c66E1ff2017aCBc282EB6d0", + "asset": "0x47BEAd2563dCBf3bF2c9407fEa4dC236fAbA485A", + "main": "ChainlinkOracle", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vXVS", + "vToken": "0x151B1e2635A717bcDc836ECd6FbB62B674FE3E1D", + "asset": "0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vBNB", + "vToken": "0xA07c5b74C9B40447a954e1466938b865b6BBea36", + "asset": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vBTC", + "vToken": "0x882C173bC7Ff3b7786CA16dfeD3DFFfb9Ee7847B", + "asset": "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vETH", + "vToken": "0xf508fCD89b8bd15579dc79A6827cB4686A3592c8", + "asset": "0x2170Ed0880ac9A755fd29B2688956BD959F933F8", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vLTC", + "vToken": "0x57A5297F2cB2c0AaC9D554660acd6D385Ab50c6B", + "asset": "0x4338665CBB7B2485A8855A139b75D5e34AB0DB94", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vXRP", + "vToken": "0xB248a295732e0225acd3337607cc01068e3b9c10", + "asset": "0x1D2F0da169ceB9fC7B3144628dB156f3F6c60dBE", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vBCH", + "vToken": "0x5F0388EBc2B94FA8E123F404b79cCF5f40b29176", + "asset": "0x8fF795a6F4D97E7887C79beA79aba5cc76444aDf", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vDOT", + "vToken": "0x1610bc33319e9398de5f57B33a5b184c806aD217", + "asset": "0x7083609fCE4d1d8Dc0C979AAb8c869Ea2C873402", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vLINK", + "vToken": "0x650b940a1033B8A1b1873f78730FcFC73ec11f1f", + "asset": "0xF8A0BF9cF54Bb92F17374d9e9A321E6a111a51bD", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vDAI", + "vToken": "0x334b3eCB4DCa3593BCCC3c7EBD1A1C1d1780FBF1", + "asset": "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vFIL", + "vToken": "0xf91d58b5aE142DAcC749f58A49FCBac340Cb0343", + "asset": "0x0D8Ce2A99Bb6e3B7Db580eD848240e4a0F9aE153", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vBETH", + "vToken": "0x972207A639CC1B374B893cc33Fa251b55CEB7c07", + "asset": "0x250632378E573c6Be1AC2f97Fcdf00515d0Aa91B", + "main": "ChainlinkOracle", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vCAN", + "vToken": "0xeBD0070237a0713E8D94fEf1B728d3d993d290ef", + "asset": "0x20bff4bbEDa07536FF00e073bd8359E5D80D733d", + "main": "ChainlinkOracle", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vADA", + "vToken": "0x9A0AF7FDb2065Ce470D72664DE73cAE409dA28Ec", + "asset": "0x3EE2200Efb3400fAbB9AacF31297cBdD1d435D47", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vDOGE", + "vToken": "0xec3422Ef92B2fb59e84c8B02Ba73F1fE84Ed8D71", + "asset": "0xbA2aE424d960c26247Dd6c32edC70B295c744C43", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vMATIC", + "vToken": "0x5c9476FcD6a4F9a3654139721c949c2233bBbBc8", + "asset": "0xCC42724C6683B7E57334c4E856f4c9965ED682bD", + "main": "ChainlinkOracle", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vCAKE", + "vToken": "0x86aC3974e2BD0d60825230fa6F355fF11409df5c", + "asset": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vAAVE", + "vToken": "0x26DA28954763B92139ED49283625ceCAf52C6f94", + "asset": "0xfb6115445Bff7b52FeB98650C87f44907E58f802", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vTUSDOLD", + "vToken": "0x08CEB3F4a7ed3500cA0982bcd0FC7816688084c3", + "asset": "0x14016E85a25aeb13065688cAFB43044C2ef86784", + "main": "ChainlinkOracle", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vTRXOLD", + "vToken": "0x61eDcFe8Dd6bA3c891CB9bEc2dc7657B3B422E93", + "asset": "0x85EAC5Ac2F758618dFa09bDbe0cf174e7d574D5B", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vUST", + "vToken": "0x78366446547D062f45b4C0f320cDaa6d710D87bb", + "asset": "0x3d4350cD54aeF9f9b2C29435e0fa809957B3F30a", + "main": "ChainlinkOracle", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vLUNA", + "vToken": "0xb91A659E88B51474767CD97EF3196A3e7cEDD2c8", + "asset": "0x156ab3346823B651294766e23e6Cf87254d68962", + "main": "ChainlinkOracle", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vTRX", + "vToken": "0xC5D3466aA484B040eE977073fcF337f2c00071c1", + "asset": "0xCE7de646e7208a4Ef112cb6ed5038FA6cC6b12e3", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vWBETH", + "vToken": "0x6CFdEc747f37DAf3b87a35a1D9c8AD3063A1A8A0", + "asset": "0xa2E3356610840701BDf5611a53974510Ae27E2e1", + "main": "0x49938fc72262c126eb5D4BdF6430C55189AEB2BA", + "pivot": "AtlasOracle", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vTUSD", + "vToken": "0xBf762cd5991cA1DCdDaC9ae5C638F5B5Dc3Bee6E", + "asset": "0x40af3827F39D0EAcBF4A168f8D4ee67c121D11c9", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vUNI", + "vToken": "0x27FF564707786720C71A2e5c1490A63266683612", + "asset": "0xBf5140A22578168FD562DCcF235E5D43A02ce9B1", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vFDUSD", + "vToken": "0xC4eF4229FEc74Ccfe17B2bdeF7715fAC740BA0ba", + "asset": "0xc5f0f7b66764F6ec8C8Dff7BA683102295E16409", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vTWT", + "vToken": "0x4d41a36D04D97785bcEA57b057C412b278e6Edcc", + "asset": "0x4B0F1812e5Df2A09796481Ff14017e6005508003", + "main": "AtlasOracle", + "pivot": "RedStoneOracle", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vSolvBTC", + "vToken": "0xf841cb62c19fCd4fF5CD0AaB5939f3140BaaC3Ea", + "asset": "0x4aae823a6a0b376De6A78e74eCC5b079d38cBCf7", + "main": "0x3f4bC081E749032cffF29dcA2E8408Ec375e745A", + "pivot": "0x1f785B1AFE0808d69d1188db9e47b7B9Dd95ab09", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vTHE", + "vToken": "0x86e06EAfa6A1eA631Eab51DE500E3D474933739f", + "asset": "0xF4C8E32EaDEC4BFe97E0F595AdD0f4450a863a11", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vSOL", + "vToken": "0xBf515bA4D1b52FFdCeaBF20d31D705Ce789F2cEC", + "asset": "0x570A5D26f7765Ecb712C0924E4De545B89fD43dF", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vlisUSD", + "vToken": "0x689E0daB47Ab16bcae87Ec18491692BF621Dc6Ab", + "asset": "0x0782b6d8c4551B9760e74c0545a9bCD90bdc41E5", + "main": "AtlasOracle", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vPT-sUSDE-26JUN2025", + "vToken": "0x9e4E5fed5Ac5B9F732d0D850A615206330Bf1866", + "asset": "0xDD809435ba6c9d6903730f923038801781cA66ce", + "main": "0xC407403fa78Bce509821D776b6Be7f91cC04474f", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vsUSDe", + "vToken": "0x699658323d58eE25c69F1a29d476946ab011bD18", + "asset": "0x211Cc4DD073734dA055fbF44a2b4667d5E5fE5d2", + "main": "0x2B2895104f958E1EC042E6Ba5cbfeCbAD3C5beDb", + "pivot": "0xA67F01322AF8EBa444D788Ee398775b446de51a0", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vUSDe", + "vToken": "0x74ca6930108F775CC667894EEa33843e691680d7", + "asset": "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34", + "main": "0x22Dc2BAEa32E95AB07C2F5B8F63336CbF61aB6b8", + "pivot": "ChainlinkOracle", + "fallback": "RedStoneOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vUSD1", + "vToken": "0x0C1DA220D301155b87318B90692Da8dc43B67340", + "asset": "0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vxSolvBTC", + "vToken": "0xd804dE60aFD05EE6B89aab5D152258fD461B07D5", + "asset": "0x1346b618dC92810EC74163e4c27004c921D446a5", + "main": "0xDfDbF9DAFbc94Cb1F827d3364637dDBB26823739", + "pivot": "0xf5534f78Df9b610B19A63956d498d00CFaD8B9D3", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vasBNB", + "vToken": "0xCC1dB43a06d97f736C7B045AedD03C6707c09BDF", + "asset": "0x77734e70b6E88b4d82fE632a168EDf6e700912b6", + "main": "0x652B90D1d45a7cD5BE82c5Fb61a4A00bA126dde5", + "pivot": "AtlasOracle", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vWBNB", + "vToken": "0x6bCa74586218dB34cdB402295796b79663d816e9", + "asset": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "main": "ChainlinkOracle", + "pivot": "RedStoneOracle", + "fallback": "AtlasOracle", + "enableFlags": [true, true, true], + "cachingEnabled": false + }, + { + "symbol": "vPT-USDe-30OCT2025", + "vToken": "0x6D0cDb3355c93A0cD20071aBbb3622731a95c73E", + "asset": "0x607C834cfb7FCBbb341Cbe23f77A6E83bCf3F55c", + "main": "0xAa5138e86c078fd2859a929173B3870b5003EC30", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vslisBNB", + "vToken": "0x89c910Eb8c90df818b4649b508Ba22130Dc73Adc", + "asset": "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B", + "main": "0xDDE6446E66c786afF4cd3D183a908bCDa57DF9c1", + "pivot": "AtlasOracle", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vU", + "vToken": "0x3d5E269787d562b74aCC55F18Bd26C5D09Fa245E", + "asset": "0xcE24439F2D9C6a2289F741120FE202248B666666", + "main": "ChainlinkOracle", + "pivot": "AtlasOracle", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vPT-clisBNB-25JUN2026", + "vToken": "0x6d3BD68E90B42615cb5abF4B8DE92b154ADc435e", + "asset": "0xe052823b4aefc6e230FAf46231A57d0905E30AE0", + "main": "0x0FfFBb55d51cD46cD10C7dc865Dc73BD76201310", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vXAUM", + "vToken": "0x92e6Ea74a1A3047DabF4186405a21c7D63a0612A", + "asset": "0x23AE4fd8E7844cdBc97775496eBd0E8248656028", + "main": "ChainlinkOracle", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vTSLAB", + "vToken": "0x97421799419Eb782628e73e7220d8E0A207469a3", + "asset": "0x5b1910eAaD6450E50f816082Aa078C41F10C292f", + "main": "AtlasOracle", + "pivot": "0x04480f1Ba2252CDF89deB022B58d0a03d1B4cF91", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vNVDAB", + "vToken": "0xEb8Ca841cBe1BC4832A10b15c7dAB1081eDaD371", + "asset": "0x02Fca66C1D1aFB4E2A7884261eB00F63598a7436", + "main": "AtlasOracle", + "pivot": "0x04480f1Ba2252CDF89deB022B58d0a03d1B4cF91", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vSPCXB", + "vToken": "0xC36dFaCc7a125859C106F29b9F2d874CCF29A55A", + "asset": "0xbe9D156892E55e7154BcD3cB0FEA677F9D3103E1", + "main": "AtlasOracle", + "pivot": "0x04480f1Ba2252CDF89deB022B58d0a03d1B4cF91", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vSKHYB", + "vToken": "0x3E281461efb3D53EC20DB207674373Ed8Ef3BbA9", + "asset": "0xCA750eF65f295BBECd685Abf54e82CAf297BDB61", + "main": "AtlasOracle", + "pivot": "0x04480f1Ba2252CDF89deB022B58d0a03d1B4cF91", + "fallback": null, + "enableFlags": [true, true, false], + "cachingEnabled": false + }, + { + "symbol": "vvhUSDT", + "vToken": "0xc0768948e668B7BacFf8b4BD1BaBe0eD2b512d3c", + "asset": "0x18AfDACF30F8671021dec4b78297E39d2FE87226", + "main": "0x50a998cf59Fe719129702125C9078b0B429DA6E7", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vvhUSDC", + "vToken": "0xb1AB0399766997C5d66a30b2f2055277B7FA5D6C", + "asset": "0x9D2D9592cF8DFbf59107fAab703d08494BE14617", + "main": "0x85aa49526287F06cb36d57121BC7abAF58a8787a", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + }, + { + "symbol": "vvhU", + "vToken": "0x80a5694441810d2b871BEeD644b6d16D113ce06E", + "asset": "0x0e5AA174d4F31b757a237eb1999DE151596788B0", + "main": "0x5b3735F362ed89b51FBe244509e398BFDDaC8da9", + "pivot": null, + "fallback": null, + "enableFlags": [true, false, false], + "cachingEnabled": false + } + ], + "atlasPivotMarkets": [ + { + "symbol": "vUSDC", + "vToken": "0xecA88125a5ADbe82614ffC12D0DB554E2e2867C8", + "asset": "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d" + }, + { + "symbol": "vUSDT", + "vToken": "0xfD5840Cd36d94D7229439859C0112a4185BC0255", + "asset": "0x55d398326f99059fF775485246999027B3197955" + }, + { + "symbol": "vXVS", + "vToken": "0x151B1e2635A717bcDc836ECd6FbB62B674FE3E1D", + "asset": "0xcF6BB5389c92Bdda8a3747Ddb454cB7a64626C63" + }, + { + "symbol": "vBNB", + "vToken": "0xA07c5b74C9B40447a954e1466938b865b6BBea36", + "asset": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" + }, + { + "symbol": "vBTC", + "vToken": "0x882C173bC7Ff3b7786CA16dfeD3DFFfb9Ee7847B", + "asset": "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c" + }, + { + "symbol": "vETH", + "vToken": "0xf508fCD89b8bd15579dc79A6827cB4686A3592c8", + "asset": "0x2170Ed0880ac9A755fd29B2688956BD959F933F8" + }, + { + "symbol": "vXRP", + "vToken": "0xB248a295732e0225acd3337607cc01068e3b9c10", + "asset": "0x1D2F0da169ceB9fC7B3144628dB156f3F6c60dBE" + }, + { + "symbol": "vDAI", + "vToken": "0x334b3eCB4DCa3593BCCC3c7EBD1A1C1d1780FBF1", + "asset": "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3" + }, + { + "symbol": "vADA", + "vToken": "0x9A0AF7FDb2065Ce470D72664DE73cAE409dA28Ec", + "asset": "0x3EE2200Efb3400fAbB9AacF31297cBdD1d435D47" + }, + { + "symbol": "vCAKE", + "vToken": "0x86aC3974e2BD0d60825230fa6F355fF11409df5c", + "asset": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82" + }, + { + "symbol": "vTRX", + "vToken": "0xC5D3466aA484B040eE977073fcF337f2c00071c1", + "asset": "0xCE7de646e7208a4Ef112cb6ed5038FA6cC6b12e3" + }, + { + "symbol": "vUSD1", + "vToken": "0x0C1DA220D301155b87318B90692Da8dc43B67340", + "asset": "0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d" + }, + { + "symbol": "vWBNB", + "vToken": "0x6bCa74586218dB34cdB402295796b79663d816e9", + "asset": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" + } + ] +} diff --git a/vips/vip-662/scripts/fetchCoreMarketOracles.ts b/vips/vip-662/scripts/fetchCoreMarketOracles.ts new file mode 100644 index 000000000..3baf35894 --- /dev/null +++ b/vips/vip-662/scripts/fetchCoreMarketOracles.ts @@ -0,0 +1,139 @@ +/** + * Generates vips/vip-662/data/coreMarketOracles.json. + * + * The file has two arrays: + * - coreMarketOracles: every market returned by the Core Pool Comptroller's getAllMarkets(), with + * its current ResilientOracle main, pivot and fallback oracles, enable flags and caching flag. + * Known oracles are shown by name (see oracleAddresses), any other oracle by address, and an + * empty slot as null. This is the on-chain state the VIP starts from. + * - atlasPivotMarkets: the markets where Atlas is the fallback oracle. vips/vip-662/bscmainnet.ts + * moves Atlas to the pivot slot for exactly these markets. + * + * Each atlasPivotMarkets entry must match what the VIP assumes, otherwise the script fails and + * writes nothing: + * - config is [Chainlink, RedStone, Atlas], all oracles enabled, caching disabled + * - the Chainlink price validates against the Atlas price with the asset's BoundValidator bounds, + * which is the check ResilientOracle runs once Atlas becomes the pivot + * + * Run: + * npx hardhat run vips/vip-662/scripts/fetchCoreMarketOracles.ts --network bscmainnet + */ +import fs from "fs"; +import { ethers } from "hardhat"; +import path from "path"; +import { NETWORK_ADDRESSES } from "src/networkAddresses"; + +const { bscmainnet } = NETWORK_ADDRESSES; + +const VBNB = "0xA07c5b74C9B40447a954e1466938b865b6BBea36"; +const NATIVE_BNB = "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"; +const OUTPUT = path.resolve(__dirname, "../data/coreMarketOracles.json"); + +const COMPTROLLER_ABI = ["function getAllMarkets() view returns (address[])"]; +const VTOKEN_ABI = ["function symbol() view returns (string)", "function underlying() view returns (address)"]; +const RESILIENT_ORACLE_ABI = [ + "function getTokenConfig(address) view returns (tuple(address asset,address[3] oracles,bool[3] enableFlagsForOracles,bool cachingEnabled))", + "function boundValidator() view returns (address)", +]; +const ORACLE_ABI = ["function getPrice(address) view returns (uint256)"]; +const BOUND_VALIDATOR_ABI = [ + "function validatePriceWithAnchorPrice(address asset,uint256 reportedPrice,uint256 anchorPrice) view returns (bool)", +]; + +const oracleAddresses: Record = { + ChainlinkOracle: bscmainnet.CHAINLINK_ORACLE, + RedStoneOracle: bscmainnet.REDSTONE_ORACLE, + BinanceOracle: bscmainnet.BINANCE_ORACLE, + AtlasOracle: bscmainnet.ATLAS_ORACLE, +}; + +async function main() { + const { getAddress } = ethers.utils; + const provider = ethers.provider; + const comptroller = new ethers.Contract(bscmainnet.UNITROLLER, COMPTROLLER_ABI, provider); + const resilientOracle = new ethers.Contract(bscmainnet.RESILIENT_ORACLE, RESILIENT_ORACLE_ABI, provider); + const boundValidator = new ethers.Contract(await resilientOracle.boundValidator(), BOUND_VALIDATOR_ABI, provider); + const chainlinkOracle = new ethers.Contract(bscmainnet.CHAINLINK_ORACLE, ORACLE_ABI, provider); + const atlasOracle = new ethers.Contract(bscmainnet.ATLAS_ORACLE, ORACLE_ABI, provider); + + const atlas = getAddress(bscmainnet.ATLAS_ORACLE); + const expectedOracles = [bscmainnet.CHAINLINK_ORACLE, bscmainnet.REDSTONE_ORACLE, bscmainnet.ATLAS_ORACLE].map( + getAddress, + ); + const nameOf = (oracle: string): string | null => { + if (oracle === ethers.constants.AddressZero) return null; + const name = Object.keys(oracleAddresses).find(key => getAddress(oracleAddresses[key]) === oracle); + return name ?? oracle; + }; + + const block = await provider.getBlockNumber(); + const markets: string[] = await comptroller.getAllMarkets(); + const coreMarketOracles = []; + const atlasPivotMarkets = []; + const failures: string[] = []; + + for (const market of markets) { + const vToken = getAddress(market); + const vTokenContract = new ethers.Contract(vToken, VTOKEN_ABI, provider); + const symbol: string = await vTokenContract.symbol(); + const asset = vToken === VBNB ? NATIVE_BNB : getAddress(await vTokenContract.underlying()); + + const config = await resilientOracle.getTokenConfig(asset); + const oracles: string[] = config.oracles.map(getAddress); + const [main, pivot, fallback] = oracles.map(nameOf); + coreMarketOracles.push({ + symbol, + vToken, + asset, + main, + pivot, + fallback, + enableFlags: [...config.enableFlagsForOracles], + cachingEnabled: config.cachingEnabled, + }); + + if (oracles[2] !== atlas) continue; + atlasPivotMarkets.push({ symbol, vToken, asset }); + + const configMatches = + oracles.every((oracle, i) => oracle === expectedOracles[i]) && + config.enableFlagsForOracles.every((flag: boolean) => flag) && + !config.cachingEnabled; + if (!configMatches) { + failures.push( + `${symbol}: unexpected config [${main}, ${pivot}, ${fallback}] flags=${config.enableFlagsForOracles} caching=${config.cachingEnabled}`, + ); + } + + const [chainlinkPrice, atlasPrice] = await Promise.all([ + chainlinkOracle.getPrice(asset), + atlasOracle.getPrice(asset), + ]); + if (!(await boundValidator.validatePriceWithAnchorPrice(asset, chainlinkPrice, atlasPrice))) { + failures.push(`${symbol}: Chainlink price ${chainlinkPrice} is outside the bounds of Atlas price ${atlasPrice}`); + } + } + + console.log(`Block ${block}: ${markets.length} Core Pool markets, Atlas is fallback for ${atlasPivotMarkets.length}`); + + if (failures.length > 0) { + throw new Error(`Nothing written:\n${failures.join("\n")}`); + } + + const out = { + block, + comptroller: bscmainnet.UNITROLLER, + resilientOracle: bscmainnet.RESILIENT_ORACLE, + oracleAddresses, + coreMarketOracles, + atlasPivotMarkets, + }; + fs.mkdirSync(path.dirname(OUTPUT), { recursive: true }); + fs.writeFileSync(OUTPUT, `${JSON.stringify(out, null, 2)}\n`); + console.log(`Wrote ${path.relative(process.cwd(), OUTPUT)}: ${atlasPivotMarkets.map(m => m.symbol).join(", ")}`); +} + +main().catch(error => { + console.error(error); + process.exitCode = 1; +});