From e35808cc061d92de48de15809343a5a8fc4d8ff2 Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Thu, 28 Sep 2023 12:51:04 +0530 Subject: [PATCH 01/10] feat: add agEUR market simulations --- .../vip-178-testnet/abi/comptroller.json | 769 +++++++ .../vip-178/vip-178-testnet/abi/erc20.json | 134 ++ .../vip-178-testnet/abi/poolRegistry.json | 310 +++ .../vip-178-testnet/abi/rateModel.json | 118 ++ .../vip-178/vip-178-testnet/abi/vToken.json | 1872 +++++++++++++++++ .../vip-178/vip-178-testnet/simulations.ts | 261 +++ .../vip-178/vip-178/abi/comptroller.json | 769 +++++++ simulations/vip-178/vip-178/abi/erc20.json | 134 ++ .../vip-178/vip-178/abi/poolRegistry.json | 310 +++ .../vip-178/vip-178/abi/rateModel.json | 118 ++ simulations/vip-178/vip-178/abi/vToken.json | 790 +++++++ simulations/vip-178/vip-178/simulations.ts | 263 +++ vips/vip-178/vip-178-testnet.ts | 80 + vips/vip-178/vip-178.ts | 88 + 14 files changed, 6016 insertions(+) create mode 100644 simulations/vip-178/vip-178-testnet/abi/comptroller.json create mode 100644 simulations/vip-178/vip-178-testnet/abi/erc20.json create mode 100644 simulations/vip-178/vip-178-testnet/abi/poolRegistry.json create mode 100644 simulations/vip-178/vip-178-testnet/abi/rateModel.json create mode 100644 simulations/vip-178/vip-178-testnet/abi/vToken.json create mode 100644 simulations/vip-178/vip-178-testnet/simulations.ts create mode 100644 simulations/vip-178/vip-178/abi/comptroller.json create mode 100644 simulations/vip-178/vip-178/abi/erc20.json create mode 100644 simulations/vip-178/vip-178/abi/poolRegistry.json create mode 100644 simulations/vip-178/vip-178/abi/rateModel.json create mode 100644 simulations/vip-178/vip-178/abi/vToken.json create mode 100644 simulations/vip-178/vip-178/simulations.ts create mode 100644 vips/vip-178/vip-178-testnet.ts create mode 100644 vips/vip-178/vip-178.ts diff --git a/simulations/vip-178/vip-178-testnet/abi/comptroller.json b/simulations/vip-178/vip-178-testnet/abi/comptroller.json new file mode 100644 index 000000000..f8d85ef31 --- /dev/null +++ b/simulations/vip-178/vip-178-testnet/abi/comptroller.json @@ -0,0 +1,769 @@ +[ + { + "inputs": [{ "internalType": "address", "name": "poolRegistry_", "type": "address" }], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "market", "type": "address" }, + { "internalType": "enum ComptrollerStorage.Action", "name": "action", "type": "uint8" } + ], + "name": "ActionPaused", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "market", "type": "address" }, + { "internalType": "uint256", "name": "cap", "type": "uint256" } + ], + "name": "BorrowCapExceeded", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "expectedLessThanOrEqualTo", "type": "uint256" }, + { "internalType": "uint256", "name": "actual", "type": "uint256" } + ], + "name": "CollateralExceedsThreshold", + "type": "error" + }, + { "inputs": [], "name": "ComptrollerMismatch", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "collateralToSeize", "type": "uint256" }, + { "internalType": "uint256", "name": "availableCollateral", "type": "uint256" } + ], + "name": "InsufficientCollateral", + "type": "error" + }, + { "inputs": [], "name": "InsufficientLiquidity", "type": "error" }, + { "inputs": [], "name": "InsufficientShortfall", "type": "error" }, + { "inputs": [], "name": "InvalidCollateralFactor", "type": "error" }, + { "inputs": [], "name": "InvalidLiquidationThreshold", "type": "error" }, + { + "inputs": [{ "internalType": "address", "name": "market", "type": "address" }], + "name": "MarketAlreadyListed", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "MarketNotCollateral", + "type": "error" + }, + { + "inputs": [{ "internalType": "address", "name": "market", "type": "address" }], + "name": "MarketNotListed", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "loopsLimit", "type": "uint256" }, + { "internalType": "uint256", "name": "requiredLoops", "type": "uint256" } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "expectedGreaterThan", "type": "uint256" }, + { "internalType": "uint256", "name": "actual", "type": "uint256" } + ], + "name": "MinimalCollateralViolated", + "type": "error" + }, + { "inputs": [], "name": "NonzeroBorrowBalance", "type": "error" }, + { + "inputs": [{ "internalType": "address", "name": "vToken", "type": "address" }], + "name": "PriceError", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "SnapshotError", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "market", "type": "address" }, + { "internalType": "uint256", "name": "cap", "type": "uint256" } + ], + "name": "SupplyCapExceeded", + "type": "error" + }, + { "inputs": [], "name": "TooMuchRepay", "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": [ + { "internalType": "address", "name": "expectedSender", "type": "address" }, + { "internalType": "address", "name": "actualSender", "type": "address" } + ], + "name": "UnexpectedSender", + "type": "error" + }, + { "inputs": [], "name": "ZeroAddressNotAllowed", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "contract VToken", "name": "vToken", "type": "address" }, + { "indexed": false, "internalType": "enum ComptrollerStorage.Action", "name": "action", "type": "uint8" }, + { "indexed": false, "internalType": "bool", "name": "pauseState", "type": "bool" } + ], + "name": "ActionPausedMarket", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint8", "name": "version", "type": "uint8" }], + "name": "Initialized", + "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": false, "internalType": "contract VToken", "name": "vToken", "type": "address" }], + "name": "MarketSupported", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "oldMaxLoopsLimit", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newmaxLoopsLimit", "type": "uint256" } + ], + "name": "MaxLoopsLimitUpdated", + "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": "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": false, "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": "uint256", "name": "oldLiquidationIncentiveMantissa", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newLiquidationIncentiveMantissa", "type": "uint256" } + ], + "name": "NewLiquidationIncentive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "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": "uint256", "name": "oldMinLiquidatableCollateral", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newMinLiquidatableCollateral", "type": "uint256" } + ], + "name": "NewMinLiquidatableCollateral", + "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": true, "internalType": "address", "name": "rewardsDistributor", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "rewardToken", "type": "address" } + ], + "name": "NewRewardsDistributor", + "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": 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" + }, + { "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": "", "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 ComptrollerStorage.Action", "name": "action", "type": "uint8" } + ], + "name": "actionPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract RewardsDistributor", "name": "_rewardsDistributor", "type": "address" }], + "name": "addRewardsDistributor", + "outputs": [], + "stateMutability": "nonpayable", + "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" }], + "name": "borrowCaps", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "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": [], + "name": "closeFactorMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address[]", "name": "vTokens", "type": "address[]" }], + "name": "enterMarkets", + "outputs": [{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }], + "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": "address", "name": "account", "type": "address" }], + "name": "getAccountLiquidity", + "outputs": [ + { "internalType": "uint256", "name": "error", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidity", "type": "uint256" }, + { "internalType": "uint256", "name": "shortfall", "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": "error", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidity", "type": "uint256" }, + { "internalType": "uint256", "name": "shortfall", "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": "error", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidity", "type": "uint256" }, + { "internalType": "uint256", "name": "shortfall", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardDistributors", + "outputs": [{ "internalType": "contract RewardsDistributor[]", "name": "", "type": "address[]" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "vToken", "type": "address" }], + "name": "getRewardsByMarket", + "outputs": [ + { + "components": [ + { "internalType": "address", "name": "rewardToken", "type": "address" }, + { "internalType": "uint256", "name": "supplySpeed", "type": "uint256" }, + { "internalType": "uint256", "name": "borrowSpeed", "type": "uint256" } + ], + "internalType": "struct ComptrollerStorage.RewardSpeeds[]", + "name": "rewardSpeeds", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "user", "type": "address" }], + "name": "healAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "loopLimit", "type": "uint256" }, + { "internalType": "address", "name": "accessControlManager", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isComptroller", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract VToken", "name": "vToken", "type": "address" }], + "name": "isDeprecated", + "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": [ + { "internalType": "address", "name": "borrower", "type": "address" }, + { + "components": [ + { "internalType": "contract VToken", "name": "vTokenCollateral", "type": "address" }, + { "internalType": "contract VToken", "name": "vTokenBorrowed", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "internalType": "struct ComptrollerStorage.LiquidationOrder[]", + "name": "orders", + "type": "tuple[]" + } + ], + "name": "liquidateAccount", + "outputs": [], + "stateMutability": "nonpayable", + "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": "error", "type": "uint256" }, + { "internalType": "uint256", "name": "tokensToSeize", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "markets", + "outputs": [ + { "internalType": "bool", "name": "isListed", "type": "bool" }, + { "internalType": "uint256", "name": "collateralFactorMantissa", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidationThresholdMantissa", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minLiquidatableCollateral", + "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": "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": [], + "name": "poolRegistry", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "borrowAmount", "type": "uint256" } + ], + "name": "preBorrowHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vTokenBorrowed", "type": "address" }, + { "internalType": "address", "name": "vTokenCollateral", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "internalType": "bool", "name": "skipLiquidityCheck", "type": "bool" } + ], + "name": "preLiquidateHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "minter", "type": "address" }, + { "internalType": "uint256", "name": "mintAmount", "type": "uint256" } + ], + "name": "preMintHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "redeemer", "type": "address" }, + { "internalType": "uint256", "name": "redeemTokens", "type": "uint256" } + ], + "name": "preRedeemHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" } + ], + "name": "preRepayHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vTokenCollateral", "type": "address" }, + { "internalType": "address", "name": "seizerContract", "type": "address" }, + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" } + ], + "name": "preSeizeHook", + "outputs": [], + "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": "preTransferHook", + "outputs": [], + "stateMutability": "nonpayable", + "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": "contract VToken[]", "name": "marketsList", "type": "address[]" }, + { "internalType": "enum ComptrollerStorage.Action[]", "name": "actionsList", "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": [], + "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": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "newLiquidationIncentiveMantissa", "type": "uint256" }], + "name": "setLiquidationIncentive", + "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": "uint256", "name": "limit", "type": "uint256" }], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "newMinLiquidatableCollateral", "type": "uint256" }], + "name": "setMinLiquidatableCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract ResilientOracleInterface", "name": "newOracle", "type": "address" }], + "name": "setPriceOracle", + "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": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "updatePrices", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/simulations/vip-178/vip-178-testnet/abi/erc20.json b/simulations/vip-178/vip-178-testnet/abi/erc20.json new file mode 100644 index 000000000..3a509c9c4 --- /dev/null +++ b/simulations/vip-178/vip-178-testnet/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-178/vip-178-testnet/abi/poolRegistry.json b/simulations/vip-178/vip-178-testnet/abi/poolRegistry.json new file mode 100644 index 000000000..8f15277d2 --- /dev/null +++ b/simulations/vip-178/vip-178-testnet/abi/poolRegistry.json @@ -0,0 +1,310 @@ +[ + { "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" + }, + { "inputs": [], "name": "ZeroAddressNotAllowed", "type": "error" }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint8", "name": "version", "type": "uint8" }], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "comptroller", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "vTokenAddress", "type": "address" } + ], + "name": "MarketAdded", + "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" }, + { + "components": [ + { "internalType": "string", "name": "category", "type": "string" }, + { "internalType": "string", "name": "logoURL", "type": "string" }, + { "internalType": "string", "name": "description", "type": "string" } + ], + "indexed": false, + "internalType": "struct PoolRegistryInterface.VenusPoolMetaData", + "name": "oldMetadata", + "type": "tuple" + }, + { + "components": [ + { "internalType": "string", "name": "category", "type": "string" }, + { "internalType": "string", "name": "logoURL", "type": "string" }, + { "internalType": "string", "name": "description", "type": "string" } + ], + "indexed": false, + "internalType": "struct PoolRegistryInterface.VenusPoolMetaData", + "name": "newMetadata", + "type": "tuple" + } + ], + "name": "PoolMetadataUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "comptroller", "type": "address" }, + { "indexed": false, "internalType": "string", "name": "oldName", "type": "string" }, + { "indexed": false, "internalType": "string", "name": "newName", "type": "string" } + ], + "name": "PoolNameSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "comptroller", "type": "address" }, + { + "components": [ + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "address", "name": "creator", "type": "address" }, + { "internalType": "address", "name": "comptroller", "type": "address" }, + { "internalType": "uint256", "name": "blockPosted", "type": "uint256" }, + { "internalType": "uint256", "name": "timestampPosted", "type": "uint256" } + ], + "indexed": false, + "internalType": "struct PoolRegistryInterface.VenusPool", + "name": "pool", + "type": "tuple" + } + ], + "name": "PoolRegistered", + "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": [ + { + "components": [ + { "internalType": "contract VToken", "name": "vToken", "type": "address" }, + { "internalType": "uint256", "name": "collateralFactor", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidationThreshold", "type": "uint256" }, + { "internalType": "uint256", "name": "initialSupply", "type": "uint256" }, + { "internalType": "address", "name": "vTokenReceiver", "type": "address" }, + { "internalType": "uint256", "name": "supplyCap", "type": "uint256" }, + { "internalType": "uint256", "name": "borrowCap", "type": "uint256" } + ], + "internalType": "struct PoolRegistry.AddMarketInput", + "name": "input", + "type": "tuple" + } + ], + "name": "addMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "contract Comptroller", "name": "comptroller", "type": "address" }, + { "internalType": "uint256", "name": "closeFactor", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidationIncentive", "type": "uint256" }, + { "internalType": "uint256", "name": "minLiquidatableCollateral", "type": "uint256" } + ], + "name": "addPool", + "outputs": [{ "internalType": "uint256", "name": "index", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAllPools", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "address", "name": "creator", "type": "address" }, + { "internalType": "address", "name": "comptroller", "type": "address" }, + { "internalType": "uint256", "name": "blockPosted", "type": "uint256" }, + { "internalType": "uint256", "name": "timestampPosted", "type": "uint256" } + ], + "internalType": "struct PoolRegistryInterface.VenusPool[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "comptroller", "type": "address" }], + "name": "getPoolByComptroller", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "address", "name": "creator", "type": "address" }, + { "internalType": "address", "name": "comptroller", "type": "address" }, + { "internalType": "uint256", "name": "blockPosted", "type": "uint256" }, + { "internalType": "uint256", "name": "timestampPosted", "type": "uint256" } + ], + "internalType": "struct PoolRegistryInterface.VenusPool", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "asset", "type": "address" }], + "name": "getPoolsSupportedByAsset", + "outputs": [{ "internalType": "address[]", "name": "", "type": "address[]" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "comptroller", "type": "address" }, + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getVTokenForAsset", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "comptroller", "type": "address" }], + "name": "getVenusPoolMetadata", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "category", "type": "string" }, + { "internalType": "string", "name": "logoURL", "type": "string" }, + { "internalType": "string", "name": "description", "type": "string" } + ], + "internalType": "struct PoolRegistryInterface.VenusPoolMetaData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "accessControlManager_", "type": "address" }], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "metadata", + "outputs": [ + { "internalType": "string", "name": "category", "type": "string" }, + { "internalType": "string", "name": "logoURL", "type": "string" }, + { "internalType": "string", "name": "description", "type": "string" } + ], + "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": [], "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": "comptroller", "type": "address" }, + { "internalType": "string", "name": "name", "type": "string" } + ], + "name": "setPoolName", + "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" }, + { + "components": [ + { "internalType": "string", "name": "category", "type": "string" }, + { "internalType": "string", "name": "logoURL", "type": "string" }, + { "internalType": "string", "name": "description", "type": "string" } + ], + "internalType": "struct PoolRegistryInterface.VenusPoolMetaData", + "name": "metadata_", + "type": "tuple" + } + ], + "name": "updatePoolMetadata", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/simulations/vip-178/vip-178-testnet/abi/rateModel.json b/simulations/vip-178/vip-178-testnet/abi/rateModel.json new file mode 100644 index 000000000..8c04a8527 --- /dev/null +++ b/simulations/vip-178/vip-178-testnet/abi/rateModel.json @@ -0,0 +1,118 @@ +[ + { + "inputs": [ + { "internalType": "uint256", "name": "baseRatePerYear", "type": "uint256" }, + { "internalType": "uint256", "name": "multiplierPerYear", "type": "uint256" }, + { "internalType": "uint256", "name": "jumpMultiplierPerYear", "type": "uint256" }, + { "internalType": "uint256", "name": "kink_", "type": "uint256" } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "baseRatePerBlock", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "multiplierPerBlock", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "jumpMultiplierPerBlock", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "kink", "type": "uint256" } + ], + "name": "NewInterestParams", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "baseRatePerBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "blocksPerYear", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "internalType": "uint256", "name": "cash", "type": "uint256" }, + { "internalType": "uint256", "name": "borrows", "type": "uint256" }, + { "internalType": "uint256", "name": "reserves", "type": "uint256" } + ], + "name": "getBorrowRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "internalType": "uint256", "name": "cash", "type": "uint256" }, + { "internalType": "uint256", "name": "borrows", "type": "uint256" }, + { "internalType": "uint256", "name": "reserves", "type": "uint256" }, + { "internalType": "uint256", "name": "reserveFactorMantissa", "type": "uint256" } + ], + "name": "getSupplyRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isInterestRateModel", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "jumpMultiplierPerBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kink", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "multiplierPerBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "internalType": "uint256", "name": "cash", "type": "uint256" }, + { "internalType": "uint256", "name": "borrows", "type": "uint256" }, + { "internalType": "uint256", "name": "reserves", "type": "uint256" } + ], + "name": "utilizationRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "pure", + "type": "function" + } +] diff --git a/simulations/vip-178/vip-178-testnet/abi/vToken.json b/simulations/vip-178/vip-178-testnet/abi/vToken.json new file mode 100644 index 000000000..a413ca84d --- /dev/null +++ b/simulations/vip-178/vip-178-testnet/abi/vToken.json @@ -0,0 +1,1872 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "actualAddAmount", + "type": "uint256" + } + ], + "name": "AddReservesFactorFreshCheck", + "type": "error" + }, + { + "inputs": [], + "name": "BorrowCashNotAvailable", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + } + ], + "name": "BorrowComptrollerRejection", + "type": "error" + }, + { + "inputs": [], + "name": "BorrowFreshnessCheck", + "type": "error" + }, + { + "inputs": [], + "name": "ForceLiquidateBorrowUnauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "HealBorrowUnauthorized", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + } + ], + "name": "LiquidateAccrueBorrowInterestFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + } + ], + "name": "LiquidateAccrueCollateralInterestFailed", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidateCloseAmountIsUintMax", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidateCloseAmountIsZero", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidateCollateralFreshnessCheck", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + } + ], + "name": "LiquidateComptrollerRejection", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidateFreshnessCheck", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidateLiquidatorIsBorrower", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + } + ], + "name": "LiquidateRepayBorrowFreshFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + } + ], + "name": "LiquidateSeizeComptrollerRejection", + "type": "error" + }, + { + "inputs": [], + "name": "LiquidateSeizeLiquidatorIsBorrower", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + } + ], + "name": "MintComptrollerRejection", + "type": "error" + }, + { + "inputs": [], + "name": "MintFreshnessCheck", + "type": "error" + }, + { + "inputs": [], + "name": "ProtocolSeizeShareTooBig", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + } + ], + "name": "RedeemComptrollerRejection", + "type": "error" + }, + { + "inputs": [], + "name": "RedeemFreshnessCheck", + "type": "error" + }, + { + "inputs": [], + "name": "RedeemTransferOutNotPossible", + "type": "error" + }, + { + "inputs": [], + "name": "ReduceReservesAdminCheck", + "type": "error" + }, + { + "inputs": [], + "name": "ReduceReservesCashNotAvailable", + "type": "error" + }, + { + "inputs": [], + "name": "ReduceReservesCashValidation", + "type": "error" + }, + { + "inputs": [], + "name": "ReduceReservesFreshCheck", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + } + ], + "name": "RepayBorrowComptrollerRejection", + "type": "error" + }, + { + "inputs": [], + "name": "RepayBorrowFreshnessCheck", + "type": "error" + }, + { + "inputs": [], + "name": "SetComptrollerOwnerCheck", + "type": "error" + }, + { + "inputs": [], + "name": "SetInterestRateModelFreshCheck", + "type": "error" + }, + { + "inputs": [], + "name": "SetInterestRateModelOwnerCheck", + "type": "error" + }, + { + "inputs": [], + "name": "SetProtocolSeizeShareUnauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "SetReserveFactorAdminCheck", + "type": "error" + }, + { + "inputs": [], + "name": "SetReserveFactorBoundsCheck", + "type": "error" + }, + { + "inputs": [], + "name": "SetReserveFactorFreshCheck", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "errorCode", + "type": "uint256" + } + ], + "name": "TransferComptrollerRejection", + "type": "error" + }, + { + "inputs": [], + "name": "TransferNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "TransferNotEnough", + "type": "error" + }, + { + "inputs": [], + "name": "TransferTooMuch", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "cashPrior", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "interestAccumulated", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "AccrueInterest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "badDebtDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "badDebtOld", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "badDebtNew", + "type": "uint256" + } + ], + "name": "BadDebtIncreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "badDebtOld", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "badDebtNew", + "type": "uint256" + } + ], + "name": "BadDebtRecovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "HealBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "vTokenCollateral", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "LiquidateBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "mintTokens", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBalance", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract AccessControlManager", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract AccessControlManager", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ComptrollerInterface", + "name": "oldComptroller", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract ComptrollerInterface", + "name": "newComptroller", + "type": "address" + } + ], + "name": "NewComptroller", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract InterestRateModel", + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldProtocolSeizeShareMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newProtocolSeizeShareMantissa", + "type": "uint256" + } + ], + "name": "NewProtocolSeizeShare", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldReserveFactorMantissa", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "NewReserveFactor", + "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": "redeemer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBalance", + "type": "uint256" + } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "accountBorrows", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalBorrows", + "type": "uint256" + } + ], + "name": "RepayBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "benefactor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newTotalReserves", + "type": "uint256" + } + ], + "name": "ReservesReduced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + } + ], + "name": "SweepToken", + "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": "amount", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "NO_ERROR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "contract AccessControlManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accrualBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accrueInterest", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "addAmount", + "type": "uint256" + } + ], + "name": "addReserves", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "badDebt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "recoveredAmount_", + "type": "uint256" + } + ], + "name": "badDebtRecovered", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOfUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "borrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "borrowBalanceStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comptroller", + "outputs": [ + { + "internalType": "contract ComptrollerInterface", + "name": "", + "type": "address" + } + ], + "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": [], + "name": "exchangeRateCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "exchangeRateStored", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "internalType": "contract VTokenInterface", + "name": "vTokenCollateral", + "type": "address" + }, + { + "internalType": "bool", + "name": "skipLiquidityCheck", + "type": "bool" + } + ], + "name": "forceLiquidateBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountSnapshot", + "outputs": [ + { + "internalType": "uint256", + "name": "error", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "vTokenBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "borrowBalance", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "exchangeRate", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCash", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "payer", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "healBorrow", + "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": [ + { + "internalType": "address", + "name": "underlying_", + "type": "address" + }, + { + "internalType": "contract ComptrollerInterface", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract InterestRateModel", + "name": "interestRateModel_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "initialExchangeRateMantissa_", + "type": "uint256" + }, + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "contract AccessControlManager", + "name": "accessControlManager_", + "type": "address" + }, + { + "components": [ + { + "internalType": "address", + "name": "shortfall", + "type": "address" + }, + { + "internalType": "address payable", + "name": "riskFund", + "type": "address" + }, + { + "internalType": "address payable", + "name": "protocolShareReserve", + "type": "address" + } + ], + "internalType": "struct VTokenInterface.RiskManagementInit", + "name": "riskManagement", + "type": "tuple" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "interestRateModel", + "outputs": [ + { + "internalType": "contract InterestRateModel", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isVToken", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + }, + { + "internalType": "contract VTokenInterface", + "name": "vTokenCollateral", + "type": "address" + } + ], + "name": "liquidateBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "mintAmount", + "type": "uint256" + } + ], + "name": "mintBehalf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolSeizeShareMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "redeemTokens", + "type": "uint256" + } + ], + "name": "redeem", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "redeemAmount", + "type": "uint256" + } + ], + "name": "redeemUnderlying", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "reduceAmount", + "type": "uint256" + } + ], + "name": "reduceReserves", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "repayAmount", + "type": "uint256" + } + ], + "name": "repayBorrowBehalf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "liquidator", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "seizeTokens", + "type": "uint256" + } + ], + "name": "seize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract AccessControlManager", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "setAccessControlAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "setInterestRateModel", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newProtocolSeizeShareMantissa_", + "type": "uint256" + } + ], + "name": "setProtocolSeizeShare", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newReserveFactorMantissa", + "type": "uint256" + } + ], + "name": "setReserveFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortfall", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "token", + "type": "address" + } + ], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBorrows", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBorrowsCurrent", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalReserves", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "src", + "type": "address" + }, + { + "internalType": "address", + "name": "dst", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlying", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/simulations/vip-178/vip-178-testnet/simulations.ts b/simulations/vip-178/vip-178-testnet/simulations.ts new file mode 100644 index 000000000..ea9675309 --- /dev/null +++ b/simulations/vip-178/vip-178-testnet/simulations.ts @@ -0,0 +1,261 @@ +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { expect } from "chai"; +import { BigNumberish } from "ethers"; +import { Contract } from "ethers"; +import { parseUnits } from "ethers/lib/utils"; +import { ethers } from "hardhat"; + +import { expectEvents } from "../../../src/utils"; +import { forking, testVip } from "../../../src/vip-framework"; +import { vip178Testnet } from "../../../vips/vip-178/vip-178-testnet"; +import COMPTROLLER_ABI from "./abi/comptroller.json"; +import ERC20_ABI from "./abi/erc20.json"; +import POOL_REGISTRY_ABI from "./abi/poolRegistry.json"; +import RATE_MODEL_ABI from "./abi/rateModel.json"; +import VTOKEN_ABI from "./abi/vToken.json"; + +const agEUR = "0x63061de4A25f24279AAab80400040684F92Ee319"; +const POOL_REGISTRY = "0xC85491616Fa949E048F3aAc39fbf5b0703800667"; +const vTOKEN_RECEIVER_agEUR = "0xDC2D855A95Ee70d7282BebD35c96f905CDE31f55"; +const VagEUR_Stablecoins = "0xa0571e758a00C586DbD53fb431d0f48eff9d0F15"; +const STABLECOIN_COMPTROLLER = "0x10b57706AD2345e590c2eA4DC02faef0d9f5b08B"; +const NORMAL_TIMELOCK = "0xce10739590001705F7FF231611ba4A48B2820327"; + +forking(33728751, () => { + let poolRegistry: Contract; + let comptroller: Contract; + let vagEUR: Contract; + + before(async () => { + poolRegistry = await ethers.getContractAt(POOL_REGISTRY_ABI, POOL_REGISTRY); + comptroller = await ethers.getContractAt(COMPTROLLER_ABI, STABLECOIN_COMPTROLLER); + vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); + }); + + describe("Contracts setup", () => { + const checkVToken = ( + vTokenAddress: string, + { + name, + symbol, + decimals, + underlying, + exchangeRate, + }: { + name: string; + symbol: string; + decimals: BigNumberish; + underlying: string; + exchangeRate: BigNumberish; + }, + ) => { + describe(symbol, () => { + let vToken: Contract; + + before(async () => { + vToken = await ethers.getContractAt(VTOKEN_ABI, vTokenAddress); + }); + + it(`should have name = "${name}"`, async () => { + expect(await vToken.name()).to.equal(name); + }); + + it(`should have symbol = "${symbol}"`, async () => { + expect(await vToken.symbol()).to.equal(symbol); + }); + + it(`should have ${decimals.toString()} decimals`, async () => { + expect(await vToken.decimals()).to.equal(decimals); + }); + + it(`should have underlying = "${underlying}"`, async () => { + expect(await vToken.underlying()).to.equal(underlying); + }); + + it(`should have initial exchange rate of ${exchangeRate.toString()}`, async () => { + expect(await vToken.exchangeRateStored()).to.equal(exchangeRate); + }); + + it("should have the correct Comptroller", async () => { + expect(await vToken.exchangeRateStored()).to.equal(exchangeRate); + }); + }); + }; + + checkVToken(VagEUR_Stablecoins, { + name: "Venus agEUR (Stablecoins)", + symbol: "vagEUR_Stablecoins", + decimals: 8, + underlying: agEUR, + exchangeRate: parseUnits("1", 28), + }); + }); + + testVip("VIP-178Testnet Add agEUR Market", vip178Testnet(), { + callbackAfterExecution: async (txResponse: TransactionResponse) => { + await expectEvents( + txResponse, + [COMPTROLLER_ABI, POOL_REGISTRY_ABI, ERC20_ABI], + ["Approval", "MarketAdded"], + [6, 1], + ); + }, + }); + + describe("Post-VIP state", () => { + describe("PoolRegistry state", () => { + it("should register pool's vTokens in Comptroller", async () => { + const vTokens = await comptroller.getAllMarkets(); + expect(vTokens).to.have.lengthOf(4); + expect(vTokens).to.include(VagEUR_Stablecoins); + }); + + it("should register in PoolRegistry", async () => { + const vToken = await poolRegistry.getVTokenForAsset(STABLECOIN_COMPTROLLER, agEUR); + expect(vToken).to.equal(VagEUR_Stablecoins); + }); + }); + + describe("Ownership", () => { + it("should transfer ownership to Timelock", async () => { + expect(await vagEUR.owner()).to.equal(NORMAL_TIMELOCK); + }); + }); + + describe("Initial supply", () => { + it(`should mint 10,000 vagEUR to ${vTOKEN_RECEIVER_agEUR}`, async () => { + expect(await vagEUR.balanceOf(vTOKEN_RECEIVER_agEUR)).to.equal(parseUnits("10000", 8)); + }); + }); + + describe("Market and risk parameters", () => { + const checkInterestRate = ( + vTokenAddress: string, + symbol: string, + { + base, + multiplier, + jump, + kink, + }: { + base: string; + multiplier: string; + jump: string; + kink: string; + }, + ) => { + describe(`${symbol} interest rate model`, () => { + const BLOCKS_PER_YEAR = 10512000; + let rateModel: Contract; + + before(async () => { + const vToken = await ethers.getContractAt(VTOKEN_ABI, vTokenAddress); + rateModel = await ethers.getContractAt(RATE_MODEL_ABI, await vToken.interestRateModel()); + }); + + it(`should have base = ${base}`, async () => { + const basePerBlock = parseUnits(base, 18).div(BLOCKS_PER_YEAR); + expect(await rateModel.baseRatePerBlock()).to.equal(basePerBlock); + }); + + it(`should have jump = ${jump}`, async () => { + const jumpPerBlock = parseUnits(jump, 18).div(BLOCKS_PER_YEAR); + expect(await rateModel.jumpMultiplierPerBlock()).to.equal(jumpPerBlock); + }); + + it(`should have multiplier = ${multiplier}`, async () => { + const multiplierPerBlock = parseUnits(multiplier, 18).div(BLOCKS_PER_YEAR); + expect(await rateModel.multiplierPerBlock()).to.equal(multiplierPerBlock); + }); + + it(`should have kink = ${kink}`, async () => { + expect(await rateModel.kink()).to.equal(parseUnits(kink, 18)); + }); + }); + }; + + describe("Interest rate models", () => { + checkInterestRate(VagEUR_Stablecoins, "VagEUR_Stablecoins", { + base: "0.02", + multiplier: "0.1", + jump: "2.5", + kink: "0.5", + }); + + describe("RF, CF, LT, Protocol seize share", () => { + it("should set VagEUR_Stablecoins reserve factor to 10%", async () => { + expect(await vagEUR.reserveFactorMantissa()).to.equal(parseUnits("0.10", 18)); + }); + + it("should set VagEUR_Stablecoins collateral factor to 75%", async () => { + const market = await comptroller.markets(VagEUR_Stablecoins); + expect(market.collateralFactorMantissa).to.equal(parseUnits("0.75", 18)); + }); + + it("should set VagEUR_Stablecoins liquidation threshold to 80%", async () => { + const market = await comptroller.markets(VagEUR_Stablecoins); + expect(market.liquidationThresholdMantissa).to.equal(parseUnits("0.80", 18)); + }); + + it("should set VagEUR_Stablecoins protocolSeizeShareMantissa to 5%", async () => { + const protocolSeizeShare = await vagEUR.protocolSeizeShareMantissa(); + expect(protocolSeizeShare).to.equal(parseUnits("0.05", 18)); + }); + }); + + describe("Caps", () => { + it("should set VagEUR_Stablecoins borrow cap to 50,000", async () => { + expect(await comptroller.borrowCaps(VagEUR_Stablecoins)).to.equal(parseUnits("50000", 18)); + }); + + it("should set VagEUR_Stablecoins supply cap to 1,00,000", async () => { + expect(await comptroller.supplyCaps(VagEUR_Stablecoins)).to.equal(parseUnits("100000", 18)); + }); + }); + }); + }); + + describe("Basic supply/borrow/repay/redeem scenario", () => { + let agEURUnderlying: Contract; + let vagEUR: Contract; + let user: SignerWithAddress; + + before(async () => { + [user] = await ethers.getSigners(); + agEURUnderlying = await ethers.getContractAt(ERC20_ABI, agEUR); + vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); + await agEURUnderlying.faucet(parseUnits("100", 18)); + }); + + it("should be possible to supply", async () => { + await agEURUnderlying.approve(vagEUR.address, parseUnits("100", 18)); + await vagEUR.mint(parseUnits("100", 18)); + expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits("100", 8)); + }); + + it("should be possible to enable the as collateral", async () => { + await comptroller.connect(user).enterMarkets([VagEUR_Stablecoins]); + expect(await comptroller.getAssetsIn(user.address)).to.deep.equal([VagEUR_Stablecoins]); + }); + + it("should be possible to borrow agEUR", async () => { + await vagEUR.connect(user).borrow(1000000); + expect(await vagEUR.borrowBalanceStored(user.address)).to.equal(1000000); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(1000000); + }); + + it("should be possible to repay agEUR", async () => { + await agEURUnderlying.approve(vagEUR.address, 1000000); + await vagEUR.repayBorrow(1000000); + expect(await vagEUR.borrowBalanceStored(user.address)).to.be.lessThan(parseUnits("0.01", 18)); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(0); + }); + + it("should be possible to redeem a part of total", async () => { + await vagEUR.redeemUnderlying(parseUnits("30", 18)); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(parseUnits("30", 18)); + expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits("70", 8)); + }); + }); + }); +}); diff --git a/simulations/vip-178/vip-178/abi/comptroller.json b/simulations/vip-178/vip-178/abi/comptroller.json new file mode 100644 index 000000000..f8d85ef31 --- /dev/null +++ b/simulations/vip-178/vip-178/abi/comptroller.json @@ -0,0 +1,769 @@ +[ + { + "inputs": [{ "internalType": "address", "name": "poolRegistry_", "type": "address" }], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "market", "type": "address" }, + { "internalType": "enum ComptrollerStorage.Action", "name": "action", "type": "uint8" } + ], + "name": "ActionPaused", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "market", "type": "address" }, + { "internalType": "uint256", "name": "cap", "type": "uint256" } + ], + "name": "BorrowCapExceeded", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "expectedLessThanOrEqualTo", "type": "uint256" }, + { "internalType": "uint256", "name": "actual", "type": "uint256" } + ], + "name": "CollateralExceedsThreshold", + "type": "error" + }, + { "inputs": [], "name": "ComptrollerMismatch", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "collateralToSeize", "type": "uint256" }, + { "internalType": "uint256", "name": "availableCollateral", "type": "uint256" } + ], + "name": "InsufficientCollateral", + "type": "error" + }, + { "inputs": [], "name": "InsufficientLiquidity", "type": "error" }, + { "inputs": [], "name": "InsufficientShortfall", "type": "error" }, + { "inputs": [], "name": "InvalidCollateralFactor", "type": "error" }, + { "inputs": [], "name": "InvalidLiquidationThreshold", "type": "error" }, + { + "inputs": [{ "internalType": "address", "name": "market", "type": "address" }], + "name": "MarketAlreadyListed", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "MarketNotCollateral", + "type": "error" + }, + { + "inputs": [{ "internalType": "address", "name": "market", "type": "address" }], + "name": "MarketNotListed", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "loopsLimit", "type": "uint256" }, + { "internalType": "uint256", "name": "requiredLoops", "type": "uint256" } + ], + "name": "MaxLoopsLimitExceeded", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "expectedGreaterThan", "type": "uint256" }, + { "internalType": "uint256", "name": "actual", "type": "uint256" } + ], + "name": "MinimalCollateralViolated", + "type": "error" + }, + { "inputs": [], "name": "NonzeroBorrowBalance", "type": "error" }, + { + "inputs": [{ "internalType": "address", "name": "vToken", "type": "address" }], + "name": "PriceError", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "user", "type": "address" } + ], + "name": "SnapshotError", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "market", "type": "address" }, + { "internalType": "uint256", "name": "cap", "type": "uint256" } + ], + "name": "SupplyCapExceeded", + "type": "error" + }, + { "inputs": [], "name": "TooMuchRepay", "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": [ + { "internalType": "address", "name": "expectedSender", "type": "address" }, + { "internalType": "address", "name": "actualSender", "type": "address" } + ], + "name": "UnexpectedSender", + "type": "error" + }, + { "inputs": [], "name": "ZeroAddressNotAllowed", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "contract VToken", "name": "vToken", "type": "address" }, + { "indexed": false, "internalType": "enum ComptrollerStorage.Action", "name": "action", "type": "uint8" }, + { "indexed": false, "internalType": "bool", "name": "pauseState", "type": "bool" } + ], + "name": "ActionPausedMarket", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint8", "name": "version", "type": "uint8" }], + "name": "Initialized", + "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": false, "internalType": "contract VToken", "name": "vToken", "type": "address" }], + "name": "MarketSupported", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "oldMaxLoopsLimit", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newmaxLoopsLimit", "type": "uint256" } + ], + "name": "MaxLoopsLimitUpdated", + "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": "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": false, "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": "uint256", "name": "oldLiquidationIncentiveMantissa", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newLiquidationIncentiveMantissa", "type": "uint256" } + ], + "name": "NewLiquidationIncentive", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "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": "uint256", "name": "oldMinLiquidatableCollateral", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newMinLiquidatableCollateral", "type": "uint256" } + ], + "name": "NewMinLiquidatableCollateral", + "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": true, "internalType": "address", "name": "rewardsDistributor", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "rewardToken", "type": "address" } + ], + "name": "NewRewardsDistributor", + "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": 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" + }, + { "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": "", "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 ComptrollerStorage.Action", "name": "action", "type": "uint8" } + ], + "name": "actionPaused", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract RewardsDistributor", "name": "_rewardsDistributor", "type": "address" }], + "name": "addRewardsDistributor", + "outputs": [], + "stateMutability": "nonpayable", + "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" }], + "name": "borrowCaps", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "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": [], + "name": "closeFactorMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address[]", "name": "vTokens", "type": "address[]" }], + "name": "enterMarkets", + "outputs": [{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }], + "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": "address", "name": "account", "type": "address" }], + "name": "getAccountLiquidity", + "outputs": [ + { "internalType": "uint256", "name": "error", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidity", "type": "uint256" }, + { "internalType": "uint256", "name": "shortfall", "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": "error", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidity", "type": "uint256" }, + { "internalType": "uint256", "name": "shortfall", "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": "error", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidity", "type": "uint256" }, + { "internalType": "uint256", "name": "shortfall", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getRewardDistributors", + "outputs": [{ "internalType": "contract RewardsDistributor[]", "name": "", "type": "address[]" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "vToken", "type": "address" }], + "name": "getRewardsByMarket", + "outputs": [ + { + "components": [ + { "internalType": "address", "name": "rewardToken", "type": "address" }, + { "internalType": "uint256", "name": "supplySpeed", "type": "uint256" }, + { "internalType": "uint256", "name": "borrowSpeed", "type": "uint256" } + ], + "internalType": "struct ComptrollerStorage.RewardSpeeds[]", + "name": "rewardSpeeds", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "user", "type": "address" }], + "name": "healAccount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "loopLimit", "type": "uint256" }, + { "internalType": "address", "name": "accessControlManager", "type": "address" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "isComptroller", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract VToken", "name": "vToken", "type": "address" }], + "name": "isDeprecated", + "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": [ + { "internalType": "address", "name": "borrower", "type": "address" }, + { + "components": [ + { "internalType": "contract VToken", "name": "vTokenCollateral", "type": "address" }, + { "internalType": "contract VToken", "name": "vTokenBorrowed", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "internalType": "struct ComptrollerStorage.LiquidationOrder[]", + "name": "orders", + "type": "tuple[]" + } + ], + "name": "liquidateAccount", + "outputs": [], + "stateMutability": "nonpayable", + "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": "error", "type": "uint256" }, + { "internalType": "uint256", "name": "tokensToSeize", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidationIncentiveMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "markets", + "outputs": [ + { "internalType": "bool", "name": "isListed", "type": "bool" }, + { "internalType": "uint256", "name": "collateralFactorMantissa", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidationThresholdMantissa", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLoopsLimit", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minLiquidatableCollateral", + "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": "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": [], + "name": "poolRegistry", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "borrowAmount", "type": "uint256" } + ], + "name": "preBorrowHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vTokenBorrowed", "type": "address" }, + { "internalType": "address", "name": "vTokenCollateral", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "internalType": "bool", "name": "skipLiquidityCheck", "type": "bool" } + ], + "name": "preLiquidateHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "minter", "type": "address" }, + { "internalType": "uint256", "name": "mintAmount", "type": "uint256" } + ], + "name": "preMintHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "redeemer", "type": "address" }, + { "internalType": "uint256", "name": "redeemTokens", "type": "uint256" } + ], + "name": "preRedeemHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vToken", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" } + ], + "name": "preRepayHook", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "vTokenCollateral", "type": "address" }, + { "internalType": "address", "name": "seizerContract", "type": "address" }, + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" } + ], + "name": "preSeizeHook", + "outputs": [], + "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": "preTransferHook", + "outputs": [], + "stateMutability": "nonpayable", + "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": "contract VToken[]", "name": "marketsList", "type": "address[]" }, + { "internalType": "enum ComptrollerStorage.Action[]", "name": "actionsList", "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": [], + "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": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "newLiquidationIncentiveMantissa", "type": "uint256" }], + "name": "setLiquidationIncentive", + "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": "uint256", "name": "limit", "type": "uint256" }], + "name": "setMaxLoopsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "newMinLiquidatableCollateral", "type": "uint256" }], + "name": "setMinLiquidatableCollateral", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract ResilientOracleInterface", "name": "newOracle", "type": "address" }], + "name": "setPriceOracle", + "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": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "updatePrices", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/simulations/vip-178/vip-178/abi/erc20.json b/simulations/vip-178/vip-178/abi/erc20.json new file mode 100644 index 000000000..3a509c9c4 --- /dev/null +++ b/simulations/vip-178/vip-178/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-178/vip-178/abi/poolRegistry.json b/simulations/vip-178/vip-178/abi/poolRegistry.json new file mode 100644 index 000000000..8f15277d2 --- /dev/null +++ b/simulations/vip-178/vip-178/abi/poolRegistry.json @@ -0,0 +1,310 @@ +[ + { "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" + }, + { "inputs": [], "name": "ZeroAddressNotAllowed", "type": "error" }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint8", "name": "version", "type": "uint8" }], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "comptroller", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "vTokenAddress", "type": "address" } + ], + "name": "MarketAdded", + "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" }, + { + "components": [ + { "internalType": "string", "name": "category", "type": "string" }, + { "internalType": "string", "name": "logoURL", "type": "string" }, + { "internalType": "string", "name": "description", "type": "string" } + ], + "indexed": false, + "internalType": "struct PoolRegistryInterface.VenusPoolMetaData", + "name": "oldMetadata", + "type": "tuple" + }, + { + "components": [ + { "internalType": "string", "name": "category", "type": "string" }, + { "internalType": "string", "name": "logoURL", "type": "string" }, + { "internalType": "string", "name": "description", "type": "string" } + ], + "indexed": false, + "internalType": "struct PoolRegistryInterface.VenusPoolMetaData", + "name": "newMetadata", + "type": "tuple" + } + ], + "name": "PoolMetadataUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "comptroller", "type": "address" }, + { "indexed": false, "internalType": "string", "name": "oldName", "type": "string" }, + { "indexed": false, "internalType": "string", "name": "newName", "type": "string" } + ], + "name": "PoolNameSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "comptroller", "type": "address" }, + { + "components": [ + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "address", "name": "creator", "type": "address" }, + { "internalType": "address", "name": "comptroller", "type": "address" }, + { "internalType": "uint256", "name": "blockPosted", "type": "uint256" }, + { "internalType": "uint256", "name": "timestampPosted", "type": "uint256" } + ], + "indexed": false, + "internalType": "struct PoolRegistryInterface.VenusPool", + "name": "pool", + "type": "tuple" + } + ], + "name": "PoolRegistered", + "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": [ + { + "components": [ + { "internalType": "contract VToken", "name": "vToken", "type": "address" }, + { "internalType": "uint256", "name": "collateralFactor", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidationThreshold", "type": "uint256" }, + { "internalType": "uint256", "name": "initialSupply", "type": "uint256" }, + { "internalType": "address", "name": "vTokenReceiver", "type": "address" }, + { "internalType": "uint256", "name": "supplyCap", "type": "uint256" }, + { "internalType": "uint256", "name": "borrowCap", "type": "uint256" } + ], + "internalType": "struct PoolRegistry.AddMarketInput", + "name": "input", + "type": "tuple" + } + ], + "name": "addMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "contract Comptroller", "name": "comptroller", "type": "address" }, + { "internalType": "uint256", "name": "closeFactor", "type": "uint256" }, + { "internalType": "uint256", "name": "liquidationIncentive", "type": "uint256" }, + { "internalType": "uint256", "name": "minLiquidatableCollateral", "type": "uint256" } + ], + "name": "addPool", + "outputs": [{ "internalType": "uint256", "name": "index", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAllPools", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "address", "name": "creator", "type": "address" }, + { "internalType": "address", "name": "comptroller", "type": "address" }, + { "internalType": "uint256", "name": "blockPosted", "type": "uint256" }, + { "internalType": "uint256", "name": "timestampPosted", "type": "uint256" } + ], + "internalType": "struct PoolRegistryInterface.VenusPool[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "comptroller", "type": "address" }], + "name": "getPoolByComptroller", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "address", "name": "creator", "type": "address" }, + { "internalType": "address", "name": "comptroller", "type": "address" }, + { "internalType": "uint256", "name": "blockPosted", "type": "uint256" }, + { "internalType": "uint256", "name": "timestampPosted", "type": "uint256" } + ], + "internalType": "struct PoolRegistryInterface.VenusPool", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "asset", "type": "address" }], + "name": "getPoolsSupportedByAsset", + "outputs": [{ "internalType": "address[]", "name": "", "type": "address[]" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "comptroller", "type": "address" }, + { "internalType": "address", "name": "asset", "type": "address" } + ], + "name": "getVTokenForAsset", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "comptroller", "type": "address" }], + "name": "getVenusPoolMetadata", + "outputs": [ + { + "components": [ + { "internalType": "string", "name": "category", "type": "string" }, + { "internalType": "string", "name": "logoURL", "type": "string" }, + { "internalType": "string", "name": "description", "type": "string" } + ], + "internalType": "struct PoolRegistryInterface.VenusPoolMetaData", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "accessControlManager_", "type": "address" }], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "", "type": "address" }], + "name": "metadata", + "outputs": [ + { "internalType": "string", "name": "category", "type": "string" }, + { "internalType": "string", "name": "logoURL", "type": "string" }, + { "internalType": "string", "name": "description", "type": "string" } + ], + "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": [], "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": "comptroller", "type": "address" }, + { "internalType": "string", "name": "name", "type": "string" } + ], + "name": "setPoolName", + "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" }, + { + "components": [ + { "internalType": "string", "name": "category", "type": "string" }, + { "internalType": "string", "name": "logoURL", "type": "string" }, + { "internalType": "string", "name": "description", "type": "string" } + ], + "internalType": "struct PoolRegistryInterface.VenusPoolMetaData", + "name": "metadata_", + "type": "tuple" + } + ], + "name": "updatePoolMetadata", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/simulations/vip-178/vip-178/abi/rateModel.json b/simulations/vip-178/vip-178/abi/rateModel.json new file mode 100644 index 000000000..8c04a8527 --- /dev/null +++ b/simulations/vip-178/vip-178/abi/rateModel.json @@ -0,0 +1,118 @@ +[ + { + "inputs": [ + { "internalType": "uint256", "name": "baseRatePerYear", "type": "uint256" }, + { "internalType": "uint256", "name": "multiplierPerYear", "type": "uint256" }, + { "internalType": "uint256", "name": "jumpMultiplierPerYear", "type": "uint256" }, + { "internalType": "uint256", "name": "kink_", "type": "uint256" } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "baseRatePerBlock", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "multiplierPerBlock", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "jumpMultiplierPerBlock", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "kink", "type": "uint256" } + ], + "name": "NewInterestParams", + "type": "event" + }, + { + "constant": true, + "inputs": [], + "name": "baseRatePerBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "blocksPerYear", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "internalType": "uint256", "name": "cash", "type": "uint256" }, + { "internalType": "uint256", "name": "borrows", "type": "uint256" }, + { "internalType": "uint256", "name": "reserves", "type": "uint256" } + ], + "name": "getBorrowRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "internalType": "uint256", "name": "cash", "type": "uint256" }, + { "internalType": "uint256", "name": "borrows", "type": "uint256" }, + { "internalType": "uint256", "name": "reserves", "type": "uint256" }, + { "internalType": "uint256", "name": "reserveFactorMantissa", "type": "uint256" } + ], + "name": "getSupplyRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isInterestRateModel", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "jumpMultiplierPerBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "kink", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "multiplierPerBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { "internalType": "uint256", "name": "cash", "type": "uint256" }, + { "internalType": "uint256", "name": "borrows", "type": "uint256" }, + { "internalType": "uint256", "name": "reserves", "type": "uint256" } + ], + "name": "utilizationRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "payable": false, + "stateMutability": "pure", + "type": "function" + } +] diff --git a/simulations/vip-178/vip-178/abi/vToken.json b/simulations/vip-178/vip-178/abi/vToken.json new file mode 100644 index 000000000..7ac5306db --- /dev/null +++ b/simulations/vip-178/vip-178/abi/vToken.json @@ -0,0 +1,790 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [{ "internalType": "uint256", "name": "actualAddAmount", "type": "uint256" }], + "name": "AddReservesFactorFreshCheck", + "type": "error" + }, + { "inputs": [], "name": "BorrowCashNotAvailable", "type": "error" }, + { "inputs": [], "name": "BorrowFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "ForceLiquidateBorrowUnauthorized", "type": "error" }, + { "inputs": [], "name": "HealBorrowUnauthorized", "type": "error" }, + { + "inputs": [{ "internalType": "uint256", "name": "errorCode", "type": "uint256" }], + "name": "LiquidateAccrueCollateralInterestFailed", + "type": "error" + }, + { "inputs": [], "name": "LiquidateCloseAmountIsUintMax", "type": "error" }, + { "inputs": [], "name": "LiquidateCloseAmountIsZero", "type": "error" }, + { "inputs": [], "name": "LiquidateCollateralFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "LiquidateFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "LiquidateLiquidatorIsBorrower", "type": "error" }, + { "inputs": [], "name": "LiquidateSeizeLiquidatorIsBorrower", "type": "error" }, + { "inputs": [], "name": "MintFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "ProtocolSeizeShareTooBig", "type": "error" }, + { "inputs": [], "name": "RedeemFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "RedeemTransferOutNotPossible", "type": "error" }, + { "inputs": [], "name": "ReduceReservesCashNotAvailable", "type": "error" }, + { "inputs": [], "name": "ReduceReservesCashValidation", "type": "error" }, + { "inputs": [], "name": "ReduceReservesFreshCheck", "type": "error" }, + { "inputs": [], "name": "RepayBorrowFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "SetInterestRateModelFreshCheck", "type": "error" }, + { "inputs": [], "name": "SetReserveFactorBoundsCheck", "type": "error" }, + { "inputs": [], "name": "SetReserveFactorFreshCheck", "type": "error" }, + { "inputs": [], "name": "TransferNotAllowed", "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" }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "cashPrior", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "interestAccumulated", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "borrowIndex", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "totalBorrows", "type": "uint256" } + ], + "name": "AccrueInterest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtDelta", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtOld", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtNew", "type": "uint256" } + ], + "name": "BadDebtIncreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "badDebtOld", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtNew", "type": "uint256" } + ], + "name": "BadDebtRecovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "borrowAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBorrows", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "totalBorrows", "type": "uint256" } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "payer", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "name": "HealBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint8", "name": "version", "type": "uint8" }], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "liquidator", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "vTokenCollateral", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } + ], + "name": "LiquidateBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "minter", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "mintAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "mintTokens", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBalance", "type": "uint256" } + ], + "name": "Mint", + "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": "contract ComptrollerInterface", "name": "oldComptroller", "type": "address" }, + { "indexed": true, "internalType": "contract ComptrollerInterface", "name": "newComptroller", "type": "address" } + ], + "name": "NewComptroller", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract InterestRateModel", + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "oldProtocolSeizeShareMantissa", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newProtocolSeizeShareMantissa", "type": "uint256" } + ], + "name": "NewProtocolSeizeShare", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "oldProtocolShareReserve", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newProtocolShareReserve", "type": "address" } + ], + "name": "NewProtocolShareReserve", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "oldReserveFactorMantissa", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newReserveFactorMantissa", "type": "uint256" } + ], + "name": "NewReserveFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "oldShortfall", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newShortfall", "type": "address" } + ], + "name": "NewShortfallContract", + "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": "redeemer", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "redeemAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "redeemTokens", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBalance", "type": "uint256" } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "payer", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBorrows", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "totalBorrows", "type": "uint256" } + ], + "name": "RepayBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "benefactor", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "addAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newTotalReserves", "type": "uint256" } + ], + "name": "ReservesAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "admin", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "reduceAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newTotalReserves", "type": "uint256" } + ], + "name": "ReservesReduced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": true, "internalType": "address", "name": "token", "type": "address" }], + "name": "SweepToken", + "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": "amount", "type": "uint256" } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "NO_ERROR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "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": "accrualBlockNumber", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accrueInterest", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "addAmount", "type": "uint256" }], + "name": "addReserves", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "badDebt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "recoveredAmount_", "type": "uint256" }], + "name": "badDebtRecovered", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], + "name": "balanceOfUnderlying", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "borrowAmount", "type": "uint256" }], + "name": "borrow", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "borrowBalanceCurrent", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "borrowBalanceStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comptroller", + "outputs": [{ "internalType": "contract ComptrollerInterface", "name": "", "type": "address" }], + "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": [], + "name": "exchangeRateCurrent", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "exchangeRateStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "internalType": "contract VTokenInterface", "name": "vTokenCollateral", "type": "address" }, + { "internalType": "bool", "name": "skipLiquidityCheck", "type": "bool" } + ], + "name": "forceLiquidateBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "getAccountSnapshot", + "outputs": [ + { "internalType": "uint256", "name": "error", "type": "uint256" }, + { "internalType": "uint256", "name": "vTokenBalance", "type": "uint256" }, + { "internalType": "uint256", "name": "borrowBalance", "type": "uint256" }, + { "internalType": "uint256", "name": "exchangeRate", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCash", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "payer", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "name": "healBorrow", + "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": [ + { "internalType": "address", "name": "underlying_", "type": "address" }, + { "internalType": "contract ComptrollerInterface", "name": "comptroller_", "type": "address" }, + { "internalType": "contract InterestRateModel", "name": "interestRateModel_", "type": "address" }, + { "internalType": "uint256", "name": "initialExchangeRateMantissa_", "type": "uint256" }, + { "internalType": "string", "name": "name_", "type": "string" }, + { "internalType": "string", "name": "symbol_", "type": "string" }, + { "internalType": "uint8", "name": "decimals_", "type": "uint8" }, + { "internalType": "address", "name": "admin_", "type": "address" }, + { "internalType": "address", "name": "accessControlManager_", "type": "address" }, + { + "components": [ + { "internalType": "address", "name": "shortfall", "type": "address" }, + { "internalType": "address payable", "name": "protocolShareReserve", "type": "address" } + ], + "internalType": "struct VTokenInterface.RiskManagementInit", + "name": "riskManagement", + "type": "tuple" + }, + { "internalType": "uint256", "name": "reserveFactorMantissa_", "type": "uint256" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "interestRateModel", + "outputs": [{ "internalType": "contract InterestRateModel", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isVToken", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "internalType": "contract VTokenInterface", "name": "vTokenCollateral", "type": "address" } + ], + "name": "liquidateBorrow", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "mintAmount", "type": "uint256" }], + "name": "mint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "minter", "type": "address" }, + { "internalType": "uint256", "name": "mintAmount", "type": "uint256" } + ], + "name": "mintBehalf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolSeizeShareMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolShareReserve", + "outputs": [{ "internalType": "address payable", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "redeemTokens", "type": "uint256" }], + "name": "redeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "redeemAmount", "type": "uint256" }], + "name": "redeemUnderlying", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "reduceAmount", "type": "uint256" }], + "name": "reduceReserves", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [{ "internalType": "uint256", "name": "repayAmount", "type": "uint256" }], + "name": "repayBorrow", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "name": "repayBorrowBehalf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } + ], + "name": "seize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "accessControlManager_", "type": "address" }], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract InterestRateModel", "name": "newInterestRateModel", "type": "address" }], + "name": "setInterestRateModel", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "newProtocolSeizeShareMantissa_", "type": "uint256" }], + "name": "setProtocolSeizeShare", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address payable", "name": "protocolShareReserve_", "type": "address" }], + "name": "setProtocolShareReserve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "newReserveFactorMantissa", "type": "uint256" }], + "name": "setReserveFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "shortfall_", "type": "address" }], + "name": "setShortfallContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortfall", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract IERC20Upgradeable", "name": "token", "type": "address" }], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBorrows", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBorrowsCurrent", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalReserves", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlying", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/simulations/vip-178/vip-178/simulations.ts b/simulations/vip-178/vip-178/simulations.ts new file mode 100644 index 000000000..36a4c2a20 --- /dev/null +++ b/simulations/vip-178/vip-178/simulations.ts @@ -0,0 +1,263 @@ +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; +import { expect } from "chai"; +import { BigNumberish } from "ethers"; +import { Contract } from "ethers"; +import { parseUnits } from "ethers/lib/utils"; +import { ethers } from "hardhat"; + +import { expectEvents, initMainnetUser } from "../../../src/utils"; +import { forking, testVip } from "../../../src/vip-framework"; +import { vip178 } from "../../../vips/vip-178/vip-178"; +import COMPTROLLER_ABI from "./abi/comptroller.json"; +import ERC20_ABI from "./abi/erc20.json"; +import POOL_REGISTRY_ABI from "./abi/poolRegistry.json"; +import RATE_MODEL_ABI from "./abi/rateModel.json"; +import VTOKEN_ABI from "./abi/vToken.json"; + +const agEUR = "0x12f31b73d812c6bb0d735a218c086d44d5fe5f89"; +const POOL_REGISTRY = "0x9F7b01A536aFA00EF10310A162877fd792cD0666"; +const VTOKEN_RECEIVER_agEUR = "0xDC2D855A95Ee70d7282BebD35c96f905CDE31f55"; +const VagEUR_Stablecoins = "0x1a9D2862028F6f5E6C299A7AC3C285508942b15E"; +const STABLECOIN_COMPTROLLER = "0x94c1495cD4c557f1560Cbd68EAB0d197e6291571"; +const NORMAL_TIMELOCK = "0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396"; + +forking(32130712, () => { + let poolRegistry: Contract; + let comptroller: Contract; + let vagEUR: Contract; + + before(async () => { + poolRegistry = await ethers.getContractAt(POOL_REGISTRY_ABI, POOL_REGISTRY); + comptroller = await ethers.getContractAt(COMPTROLLER_ABI, STABLECOIN_COMPTROLLER); + vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); + }); + + describe("Contracts setup", () => { + const checkVToken = ( + vTokenAddress: string, + { + name, + symbol, + decimals, + underlying, + exchangeRate, + }: { + name: string; + symbol: string; + decimals: BigNumberish; + underlying: string; + exchangeRate: BigNumberish; + }, + ) => { + describe(symbol, () => { + let vToken: Contract; + + before(async () => { + vToken = await ethers.getContractAt(VTOKEN_ABI, vTokenAddress); + }); + + it(`should have name = "${name}"`, async () => { + expect(await vToken.name()).to.equal(name); + }); + + it(`should have symbol = "${symbol}"`, async () => { + expect(await vToken.symbol()).to.equal(symbol); + }); + + it(`should have ${decimals.toString()} decimals`, async () => { + expect(await vToken.decimals()).to.equal(decimals); + }); + + it(`should have underlying = "${underlying}"`, async () => { + expect(await vToken.underlying()).to.equal(underlying); + }); + + it(`should have initial exchange rate of ${exchangeRate.toString()}`, async () => { + expect(await vToken.exchangeRateStored()).to.equal(exchangeRate); + }); + + it("should have the correct Comptroller", async () => { + expect(await vToken.exchangeRateStored()).to.equal(exchangeRate); + }); + }); + }; + + checkVToken(VagEUR_Stablecoins, { + name: "Venus agEUR (Stablecoins)", + symbol: "vagEUR_Stablecoins", + decimals: 8, + underlying: agEUR, + exchangeRate: parseUnits("1", 28), + }); + }); + + testVip("VIP-178 Add agEUR Market", vip178(24 * 60 * 60 * 3), { + callbackAfterExecution: async (txResponse: TransactionResponse) => { + await expectEvents( + txResponse, + [COMPTROLLER_ABI, POOL_REGISTRY_ABI, ERC20_ABI], + ["Approval", "MarketAdded"], + [6, 1], + ); + }, + }); + + describe("Post-VIP state", () => { + describe("PoolRegistry state", () => { + it("should register pool's vTokens in Comptroller", async () => { + const vTokens = await comptroller.getAllMarkets(); + expect(vTokens).to.have.lengthOf(4); + expect(vTokens).to.include(VagEUR_Stablecoins); + }); + + it("should register in PoolRegistry", async () => { + const vToken = await poolRegistry.getVTokenForAsset(STABLECOIN_COMPTROLLER, agEUR); + expect(vToken).to.equal(VagEUR_Stablecoins); + }); + }); + + describe("Ownership", () => { + it("should transfer ownership to Timelock", async () => { + expect(await vagEUR.owner()).to.equal(NORMAL_TIMELOCK); + }); + }); + + describe("Initial supply", () => { + it(`should mint 10,000 vagEUR to ${VTOKEN_RECEIVER_agEUR}`, async () => { + expect(await vagEUR.balanceOf(VTOKEN_RECEIVER_agEUR)).to.equal(parseUnits("10000", 8)); + }); + }); + + describe("Market and risk parameters", () => { + const checkInterestRate = ( + vTokenAddress: string, + symbol: string, + { + base, + multiplier, + jump, + kink, + }: { + base: string; + multiplier: string; + jump: string; + kink: string; + }, + ) => { + describe(`${symbol} interest rate model`, () => { + const BLOCKS_PER_YEAR = 10512000; + let rateModel: Contract; + + before(async () => { + const vToken = await ethers.getContractAt(VTOKEN_ABI, vTokenAddress); + rateModel = await ethers.getContractAt(RATE_MODEL_ABI, await vToken.interestRateModel()); + }); + + it(`should have base = ${base}`, async () => { + const basePerBlock = parseUnits(base, 18).div(BLOCKS_PER_YEAR); + expect(await rateModel.baseRatePerBlock()).to.equal(basePerBlock); + }); + + it(`should have jump = ${jump}`, async () => { + const jumpPerBlock = parseUnits(jump, 18).div(BLOCKS_PER_YEAR); + expect(await rateModel.jumpMultiplierPerBlock()).to.equal(jumpPerBlock); + }); + + it(`should have multiplier = ${multiplier}`, async () => { + const multiplierPerBlock = parseUnits(multiplier, 18).div(BLOCKS_PER_YEAR); + expect(await rateModel.multiplierPerBlock()).to.equal(multiplierPerBlock); + }); + + it(`should have kink = ${kink}`, async () => { + expect(await rateModel.kink()).to.equal(parseUnits(kink, 18)); + }); + }); + }; + + describe("Interest rate models", () => { + checkInterestRate(VagEUR_Stablecoins, "VagEUR_Stablecoins", { + base: "0.02", + multiplier: "0.1", + jump: "2.5", + kink: "0.5", + }); + + describe("RF, CF, LT, Protocol seize share", () => { + it("should set VagEUR_Stablecoins reserve factor to 10%", async () => { + expect(await vagEUR.reserveFactorMantissa()).to.equal(parseUnits("0.10", 18)); + }); + + it("should set VagEUR_Stablecoins collateral factor to 75%", async () => { + const market = await comptroller.markets(VagEUR_Stablecoins); + expect(market.collateralFactorMantissa).to.equal(parseUnits("0.75", 18)); + }); + + it("should set VagEUR_Stablecoins liquidation threshold to 80%", async () => { + const market = await comptroller.markets(VagEUR_Stablecoins); + expect(market.liquidationThresholdMantissa).to.equal(parseUnits("0.80", 18)); + }); + + it("should set VagEUR_Stablecoins protocolSeizeShareMantissa to 5%", async () => { + const protocolSeizeShare = await vagEUR.protocolSeizeShareMantissa(); + expect(protocolSeizeShare).to.equal(parseUnits("0.05", 18)); + }); + }); + + describe("Caps", () => { + it("should set VagEUR_Stablecoins borrow cap to 50,000", async () => { + expect(await comptroller.borrowCaps(VagEUR_Stablecoins)).to.equal(parseUnits("50000", 18)); + }); + + it("should set VagEUR_Stablecoins supply cap to 1,00,000", async () => { + expect(await comptroller.supplyCaps(VagEUR_Stablecoins)).to.equal(parseUnits("100000", 18)); + }); + }); + }); + }); + + describe("Basic supply/borrow/repay/redeem scenario", () => { + let agEURUnderlying: Contract; + let vagEUR: Contract; + let user: SignerWithAddress; + + before(async () => { + [user] = await ethers.getSigners(); + const agEUR_HOLDER = "0x7B1db35fbd95548777B9079527e8fa2a70fb2CE0"; + agEURUnderlying = await ethers.getContractAt(ERC20_ABI, agEUR); + vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); + const agEUR_holder = await initMainnetUser(agEUR_HOLDER, parseUnits("1", 18)); + await agEURUnderlying.connect(agEUR_holder).transfer(user.address, parseUnits(".00005", 18)); + }); + + it("should be possible to supply", async () => { + await agEURUnderlying.approve(vagEUR.address, parseUnits(".00005", 18)); + await vagEUR.mint(parseUnits(".00005", 18)); + expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits(".00005", 8)); + }); + + it("should be possible to enable the as collateral", async () => { + await comptroller.connect(user).enterMarkets([VagEUR_Stablecoins]); + expect(await comptroller.getAssetsIn(user.address)).to.deep.equal([VagEUR_Stablecoins]); + }); + + it("should be possible to borrow agEUR", async () => { + await vagEUR.connect(user).borrow(1000000); + expect(await vagEUR.borrowBalanceStored(user.address)).to.equal(1000000); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(1000000); + }); + + it("should be possible to repay agEUR", async () => { + await agEURUnderlying.approve(vagEUR.address, 1000000); + await vagEUR.repayBorrow(1000000); + expect(await vagEUR.borrowBalanceStored(user.address)).to.be.lessThan(parseUnits("0.01", 18)); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(0); + }); + + it("should be possible to redeem a part of total", async () => { + await vagEUR.redeemUnderlying(parseUnits(".00001", 18)); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(parseUnits(".00001", 18)); + expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits(".00004", 8)); + }); + }); + }); +}); diff --git a/vips/vip-178/vip-178-testnet.ts b/vips/vip-178/vip-178-testnet.ts new file mode 100644 index 000000000..c9e1cd507 --- /dev/null +++ b/vips/vip-178/vip-178-testnet.ts @@ -0,0 +1,80 @@ +import { parseUnits } from "ethers/lib/utils"; + +import { ProposalType } from "../../src/types"; +import { makeProposal } from "../../src/utils"; + +const agEUR = "0x63061de4A25f24279AAab80400040684F92Ee319"; +const POOL_REGISTRY = "0xC85491616Fa949E048F3aAc39fbf5b0703800667"; +const VTOKEN_RECEIVER_agEUR = "0xDC2D855A95Ee70d7282BebD35c96f905CDE31f55"; // To be revised +const vagEUR_StableCoins = "0xa0571e758a00C586DbD53fb431d0f48eff9d0F15"; +const CHAINLINK_ORACLE = "0xCeA29f1266e880A1482c06eD656cD08C148BaA32"; +const RESILIENT_ORACLE = "0x3cD69251D04A28d887Ac14cbe2E14c52F3D57823"; + +export const vip178Testnet = () => { + const meta = { + version: "v2", + title: "VIP-178 Add agEUR market to Stablecoin Pool", + description: ``, + forDescription: "I agree that Venus Protocol should proceed with add market", + againstDescription: "I do not think that Venus Protocol should proceed with add market", + abstainDescription: "I am indifferent to whether Venus Protocol proceeds with add market", + }; + + return makeProposal( + [ + { + target: CHAINLINK_ORACLE, + signature: "setDirectPrice(address,uint256)", + params: [agEUR, parseUnits("1.06", 18)], + }, + { + target: RESILIENT_ORACLE, + signature: "setTokenConfig((address,address[3],bool[3]))", + params: [ + [ + agEUR, + [ + CHAINLINK_ORACLE, + "0x0000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000", + ], + [true, false, false], + ], + ], + }, + + { + target: agEUR, + signature: "faucet(uint256)", + params: [parseUnits("10000", 18)], + }, + { + target: agEUR, + signature: "approve(address,uint256)", + params: [POOL_REGISTRY, "0"], + }, + { + target: agEUR, + signature: "approve(address,uint256)", + params: [POOL_REGISTRY, parseUnits("10000", 18)], + }, + { + target: POOL_REGISTRY, + signature: "addMarket((address,uint256,uint256,uint256,address,uint256,uint256))", + params: [ + [ + vagEUR_StableCoins, + parseUnits("0.75", 18), + parseUnits("0.8", 18), + parseUnits("10000", 18), // To be revised + VTOKEN_RECEIVER_agEUR, + parseUnits("100000", 18), + parseUnits("50000", 18), + ], + ], + }, + ], + meta, + ProposalType.REGULAR, + ); +}; diff --git a/vips/vip-178/vip-178.ts b/vips/vip-178/vip-178.ts new file mode 100644 index 000000000..a8b7a1b23 --- /dev/null +++ b/vips/vip-178/vip-178.ts @@ -0,0 +1,88 @@ +import { parseUnits } from "ethers/lib/utils"; + +import { ProposalType } from "../../src/types"; +import { makeProposal } from "../../src/utils"; + +const agEUR = "0x12f31b73d812c6bb0d735a218c086d44d5fe5f89"; +const POOL_REGISTRY = "0x9F7b01A536aFA00EF10310A162877fd792cD0666"; +const VTOKEN_RECEIVER_agEUR = "0xDC2D855A95Ee70d7282BebD35c96f905CDE31f55"; // To be revised +const vagEUR_StableCoin = "0x1a9D2862028F6f5E6C299A7AC3C285508942b15E"; +const BINANCE_ORACLE = "0x594810b741d136f1960141C0d8Fb4a91bE78A820"; +const RESILIENT_ORACLE = "0x6592b5DE802159F3E74B2486b091D11a8256ab8A"; +const TREASURY = "0xF322942f644A996A617BD29c16bd7d231d9F35E9"; +const NORMAL_TIMELOCK = "0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396"; +const MAX_STALE_PERIOD = 60 * 25; + +export const vip178 = (maxStalePeriod?: number) => { + const meta = { + version: "v2", + title: "VIP-178 Add agEUR market to Stablecoin Pool", + description: ``, + forDescription: "I agree that Venus Protocol should proceed with add market", + againstDescription: "I do not think that Venus Protocol should proceed with add market", + abstainDescription: "I am indifferent to whether Venus Protocol proceeds with add market", + }; + + return makeProposal( + [ + { + target: BINANCE_ORACLE, + signature: "setSymbolOverride(string,string)", + params: ["agEUR", "AGEUR"], + }, + { + target: BINANCE_ORACLE, + signature: "setMaxStalePeriod(string,uint256)", + params: ["AGEUR", maxStalePeriod || MAX_STALE_PERIOD], + }, + { + target: RESILIENT_ORACLE, + signature: "setTokenConfig((address,address[3],bool[3]))", + params: [ + [ + agEUR, + [ + BINANCE_ORACLE, + "0x0000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000", + ], + [true, false, false], + ], + ], + }, + + { + target: TREASURY, + signature: "withdrawTreasuryBEP20(address,uint256,address)", + params: [agEUR, parseUnits("10000", 18), NORMAL_TIMELOCK], + }, + { + target: agEUR, + signature: "approve(address,uint256)", + params: [POOL_REGISTRY, "0"], + }, + { + target: agEUR, + signature: "approve(address,uint256)", + params: [POOL_REGISTRY, parseUnits("10000", 18)], + }, + { + target: POOL_REGISTRY, + signature: "addMarket((address,uint256,uint256,uint256,address,uint256,uint256))", + params: [ + [ + vagEUR_StableCoin, + parseUnits("0.75", 18), + parseUnits("0.8", 18), + parseUnits("10000", 18), // To be revised + VTOKEN_RECEIVER_agEUR, + parseUnits("100000", 18), + parseUnits("50000", 18), + ], + ], + }, + ], + meta, + ProposalType.REGULAR, + ); +}; From 372353d168ef9bbf5b50fa6160bfd22caf4980a9 Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Thu, 28 Sep 2023 14:31:18 +0530 Subject: [PATCH 02/10] chore: update initial supply and vtoken receiver --- simulations/vip-178/vip-178-testnet/simulations.ts | 6 +++--- simulations/vip-178/vip-178/simulations.ts | 6 +++--- vips/vip-178/vip-178-testnet.ts | 4 ++-- vips/vip-178/vip-178.ts | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/simulations/vip-178/vip-178-testnet/simulations.ts b/simulations/vip-178/vip-178-testnet/simulations.ts index ea9675309..ea2c85c22 100644 --- a/simulations/vip-178/vip-178-testnet/simulations.ts +++ b/simulations/vip-178/vip-178-testnet/simulations.ts @@ -16,7 +16,7 @@ import VTOKEN_ABI from "./abi/vToken.json"; const agEUR = "0x63061de4A25f24279AAab80400040684F92Ee319"; const POOL_REGISTRY = "0xC85491616Fa949E048F3aAc39fbf5b0703800667"; -const vTOKEN_RECEIVER_agEUR = "0xDC2D855A95Ee70d7282BebD35c96f905CDE31f55"; +const vTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; const VagEUR_Stablecoins = "0xa0571e758a00C586DbD53fb431d0f48eff9d0F15"; const STABLECOIN_COMPTROLLER = "0x10b57706AD2345e590c2eA4DC02faef0d9f5b08B"; const NORMAL_TIMELOCK = "0xce10739590001705F7FF231611ba4A48B2820327"; @@ -123,8 +123,8 @@ forking(33728751, () => { }); describe("Initial supply", () => { - it(`should mint 10,000 vagEUR to ${vTOKEN_RECEIVER_agEUR}`, async () => { - expect(await vagEUR.balanceOf(vTOKEN_RECEIVER_agEUR)).to.equal(parseUnits("10000", 8)); + it(`should mint 9,000 vagEUR to ${vTOKEN_RECEIVER_agEUR}`, async () => { + expect(await vagEUR.balanceOf(vTOKEN_RECEIVER_agEUR)).to.equal(parseUnits("9000", 8)); }); }); diff --git a/simulations/vip-178/vip-178/simulations.ts b/simulations/vip-178/vip-178/simulations.ts index 36a4c2a20..28d0cbd2d 100644 --- a/simulations/vip-178/vip-178/simulations.ts +++ b/simulations/vip-178/vip-178/simulations.ts @@ -16,7 +16,7 @@ import VTOKEN_ABI from "./abi/vToken.json"; const agEUR = "0x12f31b73d812c6bb0d735a218c086d44d5fe5f89"; const POOL_REGISTRY = "0x9F7b01A536aFA00EF10310A162877fd792cD0666"; -const VTOKEN_RECEIVER_agEUR = "0xDC2D855A95Ee70d7282BebD35c96f905CDE31f55"; +const VTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; const VagEUR_Stablecoins = "0x1a9D2862028F6f5E6C299A7AC3C285508942b15E"; const STABLECOIN_COMPTROLLER = "0x94c1495cD4c557f1560Cbd68EAB0d197e6291571"; const NORMAL_TIMELOCK = "0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396"; @@ -123,8 +123,8 @@ forking(32130712, () => { }); describe("Initial supply", () => { - it(`should mint 10,000 vagEUR to ${VTOKEN_RECEIVER_agEUR}`, async () => { - expect(await vagEUR.balanceOf(VTOKEN_RECEIVER_agEUR)).to.equal(parseUnits("10000", 8)); + it(`should mint 9,000 vagEUR to ${VTOKEN_RECEIVER_agEUR}`, async () => { + expect(await vagEUR.balanceOf(VTOKEN_RECEIVER_agEUR)).to.equal(parseUnits("9000", 8)); }); }); diff --git a/vips/vip-178/vip-178-testnet.ts b/vips/vip-178/vip-178-testnet.ts index c9e1cd507..f36325d43 100644 --- a/vips/vip-178/vip-178-testnet.ts +++ b/vips/vip-178/vip-178-testnet.ts @@ -5,7 +5,7 @@ import { makeProposal } from "../../src/utils"; const agEUR = "0x63061de4A25f24279AAab80400040684F92Ee319"; const POOL_REGISTRY = "0xC85491616Fa949E048F3aAc39fbf5b0703800667"; -const VTOKEN_RECEIVER_agEUR = "0xDC2D855A95Ee70d7282BebD35c96f905CDE31f55"; // To be revised +const VTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; const vagEUR_StableCoins = "0xa0571e758a00C586DbD53fb431d0f48eff9d0F15"; const CHAINLINK_ORACLE = "0xCeA29f1266e880A1482c06eD656cD08C148BaA32"; const RESILIENT_ORACLE = "0x3cD69251D04A28d887Ac14cbe2E14c52F3D57823"; @@ -66,7 +66,7 @@ export const vip178Testnet = () => { vagEUR_StableCoins, parseUnits("0.75", 18), parseUnits("0.8", 18), - parseUnits("10000", 18), // To be revised + parseUnits("9000", 18), VTOKEN_RECEIVER_agEUR, parseUnits("100000", 18), parseUnits("50000", 18), diff --git a/vips/vip-178/vip-178.ts b/vips/vip-178/vip-178.ts index a8b7a1b23..604a359ae 100644 --- a/vips/vip-178/vip-178.ts +++ b/vips/vip-178/vip-178.ts @@ -5,7 +5,7 @@ import { makeProposal } from "../../src/utils"; const agEUR = "0x12f31b73d812c6bb0d735a218c086d44d5fe5f89"; const POOL_REGISTRY = "0x9F7b01A536aFA00EF10310A162877fd792cD0666"; -const VTOKEN_RECEIVER_agEUR = "0xDC2D855A95Ee70d7282BebD35c96f905CDE31f55"; // To be revised +const VTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; const vagEUR_StableCoin = "0x1a9D2862028F6f5E6C299A7AC3C285508942b15E"; const BINANCE_ORACLE = "0x594810b741d136f1960141C0d8Fb4a91bE78A820"; const RESILIENT_ORACLE = "0x6592b5DE802159F3E74B2486b091D11a8256ab8A"; @@ -74,7 +74,7 @@ export const vip178 = (maxStalePeriod?: number) => { vagEUR_StableCoin, parseUnits("0.75", 18), parseUnits("0.8", 18), - parseUnits("10000", 18), // To be revised + parseUnits("9000", 18), VTOKEN_RECEIVER_agEUR, parseUnits("100000", 18), parseUnits("50000", 18), From b15b6a0093c4bae9aeeb0f16eefeda428d9b0198 Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Thu, 28 Sep 2023 17:31:05 +0530 Subject: [PATCH 03/10] feat: add reward distributor simulations --- .../abi/rewardsDistributor.json | 1129 +++++++++++++++++ .../vip-178/vip-178-testnet/simulations.ts | 51 +- .../vip-178/abi/rewardsDistributor.json | 1129 +++++++++++++++++ simulations/vip-178/vip-178/simulations.ts | 49 +- vips/vip-178/vip-178-testnet.ts | 30 + vips/vip-178/vip-178.ts | 52 +- 6 files changed, 2432 insertions(+), 8 deletions(-) create mode 100644 simulations/vip-178/vip-178-testnet/abi/rewardsDistributor.json create mode 100644 simulations/vip-178/vip-178/abi/rewardsDistributor.json diff --git a/simulations/vip-178/vip-178-testnet/abi/rewardsDistributor.json b/simulations/vip-178/vip-178-testnet/abi/rewardsDistributor.json new file mode 100644 index 000000000..7035bb9a5 --- /dev/null +++ b/simulations/vip-178/vip-178-testnet/abi/rewardsDistributor.json @@ -0,0 +1,1129 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "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" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAccrued", + "type": "uint256" + } + ], + "name": "ContributorRewardsUpdated", + "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": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerRewardToken", + "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": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "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": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "RewardTokenBorrowIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardTokenGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "RewardTokenSupplyIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "SupplyLastRewardingBlockUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_INDEX", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "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": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "supplier", + "type": "address" + } + ], + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Comptroller", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "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": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardTokenSpeed", + "type": "uint256" + } + ], + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" + } + ], + "name": "setLastRewardingBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "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": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateRewardTokenSupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } +] diff --git a/simulations/vip-178/vip-178-testnet/simulations.ts b/simulations/vip-178/vip-178-testnet/simulations.ts index ea2c85c22..ff42c8b31 100644 --- a/simulations/vip-178/vip-178-testnet/simulations.ts +++ b/simulations/vip-178/vip-178-testnet/simulations.ts @@ -12,6 +12,7 @@ import COMPTROLLER_ABI from "./abi/comptroller.json"; import ERC20_ABI from "./abi/erc20.json"; import POOL_REGISTRY_ABI from "./abi/poolRegistry.json"; import RATE_MODEL_ABI from "./abi/rateModel.json"; +import REWARD_DISTRIBUTOR_ABI from "./abi/rewardsDistributor.json"; import VTOKEN_ABI from "./abi/vToken.json"; const agEUR = "0x63061de4A25f24279AAab80400040684F92Ee319"; @@ -20,16 +21,20 @@ const vTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; const VagEUR_Stablecoins = "0xa0571e758a00C586DbD53fb431d0f48eff9d0F15"; const STABLECOIN_COMPTROLLER = "0x10b57706AD2345e590c2eA4DC02faef0d9f5b08B"; const NORMAL_TIMELOCK = "0xce10739590001705F7FF231611ba4A48B2820327"; +const REWARD_DISTRIBUTOR = "0x78d32FC46e5025c29e3BA03Fcf2840323351F26a"; +const ANGLE = "0xD1Bc731d188ACc3f52a6226B328a89056B0Ec71a"; -forking(33728751, () => { +forking(33734613, () => { let poolRegistry: Contract; let comptroller: Contract; let vagEUR: Contract; + let rewardsDistributor: Contract; before(async () => { poolRegistry = await ethers.getContractAt(POOL_REGISTRY_ABI, POOL_REGISTRY); comptroller = await ethers.getContractAt(COMPTROLLER_ABI, STABLECOIN_COMPTROLLER); vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); + rewardsDistributor = await ethers.getContractAt(REWARD_DISTRIBUTOR_ABI, REWARD_DISTRIBUTOR); }); describe("Contracts setup", () => { @@ -95,9 +100,16 @@ forking(33728751, () => { callbackAfterExecution: async (txResponse: TransactionResponse) => { await expectEvents( txResponse, - [COMPTROLLER_ABI, POOL_REGISTRY_ABI, ERC20_ABI], - ["Approval", "MarketAdded"], - [6, 1], + [COMPTROLLER_ABI, POOL_REGISTRY_ABI, ERC20_ABI, REWARD_DISTRIBUTOR_ABI], + [ + "Approval", + "MarketAdded", + "NewRewardsDistributor", + "RewardTokenSupplySpeedUpdated", + "RewardTokenBorrowSpeedUpdated", + "OwnershipTransferred", + ], + [6, 1, 1, 0, 1, 3], ); }, }); @@ -215,6 +227,37 @@ forking(33728751, () => { }); }); + describe("Reward Distributor", () => { + it("should be added to Stable coins Pool", async () => { + expect(await comptroller.getRewardDistributors()).to.include(REWARD_DISTRIBUTOR); + }); + + it("should have 3 rewards distributor in Stable coins Pool", async () => { + expect(await comptroller.getRewardDistributors()).to.have.lengthOf(3); + }); + + it("should have rewardToken ANGLE", async () => { + expect(await rewardsDistributor.rewardToken()).to.equal(ANGLE); + }); + + it(`should have owner = Normal Timelock`, async () => { + expect(await rewardsDistributor.owner()).to.equal(NORMAL_TIMELOCK); + }); + + it("should have borrowSpeed = 87,549,603,174,603,174", async () => { + expect(await rewardsDistributor.rewardTokenBorrowSpeeds(VagEUR_Stablecoins)).to.equal("87549603174603174"); + }); + + it("should have supplySpeed = 0", async () => { + expect(await rewardsDistributor.rewardTokenSupplySpeeds(VagEUR_Stablecoins)).to.equal("0"); + }); + + it("should have balance = 17,650 ANGLE", async () => { + const token = await ethers.getContractAt(ERC20_ABI, ANGLE); + expect(await token.balanceOf(rewardsDistributor.address)).to.equal(parseUnits("17650", 18)); + }); + }); + describe("Basic supply/borrow/repay/redeem scenario", () => { let agEURUnderlying: Contract; let vagEUR: Contract; diff --git a/simulations/vip-178/vip-178/abi/rewardsDistributor.json b/simulations/vip-178/vip-178/abi/rewardsDistributor.json new file mode 100644 index 000000000..7035bb9a5 --- /dev/null +++ b/simulations/vip-178/vip-178/abi/rewardsDistributor.json @@ -0,0 +1,1129 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "beacon", + "type": "address" + } + ], + "name": "BeaconUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { + "stateMutability": "payable", + "type": "fallback" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "admin_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "implementation", + "outputs": [ + { + "internalType": "address", + "name": "implementation_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newImplementation", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeToAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "loopsLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "requiredLoops", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitExceeded", + "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" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "BorrowLastRewardingBlockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "ContributorRewardTokenSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAccrued", + "type": "uint256" + } + ], + "name": "ContributorRewardsUpdated", + "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": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenBorrowIndex", + "type": "uint256" + } + ], + "name": "DistributedBorrowerRewardToken", + "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": "rewardTokenDelta", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenTotal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardTokenSupplyIndex", + "type": "uint256" + } + ], + "name": "DistributedSupplierRewardToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "MarketInitialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "oldMaxLoopsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newmaxLoopsLimit", + "type": "uint256" + } + ], + "name": "MaxLoopsLimitUpdated", + "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": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "indexed": false, + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "RewardTokenBorrowIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenBorrowSpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "RewardTokenGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "RewardTokenSupplyIndexUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract VToken", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newSpeed", + "type": "uint256" + } + ], + "name": "RewardTokenSupplySpeedUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint32", + "name": "newBlock", + "type": "uint32" + } + ], + "name": "SupplyLastRewardingBlockUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "INITIAL_INDEX", + "outputs": [ + { + "internalType": "uint224", + "name": "", + "type": "uint224" + } + ], + "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": "holder", + "type": "address" + }, + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "holder", + "type": "address" + } + ], + "name": "claimRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "distributeBorrowerRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "internalType": "address", + "name": "supplier", + "type": "address" + } + ], + "name": "distributeSupplierRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "grantRewardToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract Comptroller", + "name": "comptroller_", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "rewardToken_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "loopsLimit_", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "initializeMarket", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "lastContributorBlock", + "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": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenAccrued", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenBorrowerIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenContributorSpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplierIndex", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplySpeeds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "rewardTokenSupplyState", + "outputs": [ + { + "internalType": "uint224", + "name": "index", + "type": "uint224" + }, + { + "internalType": "uint32", + "name": "block", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "lastRewardingBlock", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardTokenSpeed", + "type": "uint256" + } + ], + "name": "setContributorRewardTokenSpeed", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract VToken[]", + "name": "vTokens", + "type": "address[]" + }, + { + "internalType": "uint32[]", + "name": "supplyLastRewardingBlocks", + "type": "uint32[]" + }, + { + "internalType": "uint32[]", + "name": "borrowLastRewardingBlocks", + "type": "uint32[]" + } + ], + "name": "setLastRewardingBlocks", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "limit", + "type": "uint256" + } + ], + "name": "setMaxLoopsLimit", + "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": "setRewardTokenSpeeds", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "contributor", + "type": "address" + } + ], + "name": "updateContributorRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "mantissa", + "type": "uint256" + } + ], + "internalType": "struct ExponentialNoError.Exp", + "name": "marketBorrowIndex", + "type": "tuple" + } + ], + "name": "updateRewardTokenBorrowIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "vToken", + "type": "address" + } + ], + "name": "updateRewardTokenSupplyIndex", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_logic", + "type": "address" + }, + { + "internalType": "address", + "name": "admin_", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_data", + "type": "bytes" + } + ], + "stateMutability": "payable", + "type": "constructor" + } +] diff --git a/simulations/vip-178/vip-178/simulations.ts b/simulations/vip-178/vip-178/simulations.ts index 28d0cbd2d..c85dc852d 100644 --- a/simulations/vip-178/vip-178/simulations.ts +++ b/simulations/vip-178/vip-178/simulations.ts @@ -12,6 +12,7 @@ import COMPTROLLER_ABI from "./abi/comptroller.json"; import ERC20_ABI from "./abi/erc20.json"; import POOL_REGISTRY_ABI from "./abi/poolRegistry.json"; import RATE_MODEL_ABI from "./abi/rateModel.json"; +import REWARD_DISTRIBUTOR_ABI from "./abi/rewardsDistributor.json"; import VTOKEN_ABI from "./abi/vToken.json"; const agEUR = "0x12f31b73d812c6bb0d735a218c086d44d5fe5f89"; @@ -20,16 +21,20 @@ const VTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; const VagEUR_Stablecoins = "0x1a9D2862028F6f5E6C299A7AC3C285508942b15E"; const STABLECOIN_COMPTROLLER = "0x94c1495cD4c557f1560Cbd68EAB0d197e6291571"; const NORMAL_TIMELOCK = "0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396"; +const REWARD_DISTRIBUTOR = "0x177ED4625F57cEa2804EA3A396c8Ff78f314F1CA"; +const ANGLE = "0x97B6897AAd7aBa3861c04C0e6388Fc02AF1F227f"; -forking(32130712, () => { +forking(32136210, () => { let poolRegistry: Contract; let comptroller: Contract; let vagEUR: Contract; + let rewardsDistributor: Contract; before(async () => { poolRegistry = await ethers.getContractAt(POOL_REGISTRY_ABI, POOL_REGISTRY); comptroller = await ethers.getContractAt(COMPTROLLER_ABI, STABLECOIN_COMPTROLLER); vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); + rewardsDistributor = await ethers.getContractAt(REWARD_DISTRIBUTOR_ABI, REWARD_DISTRIBUTOR); }); describe("Contracts setup", () => { @@ -96,8 +101,15 @@ forking(32130712, () => { await expectEvents( txResponse, [COMPTROLLER_ABI, POOL_REGISTRY_ABI, ERC20_ABI], - ["Approval", "MarketAdded"], - [6, 1], + [ + "Approval", + "MarketAdded", + "NewRewardsDistributor", + "RewardTokenSupplySpeedUpdated", + "RewardTokenBorrowSpeedUpdated", + "OwnershipTransferred", + ], + [6, 1, 1, 0, 1, 3], ); }, }); @@ -215,6 +227,37 @@ forking(32130712, () => { }); }); + describe("Reward Distributor", () => { + it("should be added to Stable coins Pool", async () => { + expect(await comptroller.getRewardDistributors()).to.include(REWARD_DISTRIBUTOR); + }); + + it("should have 5 rewards distributor in Stable coins Pool", async () => { + expect(await comptroller.getRewardDistributors()).to.have.lengthOf(2); + }); + + it("should have rewardToken ANGLE", async () => { + expect(await rewardsDistributor.rewardToken()).to.equal(ANGLE); + }); + + it(`should have owner = Normal Timelock`, async () => { + expect(await rewardsDistributor.owner()).to.equal(NORMAL_TIMELOCK); + }); + + it("should have borrowSpeed = 87,549,603,174,603,174", async () => { + expect(await rewardsDistributor.rewardTokenBorrowSpeeds(VagEUR_Stablecoins)).to.equal("87549603174603174"); + }); + + it("should have supplySpeed = 0", async () => { + expect(await rewardsDistributor.rewardTokenSupplySpeeds(VagEUR_Stablecoins)).to.equal("0"); + }); + + it("should have balance = 17,650 ANGLE", async () => { + const token = await ethers.getContractAt(ERC20_ABI, ANGLE); + expect(await token.balanceOf(rewardsDistributor.address)).to.equal(parseUnits("17650", 18)); + }); + }); + describe("Basic supply/borrow/repay/redeem scenario", () => { let agEURUnderlying: Contract; let vagEUR: Contract; diff --git a/vips/vip-178/vip-178-testnet.ts b/vips/vip-178/vip-178-testnet.ts index f36325d43..0303e08fc 100644 --- a/vips/vip-178/vip-178-testnet.ts +++ b/vips/vip-178/vip-178-testnet.ts @@ -9,6 +9,9 @@ const VTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; const vagEUR_StableCoins = "0xa0571e758a00C586DbD53fb431d0f48eff9d0F15"; const CHAINLINK_ORACLE = "0xCeA29f1266e880A1482c06eD656cD08C148BaA32"; const RESILIENT_ORACLE = "0x3cD69251D04A28d887Ac14cbe2E14c52F3D57823"; +const REWARD_DISTRIBUTOR = "0x78d32FC46e5025c29e3BA03Fcf2840323351F26a"; +const STABLECOIN_COMPTROLLER = "0x10b57706AD2345e590c2eA4DC02faef0d9f5b08B"; +const ANGLE = "0xD1Bc731d188ACc3f52a6226B328a89056B0Ec71a"; export const vip178Testnet = () => { const meta = { @@ -73,6 +76,33 @@ export const vip178Testnet = () => { ], ], }, + + { + target: ANGLE, + signature: "faucet(uint256)", + params: [parseUnits("17650", 18)], + }, + + { + target: REWARD_DISTRIBUTOR, + signature: "acceptOwnership()", + params: [], + }, + { + target: ANGLE, + signature: "transfer(address,uint256)", + params: [REWARD_DISTRIBUTOR, parseUnits("17650", 18)], + }, + { + target: STABLECOIN_COMPTROLLER, + signature: "addRewardsDistributor(address)", + params: [REWARD_DISTRIBUTOR], + }, + { + target: REWARD_DISTRIBUTOR, + signature: "setRewardTokenSpeeds(address[],uint256[],uint256[])", + params: [[vagEUR_StableCoins], ["0"], ["87549603174603174"]], + }, ], meta, ProposalType.REGULAR, diff --git a/vips/vip-178/vip-178.ts b/vips/vip-178/vip-178.ts index 604a359ae..0000a720e 100644 --- a/vips/vip-178/vip-178.ts +++ b/vips/vip-178/vip-178.ts @@ -11,7 +11,10 @@ const BINANCE_ORACLE = "0x594810b741d136f1960141C0d8Fb4a91bE78A820"; const RESILIENT_ORACLE = "0x6592b5DE802159F3E74B2486b091D11a8256ab8A"; const TREASURY = "0xF322942f644A996A617BD29c16bd7d231d9F35E9"; const NORMAL_TIMELOCK = "0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396"; -const MAX_STALE_PERIOD = 60 * 25; +const REWARD_DISTRIBUTOR = "0x177ED4625F57cEa2804EA3A396c8Ff78f314F1CA"; +const ANGLE = "0x97B6897AAd7aBa3861c04C0e6388Fc02AF1F227f"; +const STABLECOIN_COMPTROLLER = "0x94c1495cD4c557f1560Cbd68EAB0d197e6291571"; +const MAX_STALE_PERIOD = 60 * 100; export const vip178 = (maxStalePeriod?: number) => { const meta = { @@ -51,6 +54,27 @@ export const vip178 = (maxStalePeriod?: number) => { ], }, + { + target: BINANCE_ORACLE, + signature: "setMaxStalePeriod(string,uint256)", + params: ["ANGLE", maxStalePeriod || MAX_STALE_PERIOD], + }, + { + target: RESILIENT_ORACLE, + signature: "setTokenConfig((address,address[3],bool[3]))", + params: [ + [ + ANGLE, + [ + BINANCE_ORACLE, + "0x0000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000", + ], + [true, false, false], + ], + ], + }, + { target: TREASURY, signature: "withdrawTreasuryBEP20(address,uint256,address)", @@ -81,6 +105,32 @@ export const vip178 = (maxStalePeriod?: number) => { ], ], }, + { + target: TREASURY, + signature: "withdrawTreasuryBEP20(address,uint256,address)", + params: [agEUR, parseUnits("17650", 18), NORMAL_TIMELOCK], + }, + + { + target: REWARD_DISTRIBUTOR, + signature: "acceptOwnership()", + params: [], + }, + { + target: ANGLE, + signature: "transfer(address,uint256)", + params: [REWARD_DISTRIBUTOR, parseUnits("17650", 18)], + }, + { + target: STABLECOIN_COMPTROLLER, + signature: "addRewardsDistributor(address)", + params: [REWARD_DISTRIBUTOR], + }, + { + target: REWARD_DISTRIBUTOR, + signature: "setRewardTokenSpeeds(address[],uint256[],uint256[])", + params: [[vagEUR_StableCoin], ["0"], ["87549603174603174"]], + }, ], meta, ProposalType.REGULAR, From ab3775867d5e5c64694a0003f69ca486347f62b4 Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Thu, 28 Sep 2023 19:09:39 +0530 Subject: [PATCH 04/10] fix: resove comments --- vips/vip-178/vip-178-testnet.ts | 9 +++++++-- vips/vip-178/vip-178.ts | 13 +++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/vips/vip-178/vip-178-testnet.ts b/vips/vip-178/vip-178-testnet.ts index 0303e08fc..787c81cf6 100644 --- a/vips/vip-178/vip-178-testnet.ts +++ b/vips/vip-178/vip-178-testnet.ts @@ -30,6 +30,11 @@ export const vip178Testnet = () => { signature: "setDirectPrice(address,uint256)", params: [agEUR, parseUnits("1.06", 18)], }, + { + target: CHAINLINK_ORACLE, + signature: "setDirectPrice(address,uint256)", + params: [ANGLE, parseUnits(".032", 18)], + }, { target: RESILIENT_ORACLE, signature: "setTokenConfig((address,address[3],bool[3]))", @@ -49,7 +54,7 @@ export const vip178Testnet = () => { { target: agEUR, signature: "faucet(uint256)", - params: [parseUnits("10000", 18)], + params: [parseUnits("9000", 18)], }, { target: agEUR, @@ -59,7 +64,7 @@ export const vip178Testnet = () => { { target: agEUR, signature: "approve(address,uint256)", - params: [POOL_REGISTRY, parseUnits("10000", 18)], + params: [POOL_REGISTRY, parseUnits("9000", 18)], }, { target: POOL_REGISTRY, diff --git a/vips/vip-178/vip-178.ts b/vips/vip-178/vip-178.ts index 0000a720e..f3d39e29c 100644 --- a/vips/vip-178/vip-178.ts +++ b/vips/vip-178/vip-178.ts @@ -14,7 +14,8 @@ const NORMAL_TIMELOCK = "0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396"; const REWARD_DISTRIBUTOR = "0x177ED4625F57cEa2804EA3A396c8Ff78f314F1CA"; const ANGLE = "0x97B6897AAd7aBa3861c04C0e6388Fc02AF1F227f"; const STABLECOIN_COMPTROLLER = "0x94c1495cD4c557f1560Cbd68EAB0d197e6291571"; -const MAX_STALE_PERIOD = 60 * 100; +const MAX_STALE_PERIOD_AGEUR = 60 * 100; +const MAX_STALE_PERIOD_ANGLE = 60 * 25; export const vip178 = (maxStalePeriod?: number) => { const meta = { @@ -36,7 +37,7 @@ export const vip178 = (maxStalePeriod?: number) => { { target: BINANCE_ORACLE, signature: "setMaxStalePeriod(string,uint256)", - params: ["AGEUR", maxStalePeriod || MAX_STALE_PERIOD], + params: ["AGEUR", maxStalePeriod || MAX_STALE_PERIOD_AGEUR], }, { target: RESILIENT_ORACLE, @@ -57,7 +58,7 @@ export const vip178 = (maxStalePeriod?: number) => { { target: BINANCE_ORACLE, signature: "setMaxStalePeriod(string,uint256)", - params: ["ANGLE", maxStalePeriod || MAX_STALE_PERIOD], + params: ["ANGLE", maxStalePeriod || MAX_STALE_PERIOD_ANGLE], }, { target: RESILIENT_ORACLE, @@ -78,7 +79,7 @@ export const vip178 = (maxStalePeriod?: number) => { { target: TREASURY, signature: "withdrawTreasuryBEP20(address,uint256,address)", - params: [agEUR, parseUnits("10000", 18), NORMAL_TIMELOCK], + params: [agEUR, parseUnits("9000", 18), NORMAL_TIMELOCK], }, { target: agEUR, @@ -88,7 +89,7 @@ export const vip178 = (maxStalePeriod?: number) => { { target: agEUR, signature: "approve(address,uint256)", - params: [POOL_REGISTRY, parseUnits("10000", 18)], + params: [POOL_REGISTRY, parseUnits("9000", 18)], }, { target: POOL_REGISTRY, @@ -108,7 +109,7 @@ export const vip178 = (maxStalePeriod?: number) => { { target: TREASURY, signature: "withdrawTreasuryBEP20(address,uint256,address)", - params: [agEUR, parseUnits("17650", 18), NORMAL_TIMELOCK], + params: [ANGLE, parseUnits("17650", 18), NORMAL_TIMELOCK], }, { From 55b78d3caedc1790e3e856911476c38c487cf394 Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Thu, 28 Sep 2023 19:22:33 +0530 Subject: [PATCH 05/10] chore: update block number and fix mainnet simulations --- simulations/vip-178/vip-178/simulations.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/simulations/vip-178/vip-178/simulations.ts b/simulations/vip-178/vip-178/simulations.ts index c85dc852d..5a6559e16 100644 --- a/simulations/vip-178/vip-178/simulations.ts +++ b/simulations/vip-178/vip-178/simulations.ts @@ -15,7 +15,7 @@ import RATE_MODEL_ABI from "./abi/rateModel.json"; import REWARD_DISTRIBUTOR_ABI from "./abi/rewardsDistributor.json"; import VTOKEN_ABI from "./abi/vToken.json"; -const agEUR = "0x12f31b73d812c6bb0d735a218c086d44d5fe5f89"; +const agEUR = "0x12f31B73D812C6Bb0d735a218c086d44D5fe5f89"; const POOL_REGISTRY = "0x9F7b01A536aFA00EF10310A162877fd792cD0666"; const VTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; const VagEUR_Stablecoins = "0x1a9D2862028F6f5E6C299A7AC3C285508942b15E"; @@ -24,7 +24,7 @@ const NORMAL_TIMELOCK = "0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396"; const REWARD_DISTRIBUTOR = "0x177ED4625F57cEa2804EA3A396c8Ff78f314F1CA"; const ANGLE = "0x97B6897AAd7aBa3861c04C0e6388Fc02AF1F227f"; -forking(32136210, () => { +forking(32138412, () => { let poolRegistry: Contract; let comptroller: Contract; let vagEUR: Contract; @@ -100,7 +100,7 @@ forking(32136210, () => { callbackAfterExecution: async (txResponse: TransactionResponse) => { await expectEvents( txResponse, - [COMPTROLLER_ABI, POOL_REGISTRY_ABI, ERC20_ABI], + [COMPTROLLER_ABI, POOL_REGISTRY_ABI, ERC20_ABI, REWARD_DISTRIBUTOR_ABI], [ "Approval", "MarketAdded", @@ -131,6 +131,7 @@ forking(32136210, () => { describe("Ownership", () => { it("should transfer ownership to Timelock", async () => { expect(await vagEUR.owner()).to.equal(NORMAL_TIMELOCK); + expect(await rewardsDistributor.owner()).to.equal(NORMAL_TIMELOCK); }); }); @@ -232,8 +233,8 @@ forking(32136210, () => { expect(await comptroller.getRewardDistributors()).to.include(REWARD_DISTRIBUTOR); }); - it("should have 5 rewards distributor in Stable coins Pool", async () => { - expect(await comptroller.getRewardDistributors()).to.have.lengthOf(2); + it("should have 3 rewards distributor in Stable coins Pool", async () => { + expect(await comptroller.getRewardDistributors()).to.have.lengthOf(3); }); it("should have rewardToken ANGLE", async () => { From b5478279a52bddeb2fd861302ebaec713d2b22c4 Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Thu, 28 Sep 2023 20:02:34 +0530 Subject: [PATCH 06/10] chore: update simulations for risk management address checks --- .../vip-178/vip-178-testnet/abi/vToken.json | 1580 +++-------------- .../vip-178/vip-178-testnet/simulations.ts | 85 +- simulations/vip-178/vip-178/simulations.ts | 91 +- vips/vip-178/vip-178-testnet.ts | 2 +- vips/vip-178/vip-178.ts | 2 +- 5 files changed, 352 insertions(+), 1408 deletions(-) diff --git a/simulations/vip-178/vip-178-testnet/abi/vToken.json b/simulations/vip-178/vip-178-testnet/abi/vToken.json index a413ca84d..7ac5306db 100644 --- a/simulations/vip-178/vip-178-testnet/abi/vToken.json +++ b/simulations/vip-178/vip-178-testnet/abi/vToken.json @@ -1,302 +1,54 @@ [ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "actualAddAmount", - "type": "uint256" - } - ], + "inputs": [{ "internalType": "uint256", "name": "actualAddAmount", "type": "uint256" }], "name": "AddReservesFactorFreshCheck", "type": "error" }, + { "inputs": [], "name": "BorrowCashNotAvailable", "type": "error" }, + { "inputs": [], "name": "BorrowFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "ForceLiquidateBorrowUnauthorized", "type": "error" }, + { "inputs": [], "name": "HealBorrowUnauthorized", "type": "error" }, { - "inputs": [], - "name": "BorrowCashNotAvailable", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" - } - ], - "name": "BorrowComptrollerRejection", - "type": "error" - }, - { - "inputs": [], - "name": "BorrowFreshnessCheck", - "type": "error" - }, - { - "inputs": [], - "name": "ForceLiquidateBorrowUnauthorized", - "type": "error" - }, - { - "inputs": [], - "name": "HealBorrowUnauthorized", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" - } - ], - "name": "LiquidateAccrueBorrowInterestFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" - } - ], + "inputs": [{ "internalType": "uint256", "name": "errorCode", "type": "uint256" }], "name": "LiquidateAccrueCollateralInterestFailed", "type": "error" }, - { - "inputs": [], - "name": "LiquidateCloseAmountIsUintMax", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidateCloseAmountIsZero", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidateCollateralFreshnessCheck", - "type": "error" - }, + { "inputs": [], "name": "LiquidateCloseAmountIsUintMax", "type": "error" }, + { "inputs": [], "name": "LiquidateCloseAmountIsZero", "type": "error" }, + { "inputs": [], "name": "LiquidateCollateralFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "LiquidateFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "LiquidateLiquidatorIsBorrower", "type": "error" }, + { "inputs": [], "name": "LiquidateSeizeLiquidatorIsBorrower", "type": "error" }, + { "inputs": [], "name": "MintFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "ProtocolSeizeShareTooBig", "type": "error" }, + { "inputs": [], "name": "RedeemFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "RedeemTransferOutNotPossible", "type": "error" }, + { "inputs": [], "name": "ReduceReservesCashNotAvailable", "type": "error" }, + { "inputs": [], "name": "ReduceReservesCashValidation", "type": "error" }, + { "inputs": [], "name": "ReduceReservesFreshCheck", "type": "error" }, + { "inputs": [], "name": "RepayBorrowFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "SetInterestRateModelFreshCheck", "type": "error" }, + { "inputs": [], "name": "SetReserveFactorBoundsCheck", "type": "error" }, + { "inputs": [], "name": "SetReserveFactorFreshCheck", "type": "error" }, + { "inputs": [], "name": "TransferNotAllowed", "type": "error" }, { "inputs": [ - { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" - } - ], - "name": "LiquidateComptrollerRejection", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidateFreshnessCheck", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidateLiquidatorIsBorrower", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" - } + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "address", "name": "calledContract", "type": "address" }, + { "internalType": "string", "name": "methodSignature", "type": "string" } ], - "name": "LiquidateRepayBorrowFreshFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" - } - ], - "name": "LiquidateSeizeComptrollerRejection", - "type": "error" - }, - { - "inputs": [], - "name": "LiquidateSeizeLiquidatorIsBorrower", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" - } - ], - "name": "MintComptrollerRejection", - "type": "error" - }, - { - "inputs": [], - "name": "MintFreshnessCheck", - "type": "error" - }, - { - "inputs": [], - "name": "ProtocolSeizeShareTooBig", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" - } - ], - "name": "RedeemComptrollerRejection", - "type": "error" - }, - { - "inputs": [], - "name": "RedeemFreshnessCheck", - "type": "error" - }, - { - "inputs": [], - "name": "RedeemTransferOutNotPossible", - "type": "error" - }, - { - "inputs": [], - "name": "ReduceReservesAdminCheck", - "type": "error" - }, - { - "inputs": [], - "name": "ReduceReservesCashNotAvailable", - "type": "error" - }, - { - "inputs": [], - "name": "ReduceReservesCashValidation", - "type": "error" - }, - { - "inputs": [], - "name": "ReduceReservesFreshCheck", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" - } - ], - "name": "RepayBorrowComptrollerRejection", - "type": "error" - }, - { - "inputs": [], - "name": "RepayBorrowFreshnessCheck", - "type": "error" - }, - { - "inputs": [], - "name": "SetComptrollerOwnerCheck", - "type": "error" - }, - { - "inputs": [], - "name": "SetInterestRateModelFreshCheck", - "type": "error" - }, - { - "inputs": [], - "name": "SetInterestRateModelOwnerCheck", - "type": "error" - }, - { - "inputs": [], - "name": "SetProtocolSeizeShareUnauthorized", - "type": "error" - }, - { - "inputs": [], - "name": "SetReserveFactorAdminCheck", - "type": "error" - }, - { - "inputs": [], - "name": "SetReserveFactorBoundsCheck", - "type": "error" - }, - { - "inputs": [], - "name": "SetReserveFactorFreshCheck", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "errorCode", - "type": "uint256" - } - ], - "name": "TransferComptrollerRejection", - "type": "error" - }, - { - "inputs": [], - "name": "TransferNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "TransferNotEnough", - "type": "error" - }, - { - "inputs": [], - "name": "TransferTooMuch", + "name": "Unauthorized", "type": "error" }, + { "inputs": [], "name": "ZeroAddressNotAllowed", "type": "error" }, { "anonymous": false, "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "cashPrior", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "interestAccumulated", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "borrowIndex", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "totalBorrows", - "type": "uint256" - } + { "indexed": false, "internalType": "uint256", "name": "cashPrior", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "interestAccumulated", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "borrowIndex", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "totalBorrows", "type": "uint256" } ], "name": "AccrueInterest", "type": "event" @@ -304,24 +56,9 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "Approval", "type": "event" @@ -329,30 +66,10 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "badDebtDelta", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "badDebtOld", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "badDebtNew", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtDelta", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtOld", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtNew", "type": "uint256" } ], "name": "BadDebtIncreased", "type": "event" @@ -360,18 +77,8 @@ { "anonymous": false, "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "badDebtOld", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "badDebtNew", - "type": "uint256" - } + { "indexed": false, "internalType": "uint256", "name": "badDebtOld", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtNew", "type": "uint256" } ], "name": "BadDebtRecovered", "type": "event" @@ -379,30 +86,10 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "borrowAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "accountBorrows", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "totalBorrows", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "borrowAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBorrows", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "totalBorrows", "type": "uint256" } ], "name": "Borrow", "type": "event" @@ -410,74 +97,27 @@ { "anonymous": false, "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "payer", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "repayAmount", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "payer", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "repayAmount", "type": "uint256" } ], "name": "HealBorrow", "type": "event" }, { "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], + "inputs": [{ "indexed": false, "internalType": "uint8", "name": "version", "type": "uint8" }], "name": "Initialized", "type": "event" }, { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "liquidator", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "repayAmount", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "vTokenCollateral", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "seizeTokens", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "liquidator", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "vTokenCollateral", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } ], "name": "LiquidateBorrow", "type": "event" @@ -485,30 +125,10 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "minter", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "mintAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "mintTokens", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "accountBalance", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "minter", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "mintAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "mintTokens", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBalance", "type": "uint256" } ], "name": "Mint", "type": "event" @@ -516,37 +136,17 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "contract AccessControlManager", - "name": "oldAccessControlManager", - "type": "address" - }, - { - "indexed": true, - "internalType": "contract AccessControlManager", - "name": "newAccessControlManager", - "type": "address" - } + { "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": "contract ComptrollerInterface", - "name": "oldComptroller", - "type": "address" - }, - { - "indexed": true, - "internalType": "contract ComptrollerInterface", - "name": "newComptroller", - "type": "address" - } + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "contract ComptrollerInterface", "name": "oldComptroller", "type": "address" }, + { "indexed": true, "internalType": "contract ComptrollerInterface", "name": "newComptroller", "type": "address" } ], "name": "NewComptroller", "type": "event" @@ -573,18 +173,8 @@ { "anonymous": false, "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "oldProtocolSeizeShareMantissa", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newProtocolSeizeShareMantissa", - "type": "uint256" - } + { "indexed": false, "internalType": "uint256", "name": "oldProtocolSeizeShareMantissa", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newProtocolSeizeShareMantissa", "type": "uint256" } ], "name": "NewProtocolSeizeShare", "type": "event" @@ -592,18 +182,17 @@ { "anonymous": false, "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "oldReserveFactorMantissa", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newReserveFactorMantissa", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "oldProtocolShareReserve", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newProtocolShareReserve", "type": "address" } + ], + "name": "NewProtocolShareReserve", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "oldReserveFactorMantissa", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newReserveFactorMantissa", "type": "uint256" } ], "name": "NewReserveFactor", "type": "event" @@ -611,18 +200,17 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } + { "indexed": true, "internalType": "address", "name": "oldShortfall", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newShortfall", "type": "address" } + ], + "name": "NewShortfallContract", + "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" @@ -630,18 +218,8 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } + { "indexed": true, "internalType": "address", "name": "previousOwner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" @@ -649,30 +227,10 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "redeemer", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "redeemAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "redeemTokens", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "accountBalance", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "redeemer", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "redeemAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "redeemTokens", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBalance", "type": "uint256" } ], "name": "Redeem", "type": "event" @@ -680,36 +238,11 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "payer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "repayAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "accountBorrows", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "totalBorrows", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "payer", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBorrows", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "totalBorrows", "type": "uint256" } ], "name": "RepayBorrow", "type": "event" @@ -717,24 +250,9 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "benefactor", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "addAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newTotalReserves", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "benefactor", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "addAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newTotalReserves", "type": "uint256" } ], "name": "ReservesAdded", "type": "event" @@ -742,62 +260,25 @@ { "anonymous": false, "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "admin", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "reduceAmount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "newTotalReserves", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "admin", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "reduceAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newTotalReserves", "type": "uint256" } ], "name": "ReservesReduced", "type": "event" }, { "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "token", - "type": "address" - } - ], + "inputs": [{ "indexed": true, "internalType": "address", "name": "token", "type": "address" }], "name": "SweepToken", "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": "amount", - "type": "uint256" - } + { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "Transfer", "type": "event" @@ -805,70 +286,34 @@ { "inputs": [], "name": "NO_ERROR", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "acceptOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, + { "inputs": [], "name": "acceptOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "accessControlManager", - "outputs": [ - { - "internalType": "contract AccessControlManager", - "name": "", - "type": "address" - } - ], + "outputs": [{ "internalType": "contract IAccessControlManagerV8", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "accrualBlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "accrueInterest", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "addAmount", - "type": "uint256" - } - ], + "inputs": [{ "internalType": "uint256", "name": "addAmount", "type": "uint256" }], "name": "addReserves", "outputs": [], "stateMutability": "nonpayable", @@ -876,302 +321,132 @@ }, { "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "spender", - "type": "address" - } + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } ], "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "badDebt", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "recoveredAmount_", - "type": "uint256" - } - ], + "inputs": [{ "internalType": "uint256", "name": "recoveredAmount_", "type": "uint256" }], "name": "badDebtRecovered", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], "name": "balanceOfUnderlying", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "borrowAmount", - "type": "uint256" - } - ], + "inputs": [{ "internalType": "uint256", "name": "borrowAmount", "type": "uint256" }], "name": "borrow", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], "name": "borrowBalanceCurrent", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], "name": "borrowBalanceStored", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "borrowIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "borrowRatePerBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "comptroller", - "outputs": [ - { - "internalType": "contract ComptrollerInterface", - "name": "", - "type": "address" - } - ], + "outputs": [{ "internalType": "contract ComptrollerInterface", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "decimals", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], "stateMutability": "view", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "subtractedValue", - "type": "uint256" - } + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" } ], "name": "decreaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "exchangeRateCurrent", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "exchangeRateStored", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "liquidator", - "type": "address" - }, - { - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "internalType": "uint256", - "name": "repayAmount", - "type": "uint256" - }, - { - "internalType": "contract VTokenInterface", - "name": "vTokenCollateral", - "type": "address" - }, - { - "internalType": "bool", - "name": "skipLiquidityCheck", - "type": "bool" - } + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "internalType": "contract VTokenInterface", "name": "vTokenCollateral", "type": "address" }, + { "internalType": "bool", "name": "skipLiquidityCheck", "type": "bool" } ], "name": "forceLiquidateBorrow", "outputs": [], @@ -1179,35 +454,13 @@ "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], "name": "getAccountSnapshot", "outputs": [ - { - "internalType": "uint256", - "name": "error", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "vTokenBalance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "borrowBalance", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "exchangeRate", - "type": "uint256" - } + { "internalType": "uint256", "name": "error", "type": "uint256" }, + { "internalType": "uint256", "name": "vTokenBalance", "type": "uint256" }, + { "internalType": "uint256", "name": "borrowBalance", "type": "uint256" }, + { "internalType": "uint256", "name": "exchangeRate", "type": "uint256" } ], "stateMutability": "view", "type": "function" @@ -1215,33 +468,15 @@ { "inputs": [], "name": "getCash", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "payer", - "type": "address" - }, - { - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "internalType": "uint256", - "name": "repayAmount", - "type": "uint256" - } + { "internalType": "address", "name": "payer", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } ], "name": "healBorrow", "outputs": [], @@ -1250,97 +485,35 @@ }, { "inputs": [ - { - "internalType": "address", - "name": "spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "addedValue", - "type": "uint256" - } + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } ], "name": "increaseAllowance", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "underlying_", - "type": "address" - }, - { - "internalType": "contract ComptrollerInterface", - "name": "comptroller_", - "type": "address" - }, - { - "internalType": "contract InterestRateModel", - "name": "interestRateModel_", - "type": "address" - }, - { - "internalType": "uint256", - "name": "initialExchangeRateMantissa_", - "type": "uint256" - }, - { - "internalType": "string", - "name": "name_", - "type": "string" - }, - { - "internalType": "string", - "name": "symbol_", - "type": "string" - }, - { - "internalType": "uint8", - "name": "decimals_", - "type": "uint8" - }, - { - "internalType": "address", - "name": "admin_", - "type": "address" - }, - { - "internalType": "contract AccessControlManager", - "name": "accessControlManager_", - "type": "address" - }, + { "internalType": "address", "name": "underlying_", "type": "address" }, + { "internalType": "contract ComptrollerInterface", "name": "comptroller_", "type": "address" }, + { "internalType": "contract InterestRateModel", "name": "interestRateModel_", "type": "address" }, + { "internalType": "uint256", "name": "initialExchangeRateMantissa_", "type": "uint256" }, + { "internalType": "string", "name": "name_", "type": "string" }, + { "internalType": "string", "name": "symbol_", "type": "string" }, + { "internalType": "uint8", "name": "decimals_", "type": "uint8" }, + { "internalType": "address", "name": "admin_", "type": "address" }, + { "internalType": "address", "name": "accessControlManager_", "type": "address" }, { "components": [ - { - "internalType": "address", - "name": "shortfall", - "type": "address" - }, - { - "internalType": "address payable", - "name": "riskFund", - "type": "address" - }, - { - "internalType": "address payable", - "name": "protocolShareReserve", - "type": "address" - } + { "internalType": "address", "name": "shortfall", "type": "address" }, + { "internalType": "address payable", "name": "protocolShareReserve", "type": "address" } ], "internalType": "struct VTokenInterface.RiskManagementInit", "name": "riskManagement", "type": "tuple" - } + }, + { "internalType": "uint256", "name": "reserveFactorMantissa_", "type": "uint256" } ], "name": "initialize", "outputs": [], @@ -1350,284 +523,131 @@ { "inputs": [], "name": "interestRateModel", - "outputs": [ - { - "internalType": "contract InterestRateModel", - "name": "", - "type": "address" - } - ], + "outputs": [{ "internalType": "contract InterestRateModel", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "isVToken", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "internalType": "uint256", - "name": "repayAmount", - "type": "uint256" - }, - { - "internalType": "contract VTokenInterface", - "name": "vTokenCollateral", - "type": "address" - } + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "internalType": "contract VTokenInterface", "name": "vTokenCollateral", "type": "address" } ], "name": "liquidateBorrow", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "mintAmount", - "type": "uint256" - } - ], + "inputs": [{ "internalType": "uint256", "name": "mintAmount", "type": "uint256" }], "name": "mint", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "minter", - "type": "address" - }, - { - "internalType": "uint256", - "name": "mintAmount", - "type": "uint256" - } + { "internalType": "address", "name": "minter", "type": "address" }, + { "internalType": "uint256", "name": "mintAmount", "type": "uint256" } ], "name": "mintBehalf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "pendingOwner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "protocolSeizeShareMantissa", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "redeemTokens", - "type": "uint256" - } - ], - "name": "redeem", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "nonpayable", + "inputs": [], + "name": "protocolShareReserve", + "outputs": [{ "internalType": "address payable", "name": "", "type": "address" }], + "stateMutability": "view", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "redeemAmount", - "type": "uint256" - } - ], - "name": "redeemUnderlying", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "inputs": [{ "internalType": "uint256", "name": "redeemTokens", "type": "uint256" }], + "name": "redeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "reduceAmount", - "type": "uint256" - } - ], - "name": "reduceReserves", - "outputs": [], + "inputs": [{ "internalType": "uint256", "name": "redeemAmount", "type": "uint256" }], + "name": "redeemUnderlying", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [], - "name": "renounceOwnership", + "inputs": [{ "internalType": "uint256", "name": "reduceAmount", "type": "uint256" }], + "name": "reduceReserves", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "repayAmount", - "type": "uint256" - } - ], + "inputs": [{ "internalType": "uint256", "name": "repayAmount", "type": "uint256" }], "name": "repayBorrow", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "internalType": "uint256", - "name": "repayAmount", - "type": "uint256" - } + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } ], "name": "repayBorrowBehalf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "reserveFactorMantissa", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "liquidator", - "type": "address" - }, - { - "internalType": "address", - "name": "borrower", - "type": "address" - }, - { - "internalType": "uint256", - "name": "seizeTokens", - "type": "uint256" - } + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } ], "name": "seize", "outputs": [], @@ -1635,91 +655,63 @@ "type": "function" }, { - "inputs": [ - { - "internalType": "contract AccessControlManager", - "name": "newAccessControlManager", - "type": "address" - } - ], - "name": "setAccessControlAddress", + "inputs": [{ "internalType": "address", "name": "accessControlManager_", "type": "address" }], + "name": "setAccessControlManager", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "contract InterestRateModel", - "name": "newInterestRateModel", - "type": "address" - } - ], + "inputs": [{ "internalType": "contract InterestRateModel", "name": "newInterestRateModel", "type": "address" }], "name": "setInterestRateModel", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "newProtocolSeizeShareMantissa_", - "type": "uint256" - } - ], + "inputs": [{ "internalType": "uint256", "name": "newProtocolSeizeShareMantissa_", "type": "uint256" }], "name": "setProtocolSeizeShare", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "newReserveFactorMantissa", - "type": "uint256" - } - ], + "inputs": [{ "internalType": "address payable", "name": "protocolShareReserve_", "type": "address" }], + "name": "setProtocolShareReserve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "newReserveFactorMantissa", "type": "uint256" }], "name": "setReserveFactor", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [{ "internalType": "address", "name": "shortfall_", "type": "address" }], + "name": "setShortfallContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "shortfall", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "supplyRatePerBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { - "inputs": [ - { - "internalType": "contract IERC20Upgradeable", - "name": "token", - "type": "address" - } - ], + "inputs": [{ "internalType": "contract IERC20Upgradeable", "name": "token", "type": "address" }], "name": "sweepToken", "outputs": [], "stateMutability": "nonpayable", @@ -1728,129 +720,61 @@ { "inputs": [], "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalBorrows", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalBorrowsCurrent", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "totalReserves", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "dst", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ - { - "internalType": "address", - "name": "src", - "type": "address" - }, - { - "internalType": "address", - "name": "dst", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], "name": "transferOwnership", "outputs": [], "stateMutability": "nonpayable", @@ -1859,13 +783,7 @@ { "inputs": [], "name": "underlying", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" } diff --git a/simulations/vip-178/vip-178-testnet/simulations.ts b/simulations/vip-178/vip-178-testnet/simulations.ts index ff42c8b31..f7a180dbb 100644 --- a/simulations/vip-178/vip-178-testnet/simulations.ts +++ b/simulations/vip-178/vip-178-testnet/simulations.ts @@ -18,13 +18,15 @@ import VTOKEN_ABI from "./abi/vToken.json"; const agEUR = "0x63061de4A25f24279AAab80400040684F92Ee319"; const POOL_REGISTRY = "0xC85491616Fa949E048F3aAc39fbf5b0703800667"; const vTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; -const VagEUR_Stablecoins = "0xa0571e758a00C586DbD53fb431d0f48eff9d0F15"; +const VagEUR_Stablecoins = "0x4E1D35166776825402d50AfE4286c500027211D1"; const STABLECOIN_COMPTROLLER = "0x10b57706AD2345e590c2eA4DC02faef0d9f5b08B"; const NORMAL_TIMELOCK = "0xce10739590001705F7FF231611ba4A48B2820327"; const REWARD_DISTRIBUTOR = "0x78d32FC46e5025c29e3BA03Fcf2840323351F26a"; const ANGLE = "0xD1Bc731d188ACc3f52a6226B328a89056B0Ec71a"; +const PROTOCOL_SHARE_RESERVE = "0xc987a03ab6C2A5891Fc0919f021cc693B5E55278"; +const SHORTFALL = "0x503574a82fE2A9f968d355C8AAc1Ba0481859369"; -forking(33734613, () => { +forking(33737831, () => { let poolRegistry: Contract; let comptroller: Contract; let vagEUR: Contract; @@ -257,47 +259,58 @@ forking(33734613, () => { expect(await token.balanceOf(rewardsDistributor.address)).to.equal(parseUnits("17650", 18)); }); }); + describe("VToken", () => { + describe("Basic supply/borrow/repay/redeem scenario", () => { + let agEURUnderlying: Contract; + let vagEUR: Contract; + let user: SignerWithAddress; - describe("Basic supply/borrow/repay/redeem scenario", () => { - let agEURUnderlying: Contract; - let vagEUR: Contract; - let user: SignerWithAddress; + before(async () => { + [user] = await ethers.getSigners(); + agEURUnderlying = await ethers.getContractAt(ERC20_ABI, agEUR); + vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); + await agEURUnderlying.faucet(parseUnits("100", 18)); + }); - before(async () => { - [user] = await ethers.getSigners(); - agEURUnderlying = await ethers.getContractAt(ERC20_ABI, agEUR); - vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); - await agEURUnderlying.faucet(parseUnits("100", 18)); - }); + it("should be possible to supply", async () => { + await agEURUnderlying.approve(vagEUR.address, parseUnits("100", 18)); + await vagEUR.mint(parseUnits("100", 18)); + expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits("100", 8)); + }); - it("should be possible to supply", async () => { - await agEURUnderlying.approve(vagEUR.address, parseUnits("100", 18)); - await vagEUR.mint(parseUnits("100", 18)); - expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits("100", 8)); - }); + it("should be possible to enable agEUR as collateral", async () => { + await comptroller.connect(user).enterMarkets([VagEUR_Stablecoins]); + expect(await comptroller.getAssetsIn(user.address)).to.deep.equal([VagEUR_Stablecoins]); + }); - it("should be possible to enable the as collateral", async () => { - await comptroller.connect(user).enterMarkets([VagEUR_Stablecoins]); - expect(await comptroller.getAssetsIn(user.address)).to.deep.equal([VagEUR_Stablecoins]); - }); + it("should be possible to borrow agEUR", async () => { + await vagEUR.connect(user).borrow(1000000); + expect(await vagEUR.borrowBalanceStored(user.address)).to.equal(1000000); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(1000000); + }); - it("should be possible to borrow agEUR", async () => { - await vagEUR.connect(user).borrow(1000000); - expect(await vagEUR.borrowBalanceStored(user.address)).to.equal(1000000); - expect(await agEURUnderlying.balanceOf(user.address)).to.equal(1000000); - }); + it("should be possible to repay agEUR", async () => { + await agEURUnderlying.approve(vagEUR.address, 1000000); + await vagEUR.repayBorrow(1000000); + expect(await vagEUR.borrowBalanceStored(user.address)).to.be.lessThan(parseUnits("0.01", 18)); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(0); + }); - it("should be possible to repay agEUR", async () => { - await agEURUnderlying.approve(vagEUR.address, 1000000); - await vagEUR.repayBorrow(1000000); - expect(await vagEUR.borrowBalanceStored(user.address)).to.be.lessThan(parseUnits("0.01", 18)); - expect(await agEURUnderlying.balanceOf(user.address)).to.equal(0); - }); + it("should be possible to redeem a part of total", async () => { + await vagEUR.redeemUnderlying(parseUnits("30", 18)); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(parseUnits("30", 18)); + expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits("70", 8)); + }); - it("should be possible to redeem a part of total", async () => { - await vagEUR.redeemUnderlying(parseUnits("30", 18)); - expect(await agEURUnderlying.balanceOf(user.address)).to.equal(parseUnits("30", 18)); - expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits("70", 8)); + describe("Risk Management", () => { + it("should set correct address of protocol share reserve", async () => { + expect(await vagEUR.protocolShareReserve()).equals(PROTOCOL_SHARE_RESERVE); + }); + + it("should set correct address of shortfall", async () => { + expect(await vagEUR.shortfall()).equals(SHORTFALL); + }); + }); }); }); }); diff --git a/simulations/vip-178/vip-178/simulations.ts b/simulations/vip-178/vip-178/simulations.ts index 5a6559e16..7f54bc24f 100644 --- a/simulations/vip-178/vip-178/simulations.ts +++ b/simulations/vip-178/vip-178/simulations.ts @@ -18,13 +18,15 @@ import VTOKEN_ABI from "./abi/vToken.json"; const agEUR = "0x12f31B73D812C6Bb0d735a218c086d44D5fe5f89"; const POOL_REGISTRY = "0x9F7b01A536aFA00EF10310A162877fd792cD0666"; const VTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; -const VagEUR_Stablecoins = "0x1a9D2862028F6f5E6C299A7AC3C285508942b15E"; +const VagEUR_Stablecoins = "0x795DE779Be00Ea46eA97a28BDD38d9ED570BCF0F"; const STABLECOIN_COMPTROLLER = "0x94c1495cD4c557f1560Cbd68EAB0d197e6291571"; const NORMAL_TIMELOCK = "0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396"; const REWARD_DISTRIBUTOR = "0x177ED4625F57cEa2804EA3A396c8Ff78f314F1CA"; const ANGLE = "0x97B6897AAd7aBa3861c04C0e6388Fc02AF1F227f"; +const PROTOCOL_SHARE_RESERVE = "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4"; +const SHORTFALL = "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209"; -forking(32138412, () => { +forking(32139104, () => { let poolRegistry: Contract; let comptroller: Contract; let vagEUR: Contract; @@ -258,49 +260,60 @@ forking(32138412, () => { expect(await token.balanceOf(rewardsDistributor.address)).to.equal(parseUnits("17650", 18)); }); }); + describe("VToken", () => { + describe("Basic supply/borrow/repay/redeem scenario", () => { + let agEURUnderlying: Contract; + let vagEUR: Contract; + let user: SignerWithAddress; - describe("Basic supply/borrow/repay/redeem scenario", () => { - let agEURUnderlying: Contract; - let vagEUR: Contract; - let user: SignerWithAddress; - - before(async () => { - [user] = await ethers.getSigners(); - const agEUR_HOLDER = "0x7B1db35fbd95548777B9079527e8fa2a70fb2CE0"; - agEURUnderlying = await ethers.getContractAt(ERC20_ABI, agEUR); - vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); - const agEUR_holder = await initMainnetUser(agEUR_HOLDER, parseUnits("1", 18)); - await agEURUnderlying.connect(agEUR_holder).transfer(user.address, parseUnits(".00005", 18)); - }); + before(async () => { + [user] = await ethers.getSigners(); + const agEUR_HOLDER = "0x7B1db35fbd95548777B9079527e8fa2a70fb2CE0"; + agEURUnderlying = await ethers.getContractAt(ERC20_ABI, agEUR); + vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); + const agEUR_holder = await initMainnetUser(agEUR_HOLDER, parseUnits("1", 18)); + await agEURUnderlying.connect(agEUR_holder).transfer(user.address, parseUnits(".00005", 18)); + }); - it("should be possible to supply", async () => { - await agEURUnderlying.approve(vagEUR.address, parseUnits(".00005", 18)); - await vagEUR.mint(parseUnits(".00005", 18)); - expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits(".00005", 8)); - }); + it("should be possible to supply", async () => { + await agEURUnderlying.approve(vagEUR.address, parseUnits(".00005", 18)); + await vagEUR.mint(parseUnits(".00005", 18)); + expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits(".00005", 8)); + }); - it("should be possible to enable the as collateral", async () => { - await comptroller.connect(user).enterMarkets([VagEUR_Stablecoins]); - expect(await comptroller.getAssetsIn(user.address)).to.deep.equal([VagEUR_Stablecoins]); - }); + it("should be possible to enable agEUR as collateral", async () => { + await comptroller.connect(user).enterMarkets([VagEUR_Stablecoins]); + expect(await comptroller.getAssetsIn(user.address)).to.deep.equal([VagEUR_Stablecoins]); + }); - it("should be possible to borrow agEUR", async () => { - await vagEUR.connect(user).borrow(1000000); - expect(await vagEUR.borrowBalanceStored(user.address)).to.equal(1000000); - expect(await agEURUnderlying.balanceOf(user.address)).to.equal(1000000); - }); + it("should be possible to borrow agEUR", async () => { + await vagEUR.connect(user).borrow(1000000); + expect(await vagEUR.borrowBalanceStored(user.address)).to.equal(1000000); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(1000000); + }); - it("should be possible to repay agEUR", async () => { - await agEURUnderlying.approve(vagEUR.address, 1000000); - await vagEUR.repayBorrow(1000000); - expect(await vagEUR.borrowBalanceStored(user.address)).to.be.lessThan(parseUnits("0.01", 18)); - expect(await agEURUnderlying.balanceOf(user.address)).to.equal(0); - }); + it("should be possible to repay agEUR", async () => { + await agEURUnderlying.approve(vagEUR.address, 1000000); + await vagEUR.repayBorrow(1000000); + expect(await vagEUR.borrowBalanceStored(user.address)).to.be.lessThan(parseUnits("0.01", 18)); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(0); + }); + + it("should be possible to redeem a part of total", async () => { + await vagEUR.redeemUnderlying(parseUnits(".00001", 18)); + expect(await agEURUnderlying.balanceOf(user.address)).to.equal(parseUnits(".00001", 18)); + expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits(".00004", 8)); + }); - it("should be possible to redeem a part of total", async () => { - await vagEUR.redeemUnderlying(parseUnits(".00001", 18)); - expect(await agEURUnderlying.balanceOf(user.address)).to.equal(parseUnits(".00001", 18)); - expect(await vagEUR.balanceOf(user.address)).to.equal(parseUnits(".00004", 8)); + describe("Risk Management", () => { + it("should set correct address of protocol share reserve", async () => { + expect(await vagEUR.protocolShareReserve()).equals(PROTOCOL_SHARE_RESERVE); + }); + + it("should set correct address of shortfall", async () => { + expect(await vagEUR.shortfall()).equals(SHORTFALL); + }); + }); }); }); }); diff --git a/vips/vip-178/vip-178-testnet.ts b/vips/vip-178/vip-178-testnet.ts index 787c81cf6..a0226335b 100644 --- a/vips/vip-178/vip-178-testnet.ts +++ b/vips/vip-178/vip-178-testnet.ts @@ -6,7 +6,7 @@ import { makeProposal } from "../../src/utils"; const agEUR = "0x63061de4A25f24279AAab80400040684F92Ee319"; const POOL_REGISTRY = "0xC85491616Fa949E048F3aAc39fbf5b0703800667"; const VTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; -const vagEUR_StableCoins = "0xa0571e758a00C586DbD53fb431d0f48eff9d0F15"; +const vagEUR_StableCoins = "0x4E1D35166776825402d50AfE4286c500027211D1"; const CHAINLINK_ORACLE = "0xCeA29f1266e880A1482c06eD656cD08C148BaA32"; const RESILIENT_ORACLE = "0x3cD69251D04A28d887Ac14cbe2E14c52F3D57823"; const REWARD_DISTRIBUTOR = "0x78d32FC46e5025c29e3BA03Fcf2840323351F26a"; diff --git a/vips/vip-178/vip-178.ts b/vips/vip-178/vip-178.ts index f3d39e29c..ae8b95db6 100644 --- a/vips/vip-178/vip-178.ts +++ b/vips/vip-178/vip-178.ts @@ -6,7 +6,7 @@ import { makeProposal } from "../../src/utils"; const agEUR = "0x12f31b73d812c6bb0d735a218c086d44d5fe5f89"; const POOL_REGISTRY = "0x9F7b01A536aFA00EF10310A162877fd792cD0666"; const VTOKEN_RECEIVER_agEUR = "0xc444949e0054a23c44fc45789738bdf64aed2391"; -const vagEUR_StableCoin = "0x1a9D2862028F6f5E6C299A7AC3C285508942b15E"; +const vagEUR_StableCoin = "0x795DE779Be00Ea46eA97a28BDD38d9ED570BCF0F"; const BINANCE_ORACLE = "0x594810b741d136f1960141C0d8Fb4a91bE78A820"; const RESILIENT_ORACLE = "0x6592b5DE802159F3E74B2486b091D11a8256ab8A"; const TREASURY = "0xF322942f644A996A617BD29c16bd7d231d9F35E9"; From 045ac4207eb912a0b97e427fe18b03ae7be40be1 Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:31:10 +0530 Subject: [PATCH 07/10] fix: resolve comments --- simulations/vip-178/vip-178/simulations.ts | 2 +- vips/vip-178/vip-178-testnet.ts | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/simulations/vip-178/vip-178/simulations.ts b/simulations/vip-178/vip-178/simulations.ts index 7f54bc24f..28aae11cd 100644 --- a/simulations/vip-178/vip-178/simulations.ts +++ b/simulations/vip-178/vip-178/simulations.ts @@ -26,7 +26,7 @@ const ANGLE = "0x97B6897AAd7aBa3861c04C0e6388Fc02AF1F227f"; const PROTOCOL_SHARE_RESERVE = "0xfB5bE09a1FA6CFDA075aB1E69FE83ce8324682e4"; const SHORTFALL = "0xf37530A8a810Fcb501AA0Ecd0B0699388F0F2209"; -forking(32139104, () => { +forking(32162545, () => { let poolRegistry: Contract; let comptroller: Contract; let vagEUR: Contract; diff --git a/vips/vip-178/vip-178-testnet.ts b/vips/vip-178/vip-178-testnet.ts index a0226335b..87616dafb 100644 --- a/vips/vip-178/vip-178-testnet.ts +++ b/vips/vip-178/vip-178-testnet.ts @@ -30,6 +30,22 @@ export const vip178Testnet = () => { signature: "setDirectPrice(address,uint256)", params: [agEUR, parseUnits("1.06", 18)], }, + { + target: RESILIENT_ORACLE, + signature: "setTokenConfig((address,address[3],bool[3]))", + params: [ + [ + agEUR, + [ + CHAINLINK_ORACLE, + "0x0000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000", + ], + [true, false, false], + ], + ], + }, + { target: CHAINLINK_ORACLE, signature: "setDirectPrice(address,uint256)", @@ -40,7 +56,7 @@ export const vip178Testnet = () => { signature: "setTokenConfig((address,address[3],bool[3]))", params: [ [ - agEUR, + ANGLE, [ CHAINLINK_ORACLE, "0x0000000000000000000000000000000000000000", @@ -50,7 +66,6 @@ export const vip178Testnet = () => { ], ], }, - { target: agEUR, signature: "faucet(uint256)", From b15f1f8f0c4c747a5ed949255e3aca707b1911cc Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Fri, 29 Sep 2023 12:53:23 +0200 Subject: [PATCH 08/10] test: add checks on the token prices --- .../vip-178/vip-178/abi/resilientOracle.json | 640 ++++++++++++++++++ simulations/vip-178/vip-178/simulations.ts | 19 + 2 files changed, 659 insertions(+) create mode 100644 simulations/vip-178/vip-178/abi/resilientOracle.json diff --git a/simulations/vip-178/vip-178/abi/resilientOracle.json b/simulations/vip-178/vip-178/abi/resilientOracle.json new file mode 100644 index 000000000..fc9c7a5e3 --- /dev/null +++ b/simulations/vip-178/vip-178/abi/resilientOracle.json @@ -0,0 +1,640 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "vBnbAddress", + "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": "BNB_ADDR", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INVALID_PRICE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "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": "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": "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": "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": "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": "vBnb", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "vai", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/simulations/vip-178/vip-178/simulations.ts b/simulations/vip-178/vip-178/simulations.ts index 28aae11cd..6f9cd1a61 100644 --- a/simulations/vip-178/vip-178/simulations.ts +++ b/simulations/vip-178/vip-178/simulations.ts @@ -12,6 +12,7 @@ import COMPTROLLER_ABI from "./abi/comptroller.json"; import ERC20_ABI from "./abi/erc20.json"; import POOL_REGISTRY_ABI from "./abi/poolRegistry.json"; import RATE_MODEL_ABI from "./abi/rateModel.json"; +import RESILIENT_ORACLE_ABI from "./abi/resilientOracle.json"; import REWARD_DISTRIBUTOR_ABI from "./abi/rewardsDistributor.json"; import VTOKEN_ABI from "./abi/vToken.json"; @@ -316,5 +317,23 @@ forking(32162545, () => { }); }); }); + + describe("Token prices", () => { + let resilientOracle: ethers.Contract; + + before(async () => { + resilientOracle = await ethers.getContractAt(RESILIENT_ORACLE_ABI, await comptroller.oracle()); + }); + + it("agEUR price", async () => { + const price = await resilientOracle.getPrice(agEUR); + expect(price).to.be.equal("1059294300000000000"); + }); + + it("ANGLE price", async () => { + const price = await resilientOracle.getPrice(ANGLE); + expect(price).to.be.equal("31221950000000000"); + }); + }); }); }); From 44f882c113c45dd14db95767816ad443f6c80f1e Mon Sep 17 00:00:00 2001 From: Jesus Lanchas Date: Fri, 29 Sep 2023 20:19:31 +0200 Subject: [PATCH 09/10] feat: add description in the VIP adding the agEUR market --- vips/vip-178/vip-178-testnet.ts | 62 ++++++++++++++++++++++++++++++--- vips/vip-178/vip-178.ts | 62 ++++++++++++++++++++++++++++++--- 2 files changed, 114 insertions(+), 10 deletions(-) diff --git a/vips/vip-178/vip-178-testnet.ts b/vips/vip-178/vip-178-testnet.ts index 87616dafb..22222bb79 100644 --- a/vips/vip-178/vip-178-testnet.ts +++ b/vips/vip-178/vip-178-testnet.ts @@ -16,11 +16,63 @@ const ANGLE = "0xD1Bc731d188ACc3f52a6226B328a89056B0Ec71a"; export const vip178Testnet = () => { const meta = { version: "v2", - title: "VIP-178 Add agEUR market to Stablecoin Pool", - description: ``, - forDescription: "I agree that Venus Protocol should proceed with add market", - againstDescription: "I do not think that Venus Protocol should proceed with add market", - abstainDescription: "I am indifferent to whether Venus Protocol proceeds with add market", + title: "VIP-178 Add support for agEUR market in the Stablecoins pool", + description: `#### Summary + +If passed, this VIP will add a new market for [agEUR](https://bscscan.com/address/0x12f31B73D812C6Bb0d735a218c086d44D5fe5f89) into the Isolated Lending Stablecoins pool. + +#### Description + +**Risk parameters** + +Following [Chaos Labs recommendations](https://community.venus.io/t/chaos-labs-risk-parameter-updates-08-28-2023/3720), the risk parameters for the new market are: + +- Underlying token: [agEUR](https://bscscan.com/address/0x12f31B73D812C6Bb0d735a218c086d44D5fe5f89) +- Borrow cap: 50,000 agEUR +- Supply cap: 100,000 agEUR +- Collateral factor: 0.75 +- Liquidation threshold: 0.8 +- Reserve factor: 0.1 + +Bootstrap liquidity: 9,000 agEUR - provided by the Venus Community. + +Interest rate curve for the new market: + +- kink: 0.5 +- base (yearly): 0.02 +- multiplier (yearly): 0.1 +- jump multiplier (yearly): 2.5 + +**Rewards** + +- 17,650 [ANGLE](https://bscscan.com/token/0x97B6897AAd7aBa3861c04C0e6388Fc02AF1F227f), for 7 days, only for borrowers in the new agEUR market + +**Security and additional considerations** + +No changes in the code are involved in this VIP. We applied the following security procedures for this upgrade: + +- **VIP execution simulation**: in a simulation environment, validating the new market is properly added to the Stablecoins pool with the right parameters and the expected bootstrap liquidity +- **Deployment on testnet**: the same market has been deployed to testnet, and used in the Venus Protocol testnet deployment + +**Contracts on mainnet** + +New market vagEUR_Stablecoins: [0x795DE779Be00Ea46eA97a28BDD38d9ED570BCF0F](https://bscscan.com/address/0x795DE779Be00Ea46eA97a28BDD38d9ED570BCF0F) + +**Contracts on testnet** + +New market vagEUR_Stablecoins: [0x4E1D35166776825402d50AfE4286c500027211D1](https://testnet.bscscan.com/address/0x4E1D35166776825402d50AfE4286c500027211D1) + +**References** + +- [Repository](https://github.com/VenusProtocol/isolated-pools) +- [Fork tests of main operations](https://github.com/VenusProtocol/isolated-pools/tree/develop/tests/hardhat/Fork) +- [VIP simulation](https://github.com/VenusProtocol/vips/pull/79) +- [Forum proposal to add agEUR market to Venus](https://community.venus.io/t/isolated-market-for-ageur-on-venus/3709) +- [Community post about Venus V4, introducing Isolated Pools](https://community.venus.io/t/proposing-venus-v4) +- [Documentation](https://docs-v4.venus.io/whats-new/isolated-pools)`, + forDescription: "Process to configure and launch the new market", + againstDescription: "Defer configuration and launch of the new market", + abstainDescription: "No opinion on the matter", }; return makeProposal( diff --git a/vips/vip-178/vip-178.ts b/vips/vip-178/vip-178.ts index ae8b95db6..f70489dd3 100644 --- a/vips/vip-178/vip-178.ts +++ b/vips/vip-178/vip-178.ts @@ -20,11 +20,63 @@ const MAX_STALE_PERIOD_ANGLE = 60 * 25; export const vip178 = (maxStalePeriod?: number) => { const meta = { version: "v2", - title: "VIP-178 Add agEUR market to Stablecoin Pool", - description: ``, - forDescription: "I agree that Venus Protocol should proceed with add market", - againstDescription: "I do not think that Venus Protocol should proceed with add market", - abstainDescription: "I am indifferent to whether Venus Protocol proceeds with add market", + title: "VIP-178 Add support for agEUR market in the Stablecoins pool", + description: `#### Summary + +If passed, this VIP will add a new market for [agEUR](https://bscscan.com/address/0x12f31B73D812C6Bb0d735a218c086d44D5fe5f89) into the Isolated Lending Stablecoins pool. + +#### Description + +**Risk parameters** + +Following [Chaos Labs recommendations](https://community.venus.io/t/chaos-labs-risk-parameter-updates-08-28-2023/3720), the risk parameters for the new market are: + +- Underlying token: [agEUR](https://bscscan.com/address/0x12f31B73D812C6Bb0d735a218c086d44D5fe5f89) +- Borrow cap: 50,000 agEUR +- Supply cap: 100,000 agEUR +- Collateral factor: 0.75 +- Liquidation threshold: 0.8 +- Reserve factor: 0.1 + +Bootstrap liquidity: 9,000 agEUR - provided by the Venus Community. + +Interest rate curve for the new market: + +- kink: 0.5 +- base (yearly): 0.02 +- multiplier (yearly): 0.1 +- jump multiplier (yearly): 2.5 + +**Rewards** + +- 17,650 [ANGLE](https://bscscan.com/token/0x97B6897AAd7aBa3861c04C0e6388Fc02AF1F227f), for 7 days, only for borrowers in the new agEUR market + +**Security and additional considerations** + +No changes in the code are involved in this VIP. We applied the following security procedures for this upgrade: + +- **VIP execution simulation**: in a simulation environment, validating the new market is properly added to the Stablecoins pool with the right parameters and the expected bootstrap liquidity +- **Deployment on testnet**: the same market has been deployed to testnet, and used in the Venus Protocol testnet deployment + +**Contracts on mainnet** + +New market vagEUR_Stablecoins: [0x795DE779Be00Ea46eA97a28BDD38d9ED570BCF0F](https://bscscan.com/address/0x795DE779Be00Ea46eA97a28BDD38d9ED570BCF0F) + +**Contracts on testnet** + +New market vagEUR_Stablecoins: [0x4E1D35166776825402d50AfE4286c500027211D1](https://testnet.bscscan.com/address/0x4E1D35166776825402d50AfE4286c500027211D1) + +**References** + +- [Repository](https://github.com/VenusProtocol/isolated-pools) +- [Fork tests of main operations](https://github.com/VenusProtocol/isolated-pools/tree/develop/tests/hardhat/Fork) +- [VIP simulation](https://github.com/VenusProtocol/vips/pull/79) +- [Forum proposal to add agEUR market to Venus](https://community.venus.io/t/isolated-market-for-ageur-on-venus/3709) +- [Community post about Venus V4, introducing Isolated Pools](https://community.venus.io/t/proposing-venus-v4) +- [Documentation](https://docs-v4.venus.io/whats-new/isolated-pools)`, + forDescription: "Process to configure and launch the new market", + againstDescription: "Defer configuration and launch of the new market", + abstainDescription: "No opinion on the matter", }; return makeProposal( From d732c3795490e8e94a5ba21801d984d00204fe7c Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Tue, 10 Oct 2023 11:30:09 +0530 Subject: [PATCH 10/10] refactor: extract common checks to helpers --- .../vip-178/vip-178-testnet/simulations.ts | 144 +--- .../vip-178/vip-178/abi/rateModel.json | 118 --- simulations/vip-178/vip-178/simulations.ts | 145 +--- .../vip-framework/abi/il_rateModel.json | 0 src/vip-framework/abi/il_vToken.json | 790 ++++++++++++++++++ src/vip-framework/checks/checkVToken.ts | 54 ++ src/vip-framework/checks/interestRateModel.ts | 48 ++ 7 files changed, 928 insertions(+), 371 deletions(-) delete mode 100644 simulations/vip-178/vip-178/abi/rateModel.json rename simulations/vip-178/vip-178-testnet/abi/rateModel.json => src/vip-framework/abi/il_rateModel.json (100%) create mode 100644 src/vip-framework/abi/il_vToken.json create mode 100644 src/vip-framework/checks/checkVToken.ts create mode 100644 src/vip-framework/checks/interestRateModel.ts diff --git a/simulations/vip-178/vip-178-testnet/simulations.ts b/simulations/vip-178/vip-178-testnet/simulations.ts index f7a180dbb..8e133501c 100644 --- a/simulations/vip-178/vip-178-testnet/simulations.ts +++ b/simulations/vip-178/vip-178-testnet/simulations.ts @@ -1,17 +1,22 @@ import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; import { expect } from "chai"; -import { BigNumberish } from "ethers"; import { Contract } from "ethers"; import { parseUnits } from "ethers/lib/utils"; import { ethers } from "hardhat"; import { expectEvents } from "../../../src/utils"; import { forking, testVip } from "../../../src/vip-framework"; +import { checkVToken } from "../../../src/vip-framework/checks/checkVToken"; +import { checkInterestRate } from "../../../src/vip-framework/checks/interestRateModel"; +import { + RewardsDistributorConfig, + checkRewardsDistributor, + checkRewardsDistributorPool, +} from "../../../src/vip-framework/checks/rewardsDistributor"; import { vip178Testnet } from "../../../vips/vip-178/vip-178-testnet"; import COMPTROLLER_ABI from "./abi/comptroller.json"; import ERC20_ABI from "./abi/erc20.json"; import POOL_REGISTRY_ABI from "./abi/poolRegistry.json"; -import RATE_MODEL_ABI from "./abi/rateModel.json"; import REWARD_DISTRIBUTOR_ABI from "./abi/rewardsDistributor.json"; import VTOKEN_ABI from "./abi/vToken.json"; @@ -30,65 +35,14 @@ forking(33737831, () => { let poolRegistry: Contract; let comptroller: Contract; let vagEUR: Contract; - let rewardsDistributor: Contract; before(async () => { poolRegistry = await ethers.getContractAt(POOL_REGISTRY_ABI, POOL_REGISTRY); comptroller = await ethers.getContractAt(COMPTROLLER_ABI, STABLECOIN_COMPTROLLER); vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); - rewardsDistributor = await ethers.getContractAt(REWARD_DISTRIBUTOR_ABI, REWARD_DISTRIBUTOR); }); describe("Contracts setup", () => { - const checkVToken = ( - vTokenAddress: string, - { - name, - symbol, - decimals, - underlying, - exchangeRate, - }: { - name: string; - symbol: string; - decimals: BigNumberish; - underlying: string; - exchangeRate: BigNumberish; - }, - ) => { - describe(symbol, () => { - let vToken: Contract; - - before(async () => { - vToken = await ethers.getContractAt(VTOKEN_ABI, vTokenAddress); - }); - - it(`should have name = "${name}"`, async () => { - expect(await vToken.name()).to.equal(name); - }); - - it(`should have symbol = "${symbol}"`, async () => { - expect(await vToken.symbol()).to.equal(symbol); - }); - - it(`should have ${decimals.toString()} decimals`, async () => { - expect(await vToken.decimals()).to.equal(decimals); - }); - - it(`should have underlying = "${underlying}"`, async () => { - expect(await vToken.underlying()).to.equal(underlying); - }); - - it(`should have initial exchange rate of ${exchangeRate.toString()}`, async () => { - expect(await vToken.exchangeRateStored()).to.equal(exchangeRate); - }); - - it("should have the correct Comptroller", async () => { - expect(await vToken.exchangeRateStored()).to.equal(exchangeRate); - }); - }); - }; - checkVToken(VagEUR_Stablecoins, { name: "Venus agEUR (Stablecoins)", symbol: "vagEUR_Stablecoins", @@ -143,51 +97,6 @@ forking(33737831, () => { }); describe("Market and risk parameters", () => { - const checkInterestRate = ( - vTokenAddress: string, - symbol: string, - { - base, - multiplier, - jump, - kink, - }: { - base: string; - multiplier: string; - jump: string; - kink: string; - }, - ) => { - describe(`${symbol} interest rate model`, () => { - const BLOCKS_PER_YEAR = 10512000; - let rateModel: Contract; - - before(async () => { - const vToken = await ethers.getContractAt(VTOKEN_ABI, vTokenAddress); - rateModel = await ethers.getContractAt(RATE_MODEL_ABI, await vToken.interestRateModel()); - }); - - it(`should have base = ${base}`, async () => { - const basePerBlock = parseUnits(base, 18).div(BLOCKS_PER_YEAR); - expect(await rateModel.baseRatePerBlock()).to.equal(basePerBlock); - }); - - it(`should have jump = ${jump}`, async () => { - const jumpPerBlock = parseUnits(jump, 18).div(BLOCKS_PER_YEAR); - expect(await rateModel.jumpMultiplierPerBlock()).to.equal(jumpPerBlock); - }); - - it(`should have multiplier = ${multiplier}`, async () => { - const multiplierPerBlock = parseUnits(multiplier, 18).div(BLOCKS_PER_YEAR); - expect(await rateModel.multiplierPerBlock()).to.equal(multiplierPerBlock); - }); - - it(`should have kink = ${kink}`, async () => { - expect(await rateModel.kink()).to.equal(parseUnits(kink, 18)); - }); - }); - }; - describe("Interest rate models", () => { checkInterestRate(VagEUR_Stablecoins, "VagEUR_Stablecoins", { base: "0.02", @@ -230,34 +139,17 @@ forking(33737831, () => { }); describe("Reward Distributor", () => { - it("should be added to Stable coins Pool", async () => { - expect(await comptroller.getRewardDistributors()).to.include(REWARD_DISTRIBUTOR); - }); - - it("should have 3 rewards distributor in Stable coins Pool", async () => { - expect(await comptroller.getRewardDistributors()).to.have.lengthOf(3); - }); - - it("should have rewardToken ANGLE", async () => { - expect(await rewardsDistributor.rewardToken()).to.equal(ANGLE); - }); - - it(`should have owner = Normal Timelock`, async () => { - expect(await rewardsDistributor.owner()).to.equal(NORMAL_TIMELOCK); - }); - - it("should have borrowSpeed = 87,549,603,174,603,174", async () => { - expect(await rewardsDistributor.rewardTokenBorrowSpeeds(VagEUR_Stablecoins)).to.equal("87549603174603174"); - }); - - it("should have supplySpeed = 0", async () => { - expect(await rewardsDistributor.rewardTokenSupplySpeeds(VagEUR_Stablecoins)).to.equal("0"); - }); - - it("should have balance = 17,650 ANGLE", async () => { - const token = await ethers.getContractAt(ERC20_ABI, ANGLE); - expect(await token.balanceOf(rewardsDistributor.address)).to.equal(parseUnits("17650", 18)); - }); + const agEURRewardsDistributorConfig: RewardsDistributorConfig = { + pool: STABLECOIN_COMPTROLLER, + address: REWARD_DISTRIBUTOR, + token: ANGLE, + vToken: VagEUR_Stablecoins, + borrowSpeed: parseUnits("17650", 18).div(201600), + supplySpeed: 0, + totalRewardsToDistribute: parseUnits("17650", 18), + }; + checkRewardsDistributor("RewardsDistributor_agEUR_Stablecoins", agEURRewardsDistributorConfig); + checkRewardsDistributorPool(STABLECOIN_COMPTROLLER, 3); }); describe("VToken", () => { describe("Basic supply/borrow/repay/redeem scenario", () => { diff --git a/simulations/vip-178/vip-178/abi/rateModel.json b/simulations/vip-178/vip-178/abi/rateModel.json deleted file mode 100644 index 8c04a8527..000000000 --- a/simulations/vip-178/vip-178/abi/rateModel.json +++ /dev/null @@ -1,118 +0,0 @@ -[ - { - "inputs": [ - { "internalType": "uint256", "name": "baseRatePerYear", "type": "uint256" }, - { "internalType": "uint256", "name": "multiplierPerYear", "type": "uint256" }, - { "internalType": "uint256", "name": "jumpMultiplierPerYear", "type": "uint256" }, - { "internalType": "uint256", "name": "kink_", "type": "uint256" } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { "indexed": false, "internalType": "uint256", "name": "baseRatePerBlock", "type": "uint256" }, - { "indexed": false, "internalType": "uint256", "name": "multiplierPerBlock", "type": "uint256" }, - { "indexed": false, "internalType": "uint256", "name": "jumpMultiplierPerBlock", "type": "uint256" }, - { "indexed": false, "internalType": "uint256", "name": "kink", "type": "uint256" } - ], - "name": "NewInterestParams", - "type": "event" - }, - { - "constant": true, - "inputs": [], - "name": "baseRatePerBlock", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "blocksPerYear", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "uint256", "name": "cash", "type": "uint256" }, - { "internalType": "uint256", "name": "borrows", "type": "uint256" }, - { "internalType": "uint256", "name": "reserves", "type": "uint256" } - ], - "name": "getBorrowRate", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "uint256", "name": "cash", "type": "uint256" }, - { "internalType": "uint256", "name": "borrows", "type": "uint256" }, - { "internalType": "uint256", "name": "reserves", "type": "uint256" }, - { "internalType": "uint256", "name": "reserveFactorMantissa", "type": "uint256" } - ], - "name": "getSupplyRate", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "isInterestRateModel", - "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "jumpMultiplierPerBlock", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "kink", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "multiplierPerBlock", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { "internalType": "uint256", "name": "cash", "type": "uint256" }, - { "internalType": "uint256", "name": "borrows", "type": "uint256" }, - { "internalType": "uint256", "name": "reserves", "type": "uint256" } - ], - "name": "utilizationRate", - "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], - "payable": false, - "stateMutability": "pure", - "type": "function" - } -] diff --git a/simulations/vip-178/vip-178/simulations.ts b/simulations/vip-178/vip-178/simulations.ts index 6f9cd1a61..3e108ad68 100644 --- a/simulations/vip-178/vip-178/simulations.ts +++ b/simulations/vip-178/vip-178/simulations.ts @@ -1,17 +1,22 @@ import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; import { expect } from "chai"; -import { BigNumberish } from "ethers"; import { Contract } from "ethers"; import { parseUnits } from "ethers/lib/utils"; import { ethers } from "hardhat"; import { expectEvents, initMainnetUser } from "../../../src/utils"; import { forking, testVip } from "../../../src/vip-framework"; +import { checkVToken } from "../../../src/vip-framework/checks/checkVToken"; +import { checkInterestRate } from "../../../src/vip-framework/checks/interestRateModel"; +import { + RewardsDistributorConfig, + checkRewardsDistributor, + checkRewardsDistributorPool, +} from "../../../src/vip-framework/checks/rewardsDistributor"; import { vip178 } from "../../../vips/vip-178/vip-178"; import COMPTROLLER_ABI from "./abi/comptroller.json"; import ERC20_ABI from "./abi/erc20.json"; import POOL_REGISTRY_ABI from "./abi/poolRegistry.json"; -import RATE_MODEL_ABI from "./abi/rateModel.json"; import RESILIENT_ORACLE_ABI from "./abi/resilientOracle.json"; import REWARD_DISTRIBUTOR_ABI from "./abi/rewardsDistributor.json"; import VTOKEN_ABI from "./abi/vToken.json"; @@ -31,65 +36,14 @@ forking(32162545, () => { let poolRegistry: Contract; let comptroller: Contract; let vagEUR: Contract; - let rewardsDistributor: Contract; before(async () => { poolRegistry = await ethers.getContractAt(POOL_REGISTRY_ABI, POOL_REGISTRY); comptroller = await ethers.getContractAt(COMPTROLLER_ABI, STABLECOIN_COMPTROLLER); vagEUR = await ethers.getContractAt(VTOKEN_ABI, VagEUR_Stablecoins); - rewardsDistributor = await ethers.getContractAt(REWARD_DISTRIBUTOR_ABI, REWARD_DISTRIBUTOR); }); describe("Contracts setup", () => { - const checkVToken = ( - vTokenAddress: string, - { - name, - symbol, - decimals, - underlying, - exchangeRate, - }: { - name: string; - symbol: string; - decimals: BigNumberish; - underlying: string; - exchangeRate: BigNumberish; - }, - ) => { - describe(symbol, () => { - let vToken: Contract; - - before(async () => { - vToken = await ethers.getContractAt(VTOKEN_ABI, vTokenAddress); - }); - - it(`should have name = "${name}"`, async () => { - expect(await vToken.name()).to.equal(name); - }); - - it(`should have symbol = "${symbol}"`, async () => { - expect(await vToken.symbol()).to.equal(symbol); - }); - - it(`should have ${decimals.toString()} decimals`, async () => { - expect(await vToken.decimals()).to.equal(decimals); - }); - - it(`should have underlying = "${underlying}"`, async () => { - expect(await vToken.underlying()).to.equal(underlying); - }); - - it(`should have initial exchange rate of ${exchangeRate.toString()}`, async () => { - expect(await vToken.exchangeRateStored()).to.equal(exchangeRate); - }); - - it("should have the correct Comptroller", async () => { - expect(await vToken.exchangeRateStored()).to.equal(exchangeRate); - }); - }); - }; - checkVToken(VagEUR_Stablecoins, { name: "Venus agEUR (Stablecoins)", symbol: "vagEUR_Stablecoins", @@ -134,7 +88,6 @@ forking(32162545, () => { describe("Ownership", () => { it("should transfer ownership to Timelock", async () => { expect(await vagEUR.owner()).to.equal(NORMAL_TIMELOCK); - expect(await rewardsDistributor.owner()).to.equal(NORMAL_TIMELOCK); }); }); @@ -145,51 +98,6 @@ forking(32162545, () => { }); describe("Market and risk parameters", () => { - const checkInterestRate = ( - vTokenAddress: string, - symbol: string, - { - base, - multiplier, - jump, - kink, - }: { - base: string; - multiplier: string; - jump: string; - kink: string; - }, - ) => { - describe(`${symbol} interest rate model`, () => { - const BLOCKS_PER_YEAR = 10512000; - let rateModel: Contract; - - before(async () => { - const vToken = await ethers.getContractAt(VTOKEN_ABI, vTokenAddress); - rateModel = await ethers.getContractAt(RATE_MODEL_ABI, await vToken.interestRateModel()); - }); - - it(`should have base = ${base}`, async () => { - const basePerBlock = parseUnits(base, 18).div(BLOCKS_PER_YEAR); - expect(await rateModel.baseRatePerBlock()).to.equal(basePerBlock); - }); - - it(`should have jump = ${jump}`, async () => { - const jumpPerBlock = parseUnits(jump, 18).div(BLOCKS_PER_YEAR); - expect(await rateModel.jumpMultiplierPerBlock()).to.equal(jumpPerBlock); - }); - - it(`should have multiplier = ${multiplier}`, async () => { - const multiplierPerBlock = parseUnits(multiplier, 18).div(BLOCKS_PER_YEAR); - expect(await rateModel.multiplierPerBlock()).to.equal(multiplierPerBlock); - }); - - it(`should have kink = ${kink}`, async () => { - expect(await rateModel.kink()).to.equal(parseUnits(kink, 18)); - }); - }); - }; - describe("Interest rate models", () => { checkInterestRate(VagEUR_Stablecoins, "VagEUR_Stablecoins", { base: "0.02", @@ -232,34 +140,17 @@ forking(32162545, () => { }); describe("Reward Distributor", () => { - it("should be added to Stable coins Pool", async () => { - expect(await comptroller.getRewardDistributors()).to.include(REWARD_DISTRIBUTOR); - }); - - it("should have 3 rewards distributor in Stable coins Pool", async () => { - expect(await comptroller.getRewardDistributors()).to.have.lengthOf(3); - }); - - it("should have rewardToken ANGLE", async () => { - expect(await rewardsDistributor.rewardToken()).to.equal(ANGLE); - }); - - it(`should have owner = Normal Timelock`, async () => { - expect(await rewardsDistributor.owner()).to.equal(NORMAL_TIMELOCK); - }); - - it("should have borrowSpeed = 87,549,603,174,603,174", async () => { - expect(await rewardsDistributor.rewardTokenBorrowSpeeds(VagEUR_Stablecoins)).to.equal("87549603174603174"); - }); - - it("should have supplySpeed = 0", async () => { - expect(await rewardsDistributor.rewardTokenSupplySpeeds(VagEUR_Stablecoins)).to.equal("0"); - }); - - it("should have balance = 17,650 ANGLE", async () => { - const token = await ethers.getContractAt(ERC20_ABI, ANGLE); - expect(await token.balanceOf(rewardsDistributor.address)).to.equal(parseUnits("17650", 18)); - }); + const agEURRewardsDistributorConfig: RewardsDistributorConfig = { + pool: STABLECOIN_COMPTROLLER, + address: REWARD_DISTRIBUTOR, + token: ANGLE, + vToken: VagEUR_Stablecoins, + borrowSpeed: parseUnits("17650", 18).div(201600), + supplySpeed: 0, + totalRewardsToDistribute: parseUnits("17650", 18), + }; + checkRewardsDistributor("RewardsDistributor_agEUR_Stablecoins", agEURRewardsDistributorConfig); + checkRewardsDistributorPool(STABLECOIN_COMPTROLLER, 3); }); describe("VToken", () => { describe("Basic supply/borrow/repay/redeem scenario", () => { diff --git a/simulations/vip-178/vip-178-testnet/abi/rateModel.json b/src/vip-framework/abi/il_rateModel.json similarity index 100% rename from simulations/vip-178/vip-178-testnet/abi/rateModel.json rename to src/vip-framework/abi/il_rateModel.json diff --git a/src/vip-framework/abi/il_vToken.json b/src/vip-framework/abi/il_vToken.json new file mode 100644 index 000000000..7ac5306db --- /dev/null +++ b/src/vip-framework/abi/il_vToken.json @@ -0,0 +1,790 @@ +[ + { "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, + { + "inputs": [{ "internalType": "uint256", "name": "actualAddAmount", "type": "uint256" }], + "name": "AddReservesFactorFreshCheck", + "type": "error" + }, + { "inputs": [], "name": "BorrowCashNotAvailable", "type": "error" }, + { "inputs": [], "name": "BorrowFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "ForceLiquidateBorrowUnauthorized", "type": "error" }, + { "inputs": [], "name": "HealBorrowUnauthorized", "type": "error" }, + { + "inputs": [{ "internalType": "uint256", "name": "errorCode", "type": "uint256" }], + "name": "LiquidateAccrueCollateralInterestFailed", + "type": "error" + }, + { "inputs": [], "name": "LiquidateCloseAmountIsUintMax", "type": "error" }, + { "inputs": [], "name": "LiquidateCloseAmountIsZero", "type": "error" }, + { "inputs": [], "name": "LiquidateCollateralFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "LiquidateFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "LiquidateLiquidatorIsBorrower", "type": "error" }, + { "inputs": [], "name": "LiquidateSeizeLiquidatorIsBorrower", "type": "error" }, + { "inputs": [], "name": "MintFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "ProtocolSeizeShareTooBig", "type": "error" }, + { "inputs": [], "name": "RedeemFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "RedeemTransferOutNotPossible", "type": "error" }, + { "inputs": [], "name": "ReduceReservesCashNotAvailable", "type": "error" }, + { "inputs": [], "name": "ReduceReservesCashValidation", "type": "error" }, + { "inputs": [], "name": "ReduceReservesFreshCheck", "type": "error" }, + { "inputs": [], "name": "RepayBorrowFreshnessCheck", "type": "error" }, + { "inputs": [], "name": "SetInterestRateModelFreshCheck", "type": "error" }, + { "inputs": [], "name": "SetReserveFactorBoundsCheck", "type": "error" }, + { "inputs": [], "name": "SetReserveFactorFreshCheck", "type": "error" }, + { "inputs": [], "name": "TransferNotAllowed", "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" }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "cashPrior", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "interestAccumulated", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "borrowIndex", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "totalBorrows", "type": "uint256" } + ], + "name": "AccrueInterest", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtDelta", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtOld", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtNew", "type": "uint256" } + ], + "name": "BadDebtIncreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "badDebtOld", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "badDebtNew", "type": "uint256" } + ], + "name": "BadDebtRecovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "borrowAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBorrows", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "totalBorrows", "type": "uint256" } + ], + "name": "Borrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "payer", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "name": "HealBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": false, "internalType": "uint8", "name": "version", "type": "uint8" }], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "liquidator", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "indexed": true, "internalType": "address", "name": "vTokenCollateral", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } + ], + "name": "LiquidateBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "minter", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "mintAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "mintTokens", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBalance", "type": "uint256" } + ], + "name": "Mint", + "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": "contract ComptrollerInterface", "name": "oldComptroller", "type": "address" }, + { "indexed": true, "internalType": "contract ComptrollerInterface", "name": "newComptroller", "type": "address" } + ], + "name": "NewComptroller", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract InterestRateModel", + "name": "oldInterestRateModel", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract InterestRateModel", + "name": "newInterestRateModel", + "type": "address" + } + ], + "name": "NewMarketInterestRateModel", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "oldProtocolSeizeShareMantissa", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newProtocolSeizeShareMantissa", "type": "uint256" } + ], + "name": "NewProtocolSeizeShare", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "oldProtocolShareReserve", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newProtocolShareReserve", "type": "address" } + ], + "name": "NewProtocolShareReserve", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": false, "internalType": "uint256", "name": "oldReserveFactorMantissa", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newReserveFactorMantissa", "type": "uint256" } + ], + "name": "NewReserveFactor", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "oldShortfall", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "newShortfall", "type": "address" } + ], + "name": "NewShortfallContract", + "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": "redeemer", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "redeemAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "redeemTokens", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBalance", "type": "uint256" } + ], + "name": "Redeem", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "payer", "type": "address" }, + { "indexed": true, "internalType": "address", "name": "borrower", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "accountBorrows", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "totalBorrows", "type": "uint256" } + ], + "name": "RepayBorrow", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "benefactor", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "addAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newTotalReserves", "type": "uint256" } + ], + "name": "ReservesAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { "indexed": true, "internalType": "address", "name": "admin", "type": "address" }, + { "indexed": false, "internalType": "uint256", "name": "reduceAmount", "type": "uint256" }, + { "indexed": false, "internalType": "uint256", "name": "newTotalReserves", "type": "uint256" } + ], + "name": "ReservesReduced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [{ "indexed": true, "internalType": "address", "name": "token", "type": "address" }], + "name": "SweepToken", + "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": "amount", "type": "uint256" } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "NO_ERROR", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "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": "accrualBlockNumber", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "accrueInterest", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "addAmount", "type": "uint256" }], + "name": "addReserves", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "badDebt", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "recoveredAmount_", "type": "uint256" }], + "name": "badDebtRecovered", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "owner", "type": "address" }], + "name": "balanceOfUnderlying", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "borrowAmount", "type": "uint256" }], + "name": "borrow", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "borrowBalanceCurrent", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "borrowBalanceStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "borrowRatePerBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "comptroller", + "outputs": [{ "internalType": "contract ComptrollerInterface", "name": "", "type": "address" }], + "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": [], + "name": "exchangeRateCurrent", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "exchangeRateStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "internalType": "contract VTokenInterface", "name": "vTokenCollateral", "type": "address" }, + { "internalType": "bool", "name": "skipLiquidityCheck", "type": "bool" } + ], + "name": "forceLiquidateBorrow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "getAccountSnapshot", + "outputs": [ + { "internalType": "uint256", "name": "error", "type": "uint256" }, + { "internalType": "uint256", "name": "vTokenBalance", "type": "uint256" }, + { "internalType": "uint256", "name": "borrowBalance", "type": "uint256" }, + { "internalType": "uint256", "name": "exchangeRate", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getCash", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "payer", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "name": "healBorrow", + "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": [ + { "internalType": "address", "name": "underlying_", "type": "address" }, + { "internalType": "contract ComptrollerInterface", "name": "comptroller_", "type": "address" }, + { "internalType": "contract InterestRateModel", "name": "interestRateModel_", "type": "address" }, + { "internalType": "uint256", "name": "initialExchangeRateMantissa_", "type": "uint256" }, + { "internalType": "string", "name": "name_", "type": "string" }, + { "internalType": "string", "name": "symbol_", "type": "string" }, + { "internalType": "uint8", "name": "decimals_", "type": "uint8" }, + { "internalType": "address", "name": "admin_", "type": "address" }, + { "internalType": "address", "name": "accessControlManager_", "type": "address" }, + { + "components": [ + { "internalType": "address", "name": "shortfall", "type": "address" }, + { "internalType": "address payable", "name": "protocolShareReserve", "type": "address" } + ], + "internalType": "struct VTokenInterface.RiskManagementInit", + "name": "riskManagement", + "type": "tuple" + }, + { "internalType": "uint256", "name": "reserveFactorMantissa_", "type": "uint256" } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "interestRateModel", + "outputs": [{ "internalType": "contract InterestRateModel", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isVToken", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" }, + { "internalType": "contract VTokenInterface", "name": "vTokenCollateral", "type": "address" } + ], + "name": "liquidateBorrow", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "mintAmount", "type": "uint256" }], + "name": "mint", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "minter", "type": "address" }, + { "internalType": "uint256", "name": "mintAmount", "type": "uint256" } + ], + "name": "mintBehalf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingOwner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolSeizeShareMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolShareReserve", + "outputs": [{ "internalType": "address payable", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "redeemTokens", "type": "uint256" }], + "name": "redeem", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "redeemAmount", "type": "uint256" }], + "name": "redeemUnderlying", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "reduceAmount", "type": "uint256" }], + "name": "reduceReserves", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { "inputs": [], "name": "renounceOwnership", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [{ "internalType": "uint256", "name": "repayAmount", "type": "uint256" }], + "name": "repayBorrow", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "repayAmount", "type": "uint256" } + ], + "name": "repayBorrowBehalf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reserveFactorMantissa", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "liquidator", "type": "address" }, + { "internalType": "address", "name": "borrower", "type": "address" }, + { "internalType": "uint256", "name": "seizeTokens", "type": "uint256" } + ], + "name": "seize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "accessControlManager_", "type": "address" }], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract InterestRateModel", "name": "newInterestRateModel", "type": "address" }], + "name": "setInterestRateModel", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "newProtocolSeizeShareMantissa_", "type": "uint256" }], + "name": "setProtocolSeizeShare", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address payable", "name": "protocolShareReserve_", "type": "address" }], + "name": "setProtocolShareReserve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "newReserveFactorMantissa", "type": "uint256" }], + "name": "setReserveFactor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "shortfall_", "type": "address" }], + "name": "setShortfallContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "shortfall", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "supplyRatePerBlock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "contract IERC20Upgradeable", "name": "token", "type": "address" }], + "name": "sweepToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBorrows", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalBorrowsCurrent", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalReserves", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "src", "type": "address" }, + { "internalType": "address", "name": "dst", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newOwner", "type": "address" }], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlying", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/vip-framework/checks/checkVToken.ts b/src/vip-framework/checks/checkVToken.ts new file mode 100644 index 000000000..fc81c9f84 --- /dev/null +++ b/src/vip-framework/checks/checkVToken.ts @@ -0,0 +1,54 @@ +import { expect } from "chai"; +import { BigNumberish } from "ethers"; +import { ethers } from "hardhat"; + +import VTOKEN_ABI from "../abi/il_vToken.json"; + +export async function checkVToken( + vTokenAddress: string, + { + name, + symbol, + decimals, + underlying, + exchangeRate, + }: { + name: string; + symbol: string; + decimals: number; + underlying: string; + exchangeRate: BigNumberish; + }, +) { + describe(symbol, () => { + let vToken: Contract; + + before(async () => { + vToken = await ethers.getContractAt(VTOKEN_ABI, vTokenAddress); + }); + + it(`should have name = "${name}"`, async () => { + expect(await vToken.name()).to.equal(name); + }); + + it(`should have symbol = "${symbol}"`, async () => { + expect(await vToken.symbol()).to.equal(symbol); + }); + + it(`should have ${decimals.toString()} decimals`, async () => { + expect(await vToken.decimals()).to.equal(decimals); + }); + + it(`should have underlying = "${underlying}"`, async () => { + expect(await vToken.underlying()).to.equal(underlying); + }); + + it(`should have initial exchange rate of ${exchangeRate.toString()}`, async () => { + expect(await vToken.exchangeRateStored()).to.equal(exchangeRate); + }); + + it("should have the correct Comptroller", async () => { + expect(await vToken.exchangeRateStored()).to.equal(exchangeRate); + }); + }); +} diff --git a/src/vip-framework/checks/interestRateModel.ts b/src/vip-framework/checks/interestRateModel.ts new file mode 100644 index 000000000..6050ec645 --- /dev/null +++ b/src/vip-framework/checks/interestRateModel.ts @@ -0,0 +1,48 @@ +import { expect } from "chai"; +import { BigNumber, Contract, utils } from "ethers"; +import { ethers } from "hardhat"; + +import RATE_MODEL_ABI from "../abi/il_rateModel.json"; +import VTOKEN_ABI from "../abi/il_vToken.json"; + +const BLOCKS_PER_YEAR = BigNumber.from(10512000); + +export async function checkInterestRate( + vTokenAddress: string, + symbol: string, + { + base, + multiplier, + jump, + kink, + }: { + base: string; + multiplier: string; + jump: string; + kink: string; + }, +) { + const vToken: Contract = await ethers.getContractAt(VTOKEN_ABI, vTokenAddress); + const rateModel: Contract = await ethers.getContractAt(RATE_MODEL_ABI, await vToken.interestRateModel()); + + describe(`${symbol} interest rate model`, () => { + it(`should have base = ${base}`, async () => { + const basePerBlock = utils.parseUnits(base, 18).div(BLOCKS_PER_YEAR); + expect(await rateModel.baseRatePerBlock()).to.equal(basePerBlock); + }); + + it(`should have jump = ${jump}`, async () => { + const jumpPerBlock = utils.parseUnits(jump, 18).div(BLOCKS_PER_YEAR); + expect(await rateModel.jumpMultiplierPerBlock()).to.equal(jumpPerBlock); + }); + + it(`should have multiplier = ${multiplier}`, async () => { + const multiplierPerBlock = utils.parseUnits(multiplier, 18).div(BLOCKS_PER_YEAR); + expect(await rateModel.multiplierPerBlock()).to.equal(multiplierPerBlock); + }); + + it(`should have kink = ${kink}`, async () => { + expect(await rateModel.kink()).to.equal(utils.parseUnits(kink, 18)); + }); + }); +}